Docker는 애플리케이션과 의존성을 컨테이너로 패키징해 어느 서버에서든 동일하게 실행할 수 있게 합니다. 서버 환경을 깔끔하게 분리하고 관리하는 데 매우 유용합니다.
Docker 설치
# 의존성 설치
sudo apt update
sudo apt install -y ca-certificates curl gnupg
# Docker 공식 GPG 키 추가
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 저장소 추가
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
# 설치
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 현재 사용자를 docker 그룹에 추가 (sudo 없이 사용)
sudo usermod -aG docker $USER
newgrp docker
기본 명령어
# 이미지 검색 및 다운로드
docker search nginx
docker pull nginx:latest
# 컨테이너 실행
docker run -d \
--name my-nginx \
-p 8080:80 \
nginx:latest
# 실행 중인 컨테이너 목록
docker ps
# 모든 컨테이너 목록 (중지된 것 포함)
docker ps -a
# 컨테이너 로그 확인
docker logs -f my-nginx
# 컨테이너 내부 접속
docker exec -it my-nginx bash
# 컨테이너 중지 및 삭제
docker stop my-nginx
docker rm my-nginx
볼륨으로 데이터 영구 보존
컨테이너를 삭제하면 내부 데이터도 함께 사라집니다. 볼륨을 사용해 데이터를 호스트에 보존합니다:
# 호스트 디렉터리를 컨테이너에 마운트
docker run -d \
--name mysql-db \
-e MYSQL_ROOT_PASSWORD=비밀번호 \
-e MYSQL_DATABASE=myapp \
-v /opt/mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.0
# Docker 관리 볼륨 사용
docker volume create mydata
docker run -d -v mydata:/data alpine
# 볼륨 목록 확인
docker volume ls
네트워크 설정
# 사용자 정의 네트워크 생성 (컨테이너 간 통신)
docker network create myapp-network
# 같은 네트워크에 컨테이너 연결
docker run -d --name app --network myapp-network my-app-image
docker run -d --name db --network myapp-network mysql:8.0
# app 컨테이너에서 db 컨테이너 이름으로 접속 가능
# mysql -h db -u root -p
docker-compose로 멀티 컨테이너 관리
여러 컨테이너를 한 파일로 정의하고 관리합니다:
# docker-compose.yml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html:ro
depends_on:
- app
networks:
- myapp
app:
image: node:20-alpine
working_dir: /app
volumes:
- ./app:/app
command: node server.js
environment:
- DB_HOST=db
- DB_PASSWORD=${DB_PASSWORD}
networks:
- myapp
depends_on:
- db
db:
image: mysql:8.0
volumes:
- db-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=myapp
networks:
- myapp
volumes:
db-data:
networks:
myapp:
driver: bridge
# 실행 (.env 파일에 환경변수 정의)
docker compose up -d
# 상태 확인
docker compose ps
docker compose logs -f
# 중지 및 삭제 (볼륨 보존)
docker compose down
# 볼륨까지 삭제
docker compose down -v
이미지 빌드 (Dockerfile)
# Dockerfile
FROM ubuntu:22.04
# 패키지 설치
RUN apt update && apt install -y \
nginx \
&& rm -rf /var/lib/apt/lists/*
# 설정 파일 복사
COPY nginx.conf /etc/nginx/nginx.conf
# 포트 노출
EXPOSE 80
# 실행 명령
CMD ["nginx", "-g", "daemon off;"]
# 이미지 빌드
docker build -t my-nginx:1.0 .
# 이미지 목록
docker images
리소스 제한 및 모니터링
# CPU/메모리 제한
docker run -d \
--name limited-app \
--memory="512m" \
--cpus="1.0" \
my-app-image
# 실시간 리소스 사용량 확인
docker stats
# 사용하지 않는 리소스 정리
docker system prune -a
보안 고려사항
# 루트가 아닌 사용자로 실행
docker run --user 1000:1000 my-app-image
# 읽기 전용 루트 파일시스템
docker run --read-only my-app-image
# 컨테이너가 새 권한 획득 방지
docker run --security-opt no-new-privileges my-app-image
Docker를 활용하면 서버에 여러 서비스를 깔끔하게 분리해 운영할 수 있습니다. 특히 개발 환경과 프로덕션 환경의 일관성을 유지하는 데 매우 효과적입니다.