1. Docker CLI 명령어 (기초)

가장 원시적이고 기본적인 방법입니다. docker-compose.yml 파일 없이 터미널에 긴 명령어를 직접 쳐서 실행합니다.

  • 장점: 별도의 설치나 파일 생성 없이 즉시 실행 가능. 간단한 테스트용으로 적합.
  • 단점: 옵션이 많아지면 명령어가 너무 길어져서 관리하기 힘듦. 오타 나기 쉬움.
  • 예시 (Nginx 실행):(이걸 Mattermost처럼 복잡하게 짜려면 명령어가 10줄이 넘어갑니다. )
#예시
docker run -d --name my-nginx -p 80:80 nginx:latest

 

2. Docker Compose (중급 - 추천 )

설정 파일(yaml)에 실행 옵션을 미리 다 적어두고, 명령어 한 방(up)으로 실행하는 방법입니다.

  • 장점: 설정이 문서로 남아서 관리하기 편함. 여러 컨테이너(앱+DB)를 한 번에 관리 가능.
  • 단점: YAML 문법(들여쓰기 등)을 익혀야 함.
  • 용도: 개인 프로젝트, 스타트업, 단일 서버 배포 시 표준처럼 쓰임.

 

3. Container Orchestration (고급 - Kubernetes, Swarm)

서버가 1대가 아니라 수십, 수백 대일 때 사용하는 전문가용 도구입니다.

  • Kubernetes (k8s): 사실상 업계 표준. 구글이 만듦.
    • "컨테이너 3개를 항상 유지해줘", "서버 A가 죽으면 서버 B에 띄워줘" 같은 고급 기능 제공.
    • Mattermost도 사용자가 많아지면 결국 k8s로 넘어갑니다.
  • Docker Swarm: Docker에 내장된 기능. k8s보다 쉽지만 기능이 적음.

 


 

💡 한눈에 비교

구분 Docker CLI (run) Docker Compose Kubernetes (k8s)
난이도 쉬움 (단순 암기) 보통 (설정 파일 작성) 매우 어려움
관리 대상 컨테이너 1개 컨테이너 세트 (앱+DB) 수십~수천 대의 서버
자동 복구 없음 (죽으면 끝) 설정에 따라 (restart: always) 완벽함 (죽으면 자동 생성)
추천 대상 단순 테스트, 1회성 실행 개인 서버, 소규모 서비스 대기업, 대규모 트래픽

 

Docker Compose를 사용하다 보면 docker-compose.yml 파일 하나만 쓰는 것이 아니라, 여러 개의 설정 파일을 합쳐서 실행해야 할 때가 있습니다. 이때 사용하는 것이 바로 -f (File) 옵션입니다.

 

1. -f 옵션이란?

  • 의미: "이 설정 파일을 사용하겠다"라고 Docker에게 명시적으로 알려주는 옵션입니다.
  • 기본 동작: 옵션 없이 docker compose up을 치면, Docker는 자동으로 현재 폴더의 docker-compose.yml 파일
    딱 하나만 찾아서 실행합니다.

 

2. 왜 사용하는가? (Mattermost 예시)

Mattermost와 같은 오픈소스 프로젝트는 설정 관리를 편하게 하기 위해 기능을 여러 파일로 쪼개놓는 경우가 많습니다.

  • docker-compose.yml: 핵심 기능 (Mattermost 앱, DB)
  • docker-compose.nginx.yml: 웹 서버 기능 (Nginx, SSL 설정)

이때 기본 명령어(docker compose up)만 치면 핵심 기능만 실행되고 웹 서버는 실행되지 않는 문제가 발생합니다.
따라서 "이 두 파일을 합쳐서 실행해라!" 라고 명령하기 위해 -f 옵션을 씁니다.

 

3. 동작 원리 (Override & Merge)

여러 개의 -f 옵션을 나열하면, Docker는 앞에서부터 순서대로 파일을 읽어서 합칩니다(Merge).

docker compose -f base.yml -f override.yml up
  1. base.yml을 먼저 읽습니다.
  2. override.yml의 내용을 읽어서, 겹치는 설정은 덮어씌우고(Override) 새로운 설정은 추가합니다.
  3. 완성된 하나의 설정으로 컨테이너를 실행합니다.

 

4. 명령어 비교 (한눈에 보기)

