도커 가이드 · 6 min read · Feb 04, 2026
도커 가이드: MySQL 및 Traefik과 함께 도커로 Ghost 블로그 배포하기

Ghost는 nodejs 기반의 강력한 오픈 소스 출판 및 블로그 플랫폼입니다. 잘 설계되어 있고 사용하기 쉽습니다. Ghost 플랫폼은 JavaScript로 작성되었으며 node.js를 런타임 환경으로 사용합니다. 첫 번째 Ghost 버전은 2013년에 MIT 라이센스 하에 출시되었습니다.
Traefik은 마이크로서비스를 위한 현대적인 HTTP 리버스 프록시 및 로드 밸런서입니다. Traefik은 Docker, Swarm 모드, Kubernetes, Amazon ECS, Rancher, Etcd, Consul 등과 같은 기존 인프라 구성 요소와 통합되어 모든 마이크로서비스 배포를 쉽게 만듭니다.
이 튜토리얼에서는 Ghost를 도커 컨테이너로 설치하고 구성하는 방법을 단계별로 보여줍니다. 최신 Docker CE 버전에서 Ghost를 설치하고 구성하며, MySQL을 데이터베이스로 사용하고 Traefik을 리버스 프록시로 사용할 것입니다.
필수 조건
- Ubuntu 18.04 LTS
- 루트 권한
우리가 할 일
- Ubuntu 18.04 LTS에 Docker CE 설치
- 비루트 사용자용 Docker 설정
- Docker Compose 설치
- Ghost 스택 구성 - 사용자 정의 네트워크 생성
- 프로젝트 디렉토리 생성
- MySQL 컨테이너 생성 및 구성
- Traefik 리버스 프록시 생성 및 구성
- Ghost 컨테이너 생성 및 구성
- MySQL 및 Traefik과 함께 Ghost 배포
- 테스트
1단계 - Ubuntu 18.04 LTS에 Docker CE 설치
이 튜토리얼에서 우리가 할 첫 번째 단계는 시스템의 최신 docker-ce 버전을 설치하는 것입니다. docker-ce 버전은 공식 docker 저장소에서 설치할 수 있습니다.
docker 키와 docker-ce 저장소를 추가합니다.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"이 명령은 시스템의 모든 저장소를 자동으로 업데이트합니다.
이제 아래의 apt 명령을 사용하여 docker를 설치합니다.
sudo apt install docker-ce -y설치가 완료되면 docker 서비스를 시작하고 시스템 시작 시마다 실행되도록 활성화합니다.
systemctl start docker
systemctl enable docker최신 docker-ce 버전이 Ubuntu 18.04 시스템에 설치되었습니다.

2단계 - 비루트 사용자용 Docker 설정
이 가이드에서는 모든 컨테이너 마이크로서비스가 일반/비루트 사용자로 실행됩니다. 따라서 사용자가 Docker 컨테이너를 실행하고 루트 권한을 위해 sudo 명령을 실행할 수 있도록 구성해야 합니다.
‘hakase’라는 새 사용자를 만들고 비밀번호를 설정합니다.
useradd -m -s /bin/bash hakase
passwd hakase이제 ‘hakase’ 사용자를 ‘sudo’ 및 ‘docker’ 그룹에 추가합니다.
usermod -a -G root hakase
usermod -a -G docker hakase그리고 docker 서비스를 재시작합니다.
systemctl restart docker이제 ‘hakase’는 docker 컨테이너를 실행하고 루트 권한을 위해 sudo 명령을 실행할 수 있습니다.

‘hakase’ 사용자로 로그인하고 docker hello-world 컨테이너를 실행합니다.
su - hakase
docker run -it hello-world그리고 다음은 결과입니다.

