stamper
CLI개인서버DockerCompose배포

개인 서버 구축 3: Docker Compose로 앱을 격리 배포하는 CLI 프롬프트

개발자김철수1시간 전조회 2추천 0
변수 입력8
변수를 채운 뒤 완성본을 복사하세요

이번 단계의 목표

애플리케이션, API, database를 Docker Compose project로 재현 가능하게 실행한다. 저장소를 내려받아 바로 운영하는 것이 아니라 image version, persistent data, secret, health check, resource, rollback 경계를 먼저 정한다.

Cloudflare Tunnel을 붙이기 전 단계이므로 web origin은 기본적으로 127.0.0.1에만 bind한다. DB, Redis, admin port는 host의 공인 interface에 publish하지 않는다.

준비할 정보

  • {{REPOSITORY}}: 배포할 저장소와 검증된 commit SHA 또는 release tag
  • {{SERVICES}}: frontend, API, worker, DB, cache 구성
  • {{PORTS}}: service 내부 port와 공개할 web origin port
  • {{DATA}}: volume, upload, DB 등 영속 데이터 위치와 예상 크기
  • {{SECRETS}}: 필요한 환경변수 이름만 작성하고 값은 넣지 않는다.
  • {{RESOURCE_BUDGET}}: CPU, RAM, disk 한도
  • {{HEALTH_CHECKS}}: service별 정상 판정 endpoint·command

권장 디렉터리 예시

/srv/my-service/
├── compose.yml
├── .env                 # 값은 commit 금지, chmod 600
├── config/              # 비밀이 아닌 설정
├── data/                # 필요할 때만 명시적 bind mount
└── backup/              # 실제 backup은 다른 장치에도 복제

디렉터리 구조는 예시다. 기존 repository와 운영 규칙이 있다면 그것을 우선한다.

복사해서 쓰는 CLI agent 프롬프트

이 Linux 개인 서버에 {{REPOSITORY}}를 Docker Compose로 배포할 계획과 파일을 만들어줘.

서비스: {{SERVICES}}
port: {{PORTS}}
영속 데이터: {{DATA}}
필요한 secret 이름: {{SECRETS}}
resource budget: {{RESOURCE_BUDGET}}
health check: {{HEALTH_CHECKS}}

작업 규칙:
1. 저장소 지침과 현재 Docker 설치 여부, OS version, architecture, disk 여유, RAM을 먼저 확인해. 기존 container·network·volume은 수정하지 마.
2. Docker Engine과 Compose plugin은 해당 OS의 공식 repository 절차를 사용해 설치 계획을 보여줘. production에 convenience script를 바로 실행하지 마.
3. `docker` group이 사실상 root 권한이라는 점을 설명하고, 운영 계정을 group에 추가할지 rootless mode를 쓸지 장단점을 보고한 뒤 선택을 받아.
4. image는 검증 가능한 version 또는 digest로 고정해. `latest`만 사용하거나 source를 매 배포마다 무검증 build하지 마.
5. compose file에 restart policy, healthcheck, logging rotation, resource 보호, read-only filesystem 가능성, least privilege user를 service별로 검토해.
6. web origin만 `127.0.0.1:{{WEB_PORT}}`처럼 bind해. DB·cache·management port는 host에 publish하지 말고 Compose 내부 network에서만 연결해.
7. Docker가 publish한 port는 ufw 규칙을 우회할 수 있으므로 `docker compose config` 결과와 `ss -lntup`에서 실제 bind address를 검증해.
8. secret 값은 compose file, Dockerfile, image layer, repository, shell history, 결과 보고서에 넣지 마. `.env.example`에는 이름과 설명만 두고 실제 `.env`는 권한과 ignore 여부를 확인해.
9. DB schema migration과 application 시작을 분리하고, backup·호환성·rollback이 없는 destructive migration은 실행하지 마.
10. 첫 배포 전 image pull/build, config validation, 예상 변경, 중단 방법을 보여주고 승인을 받아. 실행 후에는 health와 log 일부만 확인하고 secret을 마스킹해.
11. rollback은 직전 image version, compose config, DB 호환 범위, data 복구 여부를 포함해. `down -v`, volume 삭제, system prune은 실행하지 마.

결과는 '현재 host 점검 / service·network·volume 설계 / 보안 결정 / 생성 파일 diff / secret 주입 절차 / dry-run / 배포 / health 검증 / rollback / 다음 단계 origin 정보' 순서로 작성해.

배포 전 검수

docker version
docker compose version
docker compose config --quiet
docker compose images
docker compose ps
sudo ss -lntup

docker compose config 출력에는 치환된 secret이 포함될 수 있으므로 전체 출력을 공유하지 않는다. CI나 문서에는 --quiet 검증을 우선한다.

배포 후 통과 기준

  • 모든 필수 service가 running 또는 healthy이며 restart loop가 없다.
  • web origin은 서버 내부의 127.0.0.1:{{WEB_PORT}}에서만 응답한다.
  • DB·cache port는 LAN·Tailscale·공인 interface에 노출되지 않는다.
  • 서버 재부팅 후 의도한 service만 자동 복구된다.
  • 직전 image로 되돌리는 명령과 data migration의 호환 범위가 문서화되어 있다.
  • log 파일과 Docker storage 증가가 disk를 가득 채우지 않도록 상한과 확인 방법이 있다.

자주 생기는 위험

  • 0.0.0.0:5432:5432처럼 DB를 모든 interface에 공개
  • .env 또는 private registry token을 Git에 commit
  • docker.sock을 불필요한 container에 mount
  • 이유 없이 privileged: true, host network, root user 사용
  • backup 없이 volume을 재생성하거나 docker compose down -v 실행
  • health check 없이 process가 떠 있다는 이유만으로 배포 성공 판정

공식 자료

댓글 0

아직 댓글이 없습니다.