EQVPS

VPS에 Docker Compose 스택 배포하는 방법

Docker Compose로 VPS에 멀티 컨테이너 스택 배포하기: docker-compose.yml을 작성하고, 비밀은 .env에 두고, 재부팅 후 자동 실행되게 올리고, 정말 의도한 포트만 공개하세요. 웹 앱, 데이터베이스, 리버스 프록시가 있는 복사-붙여넣기 예제.

Docker Compose는 멀티 컨테이너 스택을 한 파일로 설명하고 한 명령으로 실행합니다. 이것은 배포 가이드입니다. 아직 안 했다면 먼저 Docker를 설치하세요. AI 에이전트 전용 스택(에이전트 + 벡터 DB + Redis)은 AI 에이전트용 docker-compose를 보세요.

1. 스택: 앱 + 데이터베이스 + 리버스 프록시

# /opt/stack/docker-compose.yml
services:
  app:
    image: your/app:latest
    restart: unless-stopped
    env_file: [.env]
    depends_on: [db]
    # no ports: — reached only through the proxy below

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes: ["pg:/var/lib/postgresql/data"]   # internal only

  caddy:                                        # HTTPS automatically
    image: caddy:2
    restart: unless-stopped
    ports: ["80:80", "443:443"]                 # the only public entrypoint
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data

volumes: { pg: {}, caddy_data: {} }

비밀은 .env에 살고, compose 파일에는 절대 두지 않습니다:

# /opt/stack/.env  (chmod 600, git-ignored)
DB_PASSWORD=a-long-random-string

최소한의 Caddyfile은 도메인을 앱으로 프록시하고 HTTPS를 스스로 가져옵니다:

app.yourdomain.com {
  reverse_proxy app:8080
}

2. 올리기

cd /opt/stack
docker compose up -d
docker compose ps
docker compose logs -f app

각 서비스의 restart: unless-stopped + 부팅 시 활성화된 Docker = 스택이 재부팅 후 스스로 돌아옵니다.

3. 일상 명령

docker compose pull && docker compose up -d   # update images
docker compose down                            # stop the stack
docker compose restart app                     # restart one service

사람들이 틀리는 부분: 노출된 포트

Docker는 포트를 iptables를 통해 공개하므로, ports: ["5432:5432"]가 있는 컨테이너는 닫혔다고 생각한 UFW 방화벽 뒤에서도 인터넷에서 접근됩니다. 공개 진입점만 공개하세요(80/443의 프록시). 데이터베이스와 캐시는 compose 네트워크나 127.0.0.1에 바인딩해 두세요. 웹 트래픽을 서비스하는 것은 무엇이든 전용 IP 요금제가 필요합니다. UFW 방화벽과 함께 쓰세요.

한 IP 뒤에 스택 전체를 두려면 여러 서비스 자체 호스팅을 보세요. 약 1분이면 root, NVMe, KYC 없음, 암호화폐로 결제.

자주 묻는 질문

VPS에 Docker Compose 스택을 어떻게 배포하나요?

Compose 플러그인이 있는 Docker를 설치하고, 각 서비스를 설명하는 docker-compose.yml을 작성하고, 비밀은 git이 무시하는 .env에 두고, docker compose up -d. 각 서비스에 restart: unless-stopped를 설정하고 부팅 시 Docker를 활성화해 스택이 재부팅을 견디게 하세요. 아래 예제는 웹 앱, Postgres, Caddy 리버스 프록시를 실행합니다.

비밀은 어디에 두나요 — compose 파일에?

아니요. .env 파일(chmod 600, git 무시)에 두고 compose에서 ${VAR}로 참조하거나 Docker secrets를 쓰세요. 비밀번호나 API 키를 절대 docker-compose.yml에 커밋하지 마세요 — 유효한 자격 증명이 담긴 유출 파일은 전형적인 실수입니다.

스택이 재부팅 후 돌아오나요?

그렇게 지시할 때만요. 각 서비스에 restart: unless-stopped(또는 always)를 설정하고 부팅 시 Docker를 활성화하세요(systemctl enable docker). 그러면 docker compose up -d가 재부팅을 견디고 죽은 컨테이너를 재시작합니다.

어떤 포트가 노출되나요?

ports:로 공개한 것만요. 내부 서비스(데이터베이스, 캐시)는 compose 네트워크나 127.0.0.1에 바인딩하고 공개 진입점 — 보통 80/443의 리버스 프록시 — 만 공개하세요. Docker는 iptables를 통해 공개하므로, 실수로 넣은 ports: 한 줄은 닫혔다고 생각한 UFW 뒤에서도 인터넷에서 접근됩니다.

신분증이나 카드를 요구하나요?

아니요. 가입에 이메일, 결제는 USDC 또는 USDT — 서류 없음, 카드 없음. 약 1분이면 root.

댓글

아직 댓글이 없습니다. 첫 번째가 되세요.

댓글 남기기

댓글은 표시되기 전에 검토됩니다.