3단계 - Docker Compose 설치
이 튜토리얼에서는 Github 저장소의 바이너리 파일에서 docker compose 1.21을 설치합니다.
docker-compose 바이너리를 ‘/usr/local/bin’ 디렉토리에 다운로드합니다.
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose그리고 파일 권한을 변경하여 ‘docker-compose’ 파일을 실행 가능하게 만듭니다.
sudo chmod +x /usr/local/bin/docker-composedocker compose가 설치되었습니다 - 아래 명령을 사용하여 확인합니다.
docker-compose version
docker version
Docker-compose 1.21과 Docker-ce 1.18이 설치되었습니다.
4단계 - Ghost 스택 구성
이 단계에서는 docker를 구성하고 ghost 설치를 위한 새로운 docker-compose 파일을 생성합니다.
새로운 docker 사용자 정의 네트워크를 만들고 MySQL 데이터베이스, Traefik 리버스 프록시 및 Ghost 블로그를 포함한 세 가지 주요 서비스를 포함하는 새로운 docker-compose yml 파일을 생성합니다.
사용자 정의 네트워크 생성
아래의 docker network 명령을 사용하여 사용 가능한 docker 네트워크를 표시합니다.
docker network ls‘traefiknet’이라는 이름의 traefik 리버스 프록시를 위한 새로운 사용자 정의 docker 네트워크를 생성합니다.
docker network create traefiknet이제 docker 시스템에서 사용 가능한 네트워크를 다시 확인합니다.
docker network ls
‘Treafik’을 위한 사용자 정의 네트워크 ‘traefiknet’이 생성되었습니다.
프로젝트 디렉토리 생성
docker 사용자 정의 네트워크를 생성한 후 ‘ghost’라는 이름의 새로운 프로젝트 디렉토리를 만들고 새로운 docker-compose.yml 파일을 생성합니다.
‘hakase’ 사용자로 로그인합니다.
su - hakase새로운 ‘ghost’ 디렉토리를 만들고 작업 디렉토리를 변경합니다.
mkdir ghost/
cd ghost/그리고 새로운 docker-compose 파일을 생성합니다.
touch docker-compose.ymlMySQL 서비스 생성 및 구성
MySQL은 우리가 만들고자 하는 첫 번째 서비스이며, 아래의 구성으로 MySQL 컨테이너를 생성하고자 합니다.
- MySQL 5.7 docker 이미지를 사용할 것입니다.
- MySQL 데이터 디렉토리를 로컬 docker 호스트 디렉토리에 마운트합니다.
- 로컬 내부 네트워크에서 MySQL 서비스를 실행합니다.
- MySQL 사용자 및 비밀번호를 구성합니다. - MySQL 루트 비밀번호: mypassword
- ‘ghost’라는 사용자와 비밀번호 ‘ghostdbpass’를 가진 ‘ghost’라는 이름의 데이터베이스를 생성합니다.
- MySQL 컨테이너의 이름은 ‘mysql’입니다.
‘ghost’ 디렉토리 내에 ‘data’라는 새로운 디렉토리를 만들고 ‘docker-compose.yml’ 파일을 편집합니다.
mkdir -p data/
vim docker-compose.yml아래 구성을 붙여넣습니다.
version: '3.3'
services:
mysql:
image: mysql:5.7
restart: always
volumes:
- ./data:/var/lib/mysql
labels:
- "traefik.enable=false"
networks:
- internal
environment:
MYSQL_ROOT_PASSWORD: mypassword
MYSQL_USER: ghost
MYSQL_PASSWORD: ghostdbpass
MYSQL_DATABASE: ghostdb
container_name: mysql저장하고 종료합니다.
Traefik 리버스 프록시 생성 및 구성
MySQL 서비스를 생성한 후 Traefik 리버스 프록시 컨테이너를 생성하고 구성합니다.
‘docker-compose.yml’ 스크립트를 편집하기 전에 ‘traefik.toml’이라는 이름의 새로운 traefik 구성을 생성해야 합니다.
vim traefik.toml아래의 traefik 규칙 구성을 붙여넣습니다.
#Traefik 전역 구성
debug = false
checkNewVersion = true
logLevel = "ERROR"
#HTTP 및 HTTPS를 위한 EntryPoint 정의
defaultEntryPoints = ["https","http"]
#HTTP 포트 80 및
#HTTPS 포트 443 EntryPoint 정의
#HTTP를 HTTPS로 자동으로 리디렉션 활성화
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
#8080 포트에서 Traefik 대시보드 활성화
#기본 인증 방법 사용
#hakase 및 비밀번호
[entryPoints.dash]
address=":8080"
[entryPoints.dash.auth]
[entryPoints.dash.auth.basic]
users = [
"hakase:$apr1$hEgpZUN2$OYG3KwpzI3T1FqIg9LIbi.",
]
[api]
entrypoint="dash"
dashboard = true
#네트워크 오류 시 요청 재전송 활성화
[retry]
#Docker 백엔드 구성 정의
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "hakase-labs.io"
watch = true
exposedbydefault = false
#Letsencrypt 등록
#Letsencrypt ACME HTTP 챌린지 정의
[acme]
email = "[email protected]"
storage = "acme.json"
entryPoint = "https"
OnHostRule = true
[acme.httpChallenge]
entryPoint = "http"저장하고 종료합니다.
이제 SSL Letsencrypt 구성을 위한 새로운 파일 ‘acme.json’을 생성해야 합니다. 이는 모든 letsencrypt 생성 로그를 저장하는 데 사용됩니다.
빈 ‘acme.json’ 파일을 생성하고 권한을 600으로 변경합니다.
touch acme.json
chmod 600 acme.json다음으로 ‘docker-compose.yml’ 스크립트를 편집하고 traefik 서비스 구성을 추가합니다.
- 최신 traefik docker 이미지를 사용할 것입니다.
- 컨테이너 이름은 ‘traefik’입니다.
- 사용자 정의 네트워크 ‘traefiknet’을 사용하고 HTTP 및 HTTPS 포트를 노출합니다.
- docker sock 파일과 traefik 구성 ‘traefik.toml’ 및 ‘acme.json’을 마운트합니다.
- docker 레이블을 통해 traefik 대시보드 URL과 백엔드를 정의합니다.
‘docker-compose.yml’을 편집합니다.
vim docker-compose.yml아래의 traefik 서비스 구성을 붙여넣습니다.
traefik:
image: traefik:latest
command: --docker
ports:
- 80:80
- 443:443
labels:
- "traefik.enable=true"
- "traefik.backend=dashboard"
- "traefik.frontend.rule=Host:traef.hakase-labs.io"
- "traefik.port=8080"
networks:
- traefiknet
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
- ./acme.json:/acme.json
container_name: traefik
restart: always저장하고 종료합니다.
Ghost 서비스 생성 및 구성
Traefik 리버스 프록시를 구성한 후 주요 ghost 서비스 구성을 생성합니다.
우리가 만들고자 하는 구성 세부 사항은 다음과 같습니다.
- 우리는 ghost v1과 소형 docker alpine 버전을 사용할 것입니다.
- ghost 콘텐츠 디렉토리를 ‘blog’라는 로컬 디렉토리에 마운트합니다.
- ghost 서비스는 기본 포트에서 ‘gho.hakase-labs.io’라는 도메인 이름으로 실행됩니다. docker 레이블을 통해 구성합니다.
- ghost 서비스는 내부 및 traefiknet의 두 개의 docker 네트워크를 사용할 것입니다.
- mysql 컨테이너 구성에서 MySQL 데이터베이스 세부 정보를 구성합니다.
- 그리고 ghost는 traefik 및 MySQL 컨테이너가 실행될 때 시작됩니다.
‘blog’라는 이름의 새로운 디렉토리를 만들고 ‘docker-compose.yml’ 파일을 편집합니다.
mkdir -p blog/
vim docker-compose.yml아래 구성을 붙여넣습니다.
ghost:
image: ghost:1-alpine
restart: always
ports:
- 2368
volumes:
- ./blog:/var/lib/ghost/content
labels:
- "traefik.enabled=true"
- "traefik.backend=ghost"
- "traefik.frontend.rule=Host:gho.hakase-labs.io"
- "traefik.docker.network=traefiknet"
- "traefik.port=2368"
networks:
- internal
- traefiknet
environment:
database__client: mysql
database__connection__host: mysql
database__connection__user: ghost
database__connection__password: ghostdbpass
database__connection__database: ghostdb
container_name: ghost
depends_on:
- mysql
- traefik
networks:
traefiknet:
external: true
internal:
external: false저장하고 종료합니다.