상황  명령어  결과
기본 실행 docker compose up docker-compose.yml 파일 하나만 실행됨. (Nginx 누락됨)
멀티 파일 실행 docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d 두 파일을 합쳐서 앱, DB, Nginx를 모두 실행함.

 

💡 팁: 매번 치기 귀찮다면?

매번 긴 명령어를 치는 것이 번거롭다면, 리눅스의 alias(별칭) 기능을 사용하거나 환경 변수 COMPOSE_FILE을 설정하여
해결할 수 있습니다.

# .env 파일에 아래 내용을 추가하면 -f 옵션 없이도 자동으로 두 파일을 읽습니다.
COMPOSE_FILE=docker-compose.yml:docker-compose.nginx.yml

 

1) 컨테이너 상태 확인 및 로그 (디버깅의 시작)

서버가 안 될 때

명령어  설명  예시 
docker ps 현재 실행 중인 컨테이너 목록(ID, 포트 등)을 확인합니다. docker ps
docker ps -a 중지된(꺼진) 컨테이너를 포함해 모든 목록을 확인합니다. docker ps -a
docker logs [컨테이너] 특정 컨테이너의 에러 로그를 확인합니다. (가장 중요 ⭐) docker logs docker-mattermost-1
docker logs -f [컨테이너] 로그를 실시간으로 계속 추적(Follow)하며 봅니다. (Ctrl+C로 종료) docker logs -f nginx_mattermost
docker stats 실행 중인 컨테이너들의 CPU, 메모리 사용량을 실시간으로 보여줍니다. docker stats
docker inspect [컨테이너] IP 주소, 볼륨 경로, 환경변수 등 상세 설정 정보를 봅니다. docker inspect docker-postgres-1

 

2) 컨테이너 실행 및 제어 (Lifecycle)

컨테이너를 켜고 끄거나 재부팅할 때

명령어 설명 예시 
docker start [컨테이너] 중지된(Stopped) 컨테이너를 다시 시작합니다. docker start my-app
docker stop [컨테이너] 실행 중인 컨테이너를 안전하게 종료합니다. docker stop my-app
docker restart [컨테이너] 컨테이너를 재시작합니다. (메모리 초기화, 단순 오류 해결용) docker restart docker-mattermost-1
docker rm [컨테이너] 중지된 컨테이너를 완전히 삭제합니다. docker rm my-app
docker rm -f [컨테이너] 실행 중인 컨테이너를 강제로 종료하고 삭제합니다. docker rm -f my-app

 

3) Docker Compose 명령어 (통합 관리)

여러 컨테이너(yml 파일)로 구성된 서비스를 한 번에 관리

명령어  설명  예시 
docker compose up -d 설정 파일(yml)에 따라 컨테이너를 생성하고 백그라운드 실행합니다. docker compose up -d
docker compose down 실행된 컨테이너, 네트워크를 모두 정지하고 삭제합니다. docker compose down
docker compose stop 컨테이너를 삭제하지 않고 잠시 중지만 합니다. docker compose stop
docker compose restart [서비스명] 특정 서비스(예: nginx)만 콕 집어서 재시작합니다. docker compose restart nginx
docker compose logs -f 연동된 모든 서비스의 로그를 한 화면에서 실시간으로 봅니다. docker compose logs -f

 

4) 컨테이너 내부 접속 및 DB 관리 (Advanced)

컨테이너 안으로 직접 들어가서 명령어를 치거나 DB를 조회할 때

명령어  설명 예시
docker exec -it [컨테이너] bash 실행 중인 컨테이너의 내부 쉘(Shell)로 접속합니다. docker exec -it docker-mattermost-1 bash
docker exec -it [컨테이너] sh bash가 없는 경량 컨테이너(Alpine 등)에 접속할 때 씁니다. docker exec -it nginx_mattermost sh
docker exec -it [DB컨테이너] psql -U [유저] [DB명] PostgreSQL DB에 바로 접속하여 SQL 쿼리를 날립니다. docker exec -it docker-postgres-1 psql -U mmuser mattermost
docker exec -it [DB컨테이너] mysql -u [유저] -p (MySQL/MariaDB 사용 시) DB에 접속합니다. docker exec -it docker-mysql-1 mysql -u root -p

 

5) 디스크 정리 및 캐시 삭제 (Clean Up)

