콘텐츠로 건너뛰기

🐳 docker-compose.yml 제너레이터

폼 입력만으로 완전한 docker-compose.yml 생성. 다중 서비스, 포트, 볼륨, 환경 변수, 의존성, 네트워크 지원.

완전 무료 가입 불필요 브라우저 완결 5 개 언어 다크 모드

🔒 개인정보 보호

Compose 파일 version은 3.9로 고정

🌐 최상위 정의

📄 docker-compose.yml

📖 자주 걸리는 지점

서비스·포트·볼륨·환경 변수·의존 관계·네트워크·secrets 를 폼으로 지정하면 그대로 쓸 수 있는 docker-compose.yml 을 조립합니다. 처리는 브라우저 안에서 끝나며 입력은 전송되지 않습니다. 이 도구가 보증하는 것은 YAML 의 구문과 구조뿐입니다 — 이미지가 실재하는지, 그 안의 애플리케이션이 기동하는지, 서비스끼리 제대로 연결되는지는 검증할 수 없습니다. docker compose up 이 실패하는 원인의 대부분은 YAML 서식이 아니라 그 앞의 「순서」 「경로」 「권한」 세 가지에 있습니다. 아래가 그 셋입니다.

사례 무슨 일이 일어나는가 어떻게 하면 되는가
depends_on 은 「기동했다」까지만 기다린다 depends_on 이 보증하는 것은 컨테이너의 기동 순서뿐이며 안의 프로세스가 접속을 받아들일 상태가 되었는지는 보지 않습니다. 데이터베이스는 기동한 뒤 초기화와 복구를 마칠 때까지 수 초에서 수십 초가 걸리므로 애플리케이션 쪽은 아직 열리지 않은 포트에 접속하러 갔다가 죽습니다. 증상에 특징이 있습니다 — up 만 실패하고 다시 up 하면 동작합니다. 두 번째에는 데이터베이스가 이미 데워져 있기 때문입니다. 이 「가끔 실패한다」는 성질 탓에 로컬에서는 놓치고 CI 에서 처음 드러나는 일이 흔합니다. 재현되지 않는 버그가 아니라 경쟁 상태입니다. 의존받는 쪽에 healthcheck 를 쓰고 의존하는 쪽에서 condition: service_healthy 를 지정하세요. PostgreSQL 이라면 test: ["CMD-SHELL", "pg_isready -U postgres"], interval: 5s, retries: 10, start_period: 10s 가 실용적인 출발점입니다. 다만 이것으로도 완전하지는 않습니다실행 중에 데이터베이스가 재기동하면 애플리케이션은 또 접속을 잃습니다. 최종적인 답은 애플리케이션 쪽에 접속 재시도를 넣는 것입니다. 기동 순서에 기대지 않는 설계로 해 두면 compose 에서도 Kubernetes 에서도 매니지드 DB 에서도 똑같이 동작합니다. healthcheck 는 개발 경험을 좋게 하기 위한 보조로 생각하세요.
portsvolumes 의 좌우를 헷갈린다 양쪽 모두 왼쪽이 호스트, 오른쪽이 컨테이너입니다 ("8080:80" 은 호스트의 8080 을 컨테이너의 80 으로). 여기서 사고가 셋 생깁니다. 첫째, ports 는 기본적으로 모든 인터페이스에 공개됩니다"3306:3306" 이라고 쓰면 같은 LAN 의 누구든 데이터베이스에 도달할 수 있습니다. 둘째, 같은 compose 네트워크의 서비스끼리는 포트를 공개하지 않아도 서비스 이름으로 통신할 수 있습니다. db:5432 로 닿으므로 애플리케이션을 위해 ports 를 쓸 필요는 본래 없습니다. 셋째, 바인드 마운트는 이미지 쪽 내용을 가립니다./:/app 이라고 쓰면 이미지가 빌드 때 만든 /app/node_modules 는 보이지 않게 되고 compose 일 때만 「모듈이 없다」는 말을 듣습니다. 외부에 보여야 하는 것만 ports 에 쓰고 나머지는 쓰지 마세요. 로컬에서 DB 에 붙고 싶다면 "127.0.0.1:3306:3306" 이라고 써서 루프백으로 한정합니다. node_modules 문제는 「익명 볼륨으로 덮어쓰는」 것이 정석의 해이며 volumes:./:/app/app/node_modules 두 행을 나란히 씁니다 — 후자가 바인드 마운트 위에 겹쳐져 이미지 쪽 내용이 살아남습니다. 권한 어긋남 (호스트 UID 와 컨테이너 UID 가 달라 쓸 수 없거나 root 소유 파일이 생기는 문제) 은 user: "${UID}:${GID}" 로 맞출 수 있습니다Linux 에서만 문제가 됩니다 — macOS 와 Windows 의 Docker Desktop 은 가상화 계층이 흡수하므로 재현되지 않습니다.
환경 변수가 어디서 오는지 알 수 없게 된다 compose 에는 이름이 비슷하면서 하는 일이 다른 구조가 셋 있고 이것이 혼동의 원인입니다. (1) environment: 는 컨테이너에 넘기는 값. (2) env_file: 은 같은 일을 파일에서 하는 것. (3) YAML 안의 ${VAR}compose 자신이 읽어 들일 때 치환하는 변수이며 값은 호스트의 셸과 프로젝트 바로 아래의 .env 에서만 옵니다. 여기가 최대의 함정입니다env_file: 에 쓴 값은 ${VAR} 의 해결에 쓰이지 않습니다. 게다가 정의되지 않은 ${VAR} 은 빈 문자열이 될 뿐 오류가 되지 않으므로 image: myapp:${TAG} 가 조용히 myapp: 이 되어 latest 가 당겨집니다. 추측하지 말고 docker compose config 를 읽으세요. 이것은 치환을 모두 해결한 최종형의 YAML 을 출력합니다 — 실제로 무엇이 넘어가는지를 볼 수 있는 유일한 곳입니다. 비어 있는 값이 있다면 거기가 정의되지 않은 ${VAR} 입니다. 기밀의 취급에 대해서도 방침을 정하세요: environment: 에 직접 쓴 값은 docker inspect 로 누구나 읽을 수 있고 Git 에도 들어갑니다. env_file: 은 파일을 .gitignore 에 넣을 수 있는 만큼 낫지만 컨테이너 안에서는 똑같이 그냥 환경 변수입니다. 프로덕션에서는 compose 의 secrets: 나 시크릿 관리 서비스를 쓰세요 — 전자는 파일로 마운트되므로 환경 변수처럼 자식 프로세스에 자동으로 상속되지 않습니다.