이제 모든 디렉토리와 구성이 아래와 같이 표시됩니다.
tree
5단계 - MySQL 및 Traefik과 함께 Ghost 배포
모든 ghost 스택 서비스를 빌드하고 실행하기 위해 아래 명령을 사용할 수 있습니다.
docker-compose up -d
완료되면 모든 실행 중인 서비스를 확인합니다.
docker-compose ps다음은 결과입니다.
오류가 발생하면 아래 명령을 사용하여 컨테이너 로그를 확인합니다.
docker-compose logs mysql
docker-compose logs traefik
docker-compose logs ghost
MySQL 및 Traefik 리버스 프록시와 함께 ghost 스택이 실행 중입니다.
6단계 - 테스트
Traefik 대시보드를 URL로 엽니다. 제 URL은 http://traef.hakase-labs.io/입니다.
‘traefik.toml’ 파일의 사용자 및 비밀번호로 로그인합니다.
다음은 Traefik 대시보드입니다.

Ghost 설치를 위해 주소 표시줄에 ghost URL을 입력합니다. 제 URL은 http://gho.hakase-labs.io/입니다.
그러면 ghost 홈페이지가 표시됩니다.

이제 관리 페이지를 방문하여 새 관리 사용자를 설정하고 구성합니다. 제 URL은: http://gho.hakase-labs.io/admin/
새 관리 사용자를 생성하기 위해 녹색 버튼을 클릭합니다.

사용자 세부 정보, 비밀번호, 이메일을 입력하고 다시 녹색 버튼을 클릭합니다.

새 구성원이나 사용자를 초대하려면 ‘나중에 하겠습니다..’ 링크를 클릭합니다.

이제 Ghost 대시보드를 얻을 수 있습니다.

샘플 게시물을 생성한 후 다음은 결과입니다.

MySQL 데이터베이스와 Traefik 리버스 프록시를 사용한 Ghost 블로그 설치가 성공적으로 완료되었습니다.
참고 문헌
새 게시물을 받은 편지함에서 받기
스팸은 없습니다. 언제든지 구독 해지 가능합니다.