Docker를 오래 쓰면 쌓이는 불필요한 파일들을 정리하여 용량을 확보합니다.

명령어  설명  예시
docker system prune 사용하지 않는(중지된) 컨테이너, 네트워크, 댕글링 이미지를 모두 삭제합니다. docker system prune
docker system prune -a 위 기능에 더해, 현재 컨테이너가 쓰지 않는 모든 이미지까지 싹 지웁니다. (강력함) docker system prune -a
docker image prune 이름이 없는(dangling) 불필요한 이미지만 골라서 삭제합니다. docker image prune
docker volume prune 주의: 어떤 컨테이너와도 연결되지 않은 데이터 볼륨을 영구 삭제합니다. (DB 데이터 날라감 주의 ⚠️) docker volume prune

 

 

 

6) 캐시 관리 및 빌드 제어 (Build & Cache)

이미지 빌드 속도를 위해 저장된 캐시를 관리하거나, 컨테이너를 초기화하고 싶을 때

명령어  설명  예시 
docker builder prune Docker 빌드 과정에서 생성된 모든 빌드 캐시를 삭제하여 용량을 확보합니다. docker builder prune
docker compose build --no-cache 캐시를 사용하지 않고 이미지를 처음부터 완전히 새로 빌드합니다. (코드 변경이 반영 안 될 때 유용) docker compose build --no-cache
docker compose build --no-cache [서비스] 특정 서비스만 콕 집어서 캐시 없이 재빌드합니다. docker compose build --no-cache mattermost
docker rmi [이미지ID] 특정 이미지를 삭제합니다. (해당 이미지를 쓰는 컨테이너가 없어야 삭제 가능) docker rmi a1b2c3d4
docker image prune -a 현재 실행 중인 컨테이너가 사용하지 않는 모든 이미지를 일괄 삭제합니다. docker image prune -a
docker system df 현재 Docker가 사용 중인 디스크 용량(이미지, 컨테이너, 볼륨, 캐시)을 보여줍니다. docker system df

 

 

6-1) Docker 디스크 사용량 분석 (docker system df)

더보기

1. TYPE (종류)

Docker가 관리하는 리소스의 4가지 유형입니다.

  • Images: 다운로드(pull)받거나 생성(build)한 도커 이미지 파일들입니다.
  • Containers: 이미지를 기반으로 현재 생성되어 있는 컨테이너들입니다. (실행 중 + 정지됨 모두 포함)
  • Local Volumes: 컨테이너의 데이터를 영구 저장하기 위해 생성된 볼륨(데이터 저장소)입니다. (DB 데이터, 설정 파일 등)
  • Build Cache: 이미지를 빌드할 때 속도를 높이기 위해 저장해 둔 임시 캐시 파일입니다.

 

2. TOTAL (총 개수)

해당 리소스가 내 컴퓨터에 총 몇 개가 있는지를 나타냅니다.

  • 예: Images가 10개라면, 내 PC에 도커 이미지가 10개 저장되어 있다는 뜻입니다.

 

3. ACTIVE (사용 중)

총 개수(TOTAL) 중에서 현재 실제로 실행 중인 컨테이너가 사용하고 있는 개수입니다.

  • Images: 현재 켜져 있는 컨테이너가 쓰고 있는 이미지 개수.
  • Local Volumes: 현재 컨테이너와 연결(Mount)되어 있는 볼륨 개수.
  • Containers: 현재 실행 중인(Up) 컨테이너 개수.

 

4. SIZE (사용 용량)

해당 리소스들이 차지하고 있는 실제 디스크 용량입니다.

  • Images: 모든 이미지 파일 크기의 합계.
  • Containers: 컨테이너가 실행되면서 추가로 생성한 파일(로그, 임시 파일 등)의 크기입니다. (이미지 크기는 제외됨)
    • 주의: 컨테이너 내부에서 파일을 많이 쓰면 이 수치가 커집니다.

 

5. RECLAIMABLE (회수 가능 용량 ⭐)

  • 이걸 지우면 이만큼 용량을 확보할 수 있다 는 뜻입니다. 가장 중요한 지표입니다.
  • 계산법: (전체 용량) - (현재 사용 중인 용량)
  • 즉, 지금 당장 docker system prune 명령어를 쳤을 때 지워질 수 있는 쓰레기 파일들의 총량입니다.
  • 옆에 있는 퍼센트(%)는 전체 대비 낭비되고 있는 비율을 보여줍니다.

