[SSAFYdia] SSAFY 공통 프로젝트 백엔드 개발기: Docker로 배포부터 운영까지 🐋
안녕하세요!
SSAFY 공통 프로젝트에서 백엔드 개발을 담당하면서 Docker를 활용하여 인프라를 구축한 경험으로 토대로 얻은 Docker 지식들을 공유하려고 합니다.
처음에는 생소했던 컨테이너 기술이었지만 프로젝트를 진행하면서 그 필요성과 장점을 실감하게 되었습니다. 특히 여러 개의 서비스를 연동하고 배포해야 하는 환경에서 큰 도움이 되었습니다. (저는 Spring Boot, MySQL, Nginx, Jenkins, Redis 등을 컨테이너화하고 서로 연동하는데 Docker를 활용했습니다!)
따라서 이번 기사를 통해 Docker의 기본 개념부터 간단한 실습, 실제 프로젝트에서 어떻게 활용했는지에 대해 설명하고자 합니다.
1. 도커란?
Docker는 컨테이너 기반의 가상화 기술을 제공하는 플랫폼으로 애플리케이션을 일관된 환경에서 실행할 수 있도록 지원합니다. 기존의 가상 머신(VM)과 달리 운영 체제 전체를 포함하지 않고 필요한 라이브러리와 실행 환경만을 패키징하여 가볍고 빠르게 실행할 수 있습니다.
2. 도커를 사용하는 이유
프로젝트를 진행하면서 Docker의 필요성을 실감하게 되었는데 특히 여러 환경에서 동일한 개발 환경을 유지하고 배포를 간편하게 할 수 있다는 점이 가장 매력적으로 다가왔습니다!
- 환경 일관성 유지: 개발 환경과 운영 환경의 차이로 인해 발생하는 문제를 줄일 수 있습니다.
- 경량화된 가상화: 가상 머신보다 가볍고 빠르며 자원을 효율적으로 사용할 수 있습니다.
- 빠른 배포 및 확장성: 컨테이너 이미지를 활용하여 손쉽게 배포 및 확장이 가능합니다.
- 운영 및 관리 편의성: 여러 개의 컨테이너를 효과적으로 관리할 수 있습니다.
3. 도커 구성요소
Docker를 구성하는 주요 요소는 다음과 같습니다.
- Docker Engine: 컨테이너 실행을 담당하는 핵심 엔진
- 이미지(Image): 컨테이너 실행을 위한 패키지
- 컨테이너(Container): 이미지를 실행한 독립적인 환경
- Docker Hub: 도커 이미지를 공유할 수 있는 저장소
- Docker Compose: 여러 개의 컨테이너를 한 번에 실행하고 관리하는 도구
Docker를 물류 시스템에 비유하면 다음과 같습니다.
Docker Engine = 항구의 크레인 🏗️ → 컨테이너(화물)를 배에 싣고 내리는 핵심 역할
이미지(Image) = 포장된 화물 📦 → 실행에 필요한 모든 요소를 포함한 패키지
컨테이너(Container) = 화물을 실은 선박 🚢 → 독립적으로 운반되고 실행되는 단위
Docker Hub = 글로벌 물류 창고 🏢 → 컨테이너(이미지)를 저장하고 공유하는 공간
Docker Compose = 물류 자동화 시스템 ⚙️ → 여러 컨테이너를 한 번에 조정하는 도구
이처럼 Docker는 효율적인 컨테이너 관리와 배포를 돕는 물류 시스템과 같은 역할을 합니다!
4. 도커 사용법 (간단 실습)
Docker의 기본적인 사용법을 익히기 위해 다음과 같이 간단히 컨테이너를 실행해보는 실습을 진행해 보면 좋을 것 같습니다.
도커 설치
# Ubuntu 기준
sudo apt update
sudo apt install -y docker.io
컨테이너 실행
# nginx 컨테이너 실행
sudo docker run -d -p 8080:80 --name my-nginx nginx
컨테이너 목록 확인
sudo docker ps
컨테이너 중지 및 삭제
sudo docker stop my-nginx
sudo docker rm my-nginx
5. 프로젝트에서 Docker 활용하기
저는 프로젝트에서 Spring Boot, MySQL, Jenkins, Nginx, Certbot, Redis를 Docker 컨테이너로 구성하여 배포하였습니다. 이를 통해 각 서비스의 환경을 일관되게 유지할 수 있었고 개발과 운영 환경 간의 차이를 최소화할 수 있었습니다. 또한 컨테이너 기반으로 애플리케이션을 실행하면서 설정 자동화가 가능해졌고 배포 과정이 훨씬 간소화되어 전체적인 개발 속도와 운영 효율성이 향상되었습니다.
특히 Docker Compose를 활용하여 여러 컨테이너를 손쉽게 관리할 수 있었고 개별 서비스 간의 네트워크 연결도 원활하게 설정할 수 있었습니다. 덕분에 팀원들과의 협업이 더욱 원활해졌으며 배포 및 유지보수 과정에서도 많은 이점을 얻을 수 있었습니다.
5.1 Spring Boot 컨테이너화
Spring Boot 애플리케이션을 Docker에 올리는 과정에서 환경 차이에 따른 문제를 해결할 수 있었습니다.
Dockerfile 작성
FROM openjdk:17
WORKDIR /app
COPY target/myapp.jar app.jar
CMD ["java", "-jar", "app.jar"]
컨테이너 빌드 및 실행
docker build -t myapp .
docker run -d -p 8080:8080 --name myapp myapp
5.2 MySQL 컨테이너화
데이터베이스 환경을 Docker로 통합하여 관리할 수 있었습니다.
Docker Compose 설정
version: '3.1'
services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: password
ports:
- "3306:3306"
5.3 Jenkins 컨테이너화
CI/CD 자동화를 위해 Jenkins를 Docker 컨테이너로 실행하여 간편하게 설정할 수 있었습니다.
docker run -d -p 8081:8080 -v jenkins_home:/var/jenkins_home --name jenkins jenkins/jenkins:lts
5.4 Nginx + Certbot 컨테이너화
SSL 인증서를 자동으로 갱신하는 환경을 구축하기 위해 Certbot과 Nginx를 활용하였습니다.
version: '3'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
certbot:
image: certbot/certbot
command: certonly --webroot -w /var/www/certbot -d example.com --email admin@example.com --agree-tos --no-eff-email
5.5 Redis 컨테이너화
프로젝트에서 Redis를 사용하면서 가장 크게 느낀 점은 데이터 처리 속도의 향상이었습니다. 저는 프로젝트에서 학생들의 저축 목표 달성률을 계산하고 실시간으로 학급 내 순위를 정하는 데 Redis를 활용했습니다. 기존에는 데이터베이스에서 직접 읽고 쓰는 과정에서 지연이 발생했지만 Redis를 활용함으로써 데이터를 메모리에 캐싱하여 빠르게 접근할 수 있었습니다.
+) 이후에는 사용자 세션을 관리하는 데에도 Redis를 사용하여 서버 재시작 시에도 세션이 유지될 수 있도록 구성해 보는 작업을 진행해보고 싶습니다.
Docker Compose 설정
version: '3.1'
services:
redis:
image: redis:latest
restart: always
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
redis_data:
이번 SSAFY 공통 프로젝트에서 Docker를 활용하여 백엔드 인프라를 구축하는 과정을 경험하면서 개발 환경의 일관성 유지, 배포 자동화, 운영 효율성 등을 체감할 수 있었습니다.
앞으로도 Docker Compose와 Kubernetes 등을 적극 활용하여 더욱 확장성 있는 개발 및 운영 환경을 구축할 계획입니다!
이 글을 읽으시는 분들도 프로젝트에 Docker를 적극 도입해서 환경 설정을 자동화하고 배포 속도를 개선해보는 경험을 해보시면 좋을 것 같습니다! (여러분들의 시간은 소중하니까요...)
이번 기사도 읽어주셔서 감사하고 궁금한 점 있으시면 댓글 남겨주세요~!