이 도구가 출력하는 version: '3.9' 는 현재의 Compose V2 에서는 건너뜁니다. the attribute version is obsolete 라는 경고가 나오지만 동작에는 영향이 없습니다 — 거슬리면 그 한 행을 지우세요. 버전 번호는 Compose V1 시절에 기능 세트를 고르기 위한 것이었지만 V2 는 언제나 최신 사양으로 해석합니다. 운용 면에서 자주 밟는 것을 둘 더 들어 둡니다. restart: always 는 기동 직후 죽는 컨테이너를 무한히 재기동시킵니다로그가 반복으로 메워지고 진짜 오류 메시지는 첫 회분만 남아 찾기 어려워집니다. 원인 조사 중에는 빼 두세요. 또 하나, docker compose down 은 이름 있는 볼륨을 지우지 않습니다. 데이터베이스 초기화 스크립트가 「안 듣는다」면 대개 예전 볼륨이 남아 있습니다 — 대부분의 이미지는 데이터 디렉터리가 비어 있을 때만 초기화를 실행하기 때문입니다. 다시 만들려면 docker compose down -v 가 필요하고 이 명령은 데이터를 정말로 지웁니다.

📖 사용법

  1. 1
    프리셋 선택 또는 서비스 추가
    LAMP, Next.js, Laravel 등 6가지 프리셋에서 시작하거나 빈 서비스 카드를 추가합니다.
  2. 2
    각 서비스 필드 입력
    image, ports, volumes, environment, depends_on, restart, networks 입력. 실시간 반영.
  3. 3
    복사 또는 다운로드
    생성된 YAML을 한 번에 복사하거나 docker-compose.yml로 다운로드.

❓ 자주 묻는 질문

어떤 compose 버전이 생성되나요?
version: 3.9를 출력합니다. Docker Engine 19.03 이상에서 동작합니다.
비밀번호와 API 키가 전송되나요?
아니요. 모든 처리는 브라우저 내에서 이루어지며 네트워크 전송은 없습니다.
생성된 YAML을 바로 docker compose up으로 실행할 수 있나요?
예. 프리셋은 공식 이미지와 기본 설정을 사용하므로 그대로 동작합니다. 프로덕션은 .env / secrets로 분리하세요.
🐛 이 도구에서 문제가 발생했나요?

무료 · 가입 불필요. 재현 절차만이라도 도움이 됩니다. 보고는 운영자에게 직접 전달되어 개선에 사용됩니다.

※ 재현을 위해 브라우저 정보 (UA / 화면 / 언어 / URL) 가 자동 전송됩니다