예시 해석

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          5         2         1.5GB     800MB (53%)

  • 해석:
    • 내 PC에 이미지가 총 5개 있음.
    • 그중 2개는 지금 컨테이너가 쓰고 있음.
    • 전체 용량은 1.5GB임.
    • 쓰지 않는 나머지 3개를 지우면 800MB를 확보할 수 있음! (docker image prune으로 삭제 가능)

 

# Docker란?

Docker의 개념

Docker는 컨테이너 기반 가상화 기술로, 애플리케이션과 그 의존성을 하나의 패키지로 묶어서 어디서든 동일하게 실행할 수 있게 해주는 도구입니다.

 

1. Docker를 사용하는 이유

  • 환경 일관성
# 개발자 A의 환경
Windows 11 + Node.js 18.2.0 + React 18

# 개발자 B의 환경  
macOS + Node.js 18.2.0 + React 18

# 서버 환경
Ubuntu 22.04 + Node.js 18.2.0 + React 18

→ Docker로 모든 환경이 동일하게 보장됨

 

  • 의존성 관리
# 기존 방식: "내 컴퓨터에서는 되는데..."
npm install
npm start  # 실패할 수 있음

# Docker 방식: 항상 동일한 결과
docker run my-app  # 항상 성공
  • 배포 간소화
# 기존 방식
1. 서버에 Node.js 설치
2. 의존성 설치
3. 환경 변수 설정
4. 빌드
5. 실행

# Docker 방식
docker run my-app  # 한 번에 끝!

2. Dockerfile 사용법

Dockerfile이란?

Docker 이미지를 만드는 설계도입니다.

 

  • 기본구조
# 1. 베이스 이미지 선택
FROM node:18-alpine

# 2. 작업 디렉토리 설정
WORKDIR /app

# 3. 파일 복사
COPY package*.json ./

# 4. 의존성 설치
RUN npm install

# 5. 소스 코드 복사
COPY . .

# 6. 빌드
RUN npm run build

# 7. 포트 노출
EXPOSE 3000

# 8. 실행 명령
CMD ["npm", "start"]
  • 실제 예시(React)
# React 앱을 위한 Dockerfile
FROM node:18-alpine as build

WORKDIR /app

# 패키지 파일 복사 및 의존성 설치
COPY frontend/package*.json ./
RUN npm ci --legacy-peer-deps

# 소스 코드 복사 및 빌드
COPY frontend/ ./
RUN npm run build

# nginx를 사용한 프로덕션 서버
FROM nginx:alpine

# 빌드된 파일을 nginx에 복사
COPY --from=build /app/build /usr/share/nginx/html

# nginx 설정 파일 복사
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

 

※ Dockerfile 명령어 설명

  • FROM: 베이스 이미지
  • WORKDIR: 작업 디렉토리
  • COPY: 파일 복사
  • RUN: 명령어 실행
  • EXPOSE: 포트 노출
  • CMD: 컨테이너 시작 시 실행할 명령

 

3. Docker Compose 사용법

 

Docker Compose란?

여러 개의 Docker 컨테이너를 하나의 애플리케이션으로 관리하는 도구입니다.

 

 

Docker Compose를 사용하는 이유

 

1. 멀티 컨테이너 관리

# 프론트엔드 + 백엔드 + 데이터베이스를 한 번에!
services:
  frontend:    # React 앱
  backend:     # Spring Boot
  database:    # MariaDB

 

2. 네트워킹 자동화

# 컨테이너 간 통신 자동 설정
networks:
  app-network:
    driver: bridge

 

3. 환경 변수 관리

environment:
  - NODE_ENV=production
  - DATABASE_URL=mysql://db:3306/mydb

 

docker-compose.yml 구조

services:
  # 서비스 1: 프론트엔드
  frontend:
    build: 
      context: .
      dockerfile: Dockerfile
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - app-network

  # 서비스 2: 백엔드
  backend:
    build:
      context: .
      dockerfile: backend.Dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - db
    networks:
      - app-network

  # 서비스 3: 데이터베이스
  db:
    image: mariadb:10.11
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  db_data:

 

Docker Compose 명령어

# 서비스 시작
docker compose up

# 백그라운드 실행
docker compose up -d

# 빌드와 함께 시작
docker compose up --build

# 서비스 중지
docker compose down

# 로그 확인
docker compose logs -f

# 특정 서비스만 재시작
docker compose restart frontend

 

4. EC2 Ubuntu에서 Docker 배포하기

 

1. EC2 인스턴스 준비

# Ubuntu 22.04 LTS 인스턴스 생성
# t3.medium 이상 권장 (2GB RAM 이상)

 

2. Docker 설치

# SSH로 EC2 접속
ssh -i your-key.pem ubuntu@your-ec2-ip

# 시스템 업데이트
sudo apt update && sudo apt upgrade -y

# Docker 설치
sudo apt install -y docker.io docker-compose

# Docker 서비스 시작
sudo systemctl start docker
sudo systemctl enable docker

# 사용자를 docker 그룹에 추가
sudo usermod -aG docker ubuntu

# 재로그인 또는 다음 명령 실행
newgrp docker

 

 

3. 프로젝트 파일 업로드

# 방법 1: Git 사용
git clone <https://github.com/your-repo/sakai_project.git>
cd sakai_project

# 방법 2: SCP 사용
scp -i your-key.pem -r ./sakai_project ubuntu@your-ec2-ip:~/

# 방법 3: rsync 사용
rsync -avz -e "ssh -i your-key.pem" ./sakai_project/ ubuntu@your-ec2-ip:~/sakai_project/

 

 

4. 백엔드 파일 준비

# 백엔드 파일도 함께 업로드
scp -i your-key.pem -r ../sakai_backend ubuntu@your-ec2-ip:~/

 

 

5. Docker Compose 실행

# EC2에서 실행
cd sakai_project

# Docker Compose로 서비스 시작
docker compose up -d --build

# 상태 확인
docker compose ps

# 로그 확인
docker compose logs -f

 

 

6. 보안 그룹 설정

# AWS 콘솔에서 보안 그룹 설정
# 인바운드 규칙 추가:
# - HTTP (80) - 0.0.0.0/0
# - HTTPS (443) - 0.0.0.0/0 (선택사항)
# - SSH (22) - Your IP

 

 

7. 도메인 설정 (선택사항)

# Nginx 설정으로 도메인 연결
# /etc/nginx/sites-available/default 수정
server {
    listen 80;
    server_name your-domain.com;
    
    location / {
        proxy_pass <http://localhost:80>;
    }
}

 

 

5. 완전한 배포 스크립트

#!/bin/bash

# EC2 배포 스크립트
echo "🚀 Sakai 프로젝트 배포 시작..."

# 1. 시스템 업데이트
sudo apt update && sudo apt upgrade -y

# 2. Docker 설치 (이미 설치되어 있다면 스킵)
if ! command -v docker &> /dev/null; then
    sudo apt install -y docker.io docker-compose
    sudo systemctl start docker
    sudo systemctl enable docker
    sudo usermod -aG docker ubuntu
fi

# 3. 프로젝트 디렉토리로 이동
cd ~/sakai_project

# 4. 기존 컨테이너 정리
docker compose down
docker system prune -f

# 5. 새로 빌드 및 실행
docker compose up -d --build

# 6. 상태 확인
echo "✅ 배포 완료!"
echo "📊 서비스 상태:"
docker compose ps

echo "🌐 접속 URL:"
echo "Frontend: <http://$>(curl -s ifconfig.me):80"
echo "Backend API: <http://$>(curl -s ifconfig.me):8080"
  • 실행 방법
# 스크립트 실행 권한 부여
chmod +x deploy.sh

# 배포 실행
./deploy.sh

 

 

6. 배포 체크리스트

 

배포 전 확인사항

  • [ ] [ ] EC2 인스턴스 생성 완료
  • [ ] 보안 그룹 설정 (80, 8080 포트 열기)
  • [ ] 프로젝트 파일 업로드 완료
  • [ ] 백엔드 파일 업로드 완료
  • [ ] [ ] Docker 설치 완료

 

배포 후 확인사항

  • [ ] [ ] docker compose ps로 모든 서비스 실행 확인
  • [ ] [ ] curl http://localhost:80으로 프론트엔드 접속 확인
  • [ ] [ ] curl http://localhost:8080/api/health로 백엔드 확인
  • [ ] 외부에서 접속 테스트

+ Recent posts