블로그 배포 · 9 min read · Oct 23, 2025
Debian 12에서 Nginx로 Ghost 블로그 배포하는 방법

Ghost는 전문적인 블로그를 만들 수 있도록 도와주는 오픈 소스 블로깅 플랫폼입니다. 2013년에 WordPress의 대안으로 출시되었습니다. JavaScript로 작성되었으며 Node.js 라이브러리로 구동됩니다.
이 튜토리얼에서는 Debian 12에서 Nginx와 MySQL을 사용하여 Ghost CMS를 설치하는 방법을 살펴보겠습니다. 설치를 안전하게 하기 위해 Let’s Encrypt SSL 인증서를 사용할 것입니다.
전제 조건
- 최소 2GB의 RAM을 가진 Debian 12를 실행하는 서버.
- sudo 권한이 있는 비루트 사용자.
- 서버를 가리키는 완전한 도메인 이름(FQDN) 예:
example.com. - 모든 것이 업데이트되었는지 확인합니다.
$ sudo apt update $ sudo apt upgrade - 시스템에 필요한 몇 가지 패키지.
$ sudo apt install wget curl nano ufw software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release debian-archive-keyring unzip -y이 패키지 중 일부는 이미 시스템에 설치되어 있을 수 있습니다.
1단계 - UFW 방화벽 구성
첫 번째 단계는 방화벽을 구성하는 것입니다. Debian은 기본적으로 ufw(간단한 방화벽)를 제공합니다.
방화벽이 실행 중인지 확인합니다.
$ sudo ufw status
다음과 같은 출력이 표시되어야 합니다.
Status: inactive
SSH 포트를 허용하여 방화벽이 활성화될 때 현재 연결이 끊어지지 않도록 합니다.
$ sudo ufw allow OpenSSH
HTTP 및 HTTPS 포트도 허용합니다.
$ sudo ufw allow http
$ sudo ufw allow https
방화벽을 활성화합니다.
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
방화벽 상태를 다시 확인합니다.
$ sudo ufw status
유사한 출력을 볼 수 있어야 합니다.
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443 ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
2단계 - Nginx 설치
Debian 12는 이전 버전의 Nginx를 포함하고 있습니다. 최신 버전을 설치하려면 공식 Nginx 저장소를 다운로드해야 합니다.
Nginx의 서명 키를 가져옵니다.
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Nginx의 안정적인 버전 저장소를 추가합니다.
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
시스템 저장소를 업데이트합니다.
$ sudo apt update
Nginx를 설치합니다.
$ sudo apt install nginx
설치를 확인합니다. sudo는 Debian에서 명령을 실행하는 데 필요합니다.
$ sudo nginx -v
nginx version: nginx/1.24.0
Nginx 서버를 시작합니다.
$ sudo systemctl start nginx
3단계 - Node.js 설치
Ghost 설치 프로그램은 작동하기 위해 Node.js가 필요합니다. 첫 번째 단계는 Nodesource GPG 키를 가져오는 것입니다.
$ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg
다음으로 Nodesource 저장소 파일을 생성합니다. Ghost에서 권장하는 현재 LTS(장기 지원) 버전인 Node 18x를 설치할 것입니다.
$ NODE_MAJOR=18
$ echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
시스템 저장소 목록을 업데이트합니다.
$ sudo apt update
Node를 설치합니다.
$ sudo apt install nodejs -y
Node 설치를 확인합니다.
$ node --version
v18.18.2
4단계 - Docker를 사용하여 MySQL 설치
Debian은 더 이상 MySQL을 제공하지 않습니다. 대신 MariaDB를 제공합니다. Ghost는 MySQL만 지원합니다. MariaDB와 함께 작동하도록 Ghost를 조정할 수 있지만 권장되지 않습니다. 이 튜토리얼을 작성할 당시 MySQL의 공식 저장소는 Debian 12에 대해 업데이트되지 않았으므로 Docker를 사용하여 설치할 것입니다.
Docker GPG 키를 가져옵니다.
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
Docker 저장소 파일을 생성합니다.
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
시스템 저장소 목록을 업데이트합니다.
$ sudo apt update
Docker 및 Docker Compose를 설치합니다.
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
기본적으로 Docker는 루트 권한이 필요합니다. docker 명령을 실행할 때마다 sudo를 사용하지 않으려면 사용자 이름을 docker 그룹에 추가합니다.
$ sudo usermod -aG docker $(whoami)
이 변경 사항을 활성화하려면 서버에서 로그아웃한 후 동일한 사용자로 다시 로그인해야 하거나 다음 명령을 사용할 수 있습니다.
$ su - ${USER}
사용자가 Docker 그룹에 추가되었는지 확인합니다.
$ groups
navjot wheel docker
이제 Docker가 설치되었으므로 MySQL용 Docker Compose 파일을 생성해야 합니다. MySQL Docker를 위한 디렉토리를 생성합니다.
$ mkdir ~/mysql
docker-compose.yml 파일을 생성하고 편집을 위해 엽니다.
$ nano docker-compose.yml
다음 코드를 붙여넣습니다.
services:
database:
image: container-registry.oracle.com/mysql/community-server:latest
container_name: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_USER: ghost
MYSQL_PASSWORD: ghostpassword
MYSQL_DATABASE: ghostdb
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql
프롬프트가 표시되면 Ctrl + X를 눌러 파일을 저장하고 Y를 입력합니다.
여기서 우리는 루트 비밀번호와 Ghost 데이터베이스의 MySQL 자격 증명을 설정했습니다. 이러한 내용은 컨테이너가 실행될 때 생성됩니다.
MySQL 컨테이너를 시작합니다.
$ docker compose up -d
Docker 컨테이너의 상태를 확인합니다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec42fb205f1e container-registry.oracle.com/mysql/community-server:latest "/entrypoint.sh mysq…" 4 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060-33061/tcp mysql
Ghost는 포트 3306을 사용하여 MySQL 컨테이너에 연결하고 작업을 수행할 수 있습니다.
5단계 - Ghost 설치
Docker를 사용하여 Ghost를 설치할 수도 있지만 여기서는 그렇게 하지 않겠습니다.
Ghost 설치는 Ghost-CLI 명령줄 도구와 블로그 패키지 자체의 세 가지 구성 요소로 이루어집니다.
Ghost-CLI 설치
Ghost-CLI 도구를 설치하려면 다음 명령을 실행합니다.
$ sudo npm install ghost-cli@latest -g
Ghost 디렉토리 준비
Ghost 루트 디렉토리를 생성합니다.
$ sudo mkdir -p /var/www/html/ghost
디렉토리의 소유권을 현재 사용자에게 설정합니다.
$ sudo chown $USER:$USER /var/www/html/ghost
올바른 디렉토리 권한을 설정합니다.
$ sudo chmod 755 /var/www/html/ghost
Ghost 디렉토리로 이동합니다.
$ cd /var/www/html/ghost
Ghost 설치
Ghost 설치는 단일 명령 프로세스입니다.
$ ghost install
설치 중에 CLI 도구는 블로그를 구성하기 위해 여러 질문을 합니다.
- 블로그 URL: https 프로토콜과 함께 전체 블로그 URL을 입력합니다. (
https://example.com) - MySQL 호스트 이름: Ghost 설치와 MySQL이 동일한 서버에 있으므로 기본값인
localhost를 사용하려면 Enter를 누릅니다. - MySQL 사용자 이름: MySQL 사용자 이름으로
ghost를 입력합니다. - MySQL 비밀번호: Docker 파일에서 이전에 생성한 루트 비밀번호를 입력합니다.
- Ghost 데이터베이스 이름: Docker 파일에서 구성한 데이터베이스 이름 (
ghostdb)을 입력합니다. - Sudo 비밀번호: 관리 작업을 수행하기 위해 sudo 비밀번호를 입력하라는 메시지가 표시됩니다.
- Nginx 설정?: 일반적으로 Ghost-CLI는 Nginx 설치를 감지하고 블로그에 대해 자동으로 구성합니다. 그러나 이는 OS 패키지를 사용하여 설치된 Nginx에만 해당됩니다. 우리는 Nginx의 저장소를 사용하여 설치했기 때문에 Ghost는 이를 감지할 수 없으며 자동으로 건너뜁니다.
- SSL 설정?: Nginx 구성을 건너뛰었으므로 CLI 도구는 SSL 설정도 건너뜁니다.
- systemd 설정?: Ghost는 Ghost에 대한 시스템 서비스를 설정할 것인지 묻습니다. 진행하려면 Y를 누릅니다.
- Ghost 시작?: Ghost 설치를 시작하려면 Y를 누릅니다. 그러나 Nginx와 SSL이 아직 구성되지 않았기 때문에 작동하지 않을 것입니다.
6단계 - SSL 설치
진행하기 전에 Certbot 도구를 설치하고 도메인에 대한 SSL 인증서를 설치해야 합니다.
Certbot을 설치하기 위해 Snapd 패키지 설치 프로그램을 사용할 것입니다. Snapd는 항상 Certbot의 최신 안정 버전을 제공합니다. 그러나 Debian은 기본적으로 Snapd가 설치되어 있지 않습니다. 먼저 설치합니다.
$ sudo apt install snapd
snapd 버전이 최신인지 확인합니다.
$ sudo snap install core
$ sudo snap refresh core
Certbot을 설치합니다.
$ sudo snap install --classic certbot
다음 명령을 사용하여 /usr/bin 디렉토리에 대한 심볼릭 링크를 생성하여 Certbot 명령을 실행할 수 있도록 합니다.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
설치를 확인합니다.
$ certbot --version
certbot 2.7.1
SSL 인증서를 생성합니다.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d example.com
위 명령은 서버의 /etc/letsencrypt/live/example.com 디렉토리에 인증서를 다운로드합니다.
Diffie-Hellman 그룹 인증서를 생성합니다.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Certbot 갱신 스케줄러 서비스를 확인합니다.
$ sudo systemctl list-timers
snap.certbot.renew.service가 실행될 서비스 중 하나로 표시됩니다.
NEXT LEFT LAST PASSED UNIT ACTIVATES
Tue 2023-10-17 00:00:00 UTC 14h left Mon 2023-10-16 00:00:18 UTC 9h ago dpkg-db-backup.timer dpkg-db-backup.service
Mon 2023-10-16 19:12:00 UTC 9h left Mon 2023-10-16 07:27:11 UTC 2h 17min ago snap.certbot.renew.timer snap.certbot.renew.service
Mon 2023-10-16 20:49:14 UTC 11h left Mon 2023-10-16 07:48:12 UTC 1h 56min ago apt-daily.timer apt-daily.service
SSL 갱신이 잘 작동하는지 확인하기 위해 프로세스의 드라이런을 수행합니다.
$ sudo certbot renew --dry-run
오류가 없으면 모든 준비가 완료된 것입니다. 인증서는 자동으로 갱신됩니다.
7단계 - Nginx 구성
파일 /etc/nginx/conf.d/ghost.conf를 생성하고 편집을 위해 엽니다.
$ sudo nano /etc/nginx/conf.d/ghost.conf
다음 코드를 ghost.conf 파일에 붙여넣습니다. example.com의 모든 인스턴스를 귀하의 도메인으로 바꿉니다.
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
access_log /var/log/nginx/ghost.access.log;
error_log /var/log/nginx/ghost.error.log;
client_max_body_size 20m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] valid=60s;
resolver_timeout 2s;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:2368;
}
}
위의 구성은 모든 HTTP 요청을 HTTPS로 리디렉션하고 Ghost 서비스가 귀하의 도메인을 통해 제공되도록 프록시 역할을 합니다.
프롬프트가 표시되면 Ctrl + X를 눌러 파일을 저장하고 Y를 입력합니다.
파일 /etc/nginx/nginx.conf를 편집을 위해 엽니다.
$ sudo nano /etc/nginx/nginx.conf
include /etc/nginx/conf.d/*.conf; 줄 앞에 다음 줄을 추가합니다.
server_names_hash_bucket_size 64;
프롬프트가 표시되면 Ctrl + X를 눌러 파일을 저장하고 Y를 입력합니다.
Nginx 구성을 확인합니다.
$ sudo nginx -t
오류가 없으면 준비가 완료된 것입니다. Nginx 서버를 재시작하여 구성을 적용합니다.
$ sudo systemctl restart nginx
9단계 - 사이트 실행
이제 웹 브라우저에서 https://example.com을 열어 설치를 확인할 수 있습니다. 성공적인 설치를 나타내는 다음 페이지가 표시됩니다.

10단계 - 설정 완료
Ghost 블로그 설정을 마치려면 브라우저에서 https://example.com/ghost를 방문하십시오. 블로그 도메인의 끝에 추가된 /ghost는 Ghost의 관리 패널로 리디렉션하거나 처음 접근하는 경우 설정으로 리디렉션됩니다.
여기에서 관리 계정을 생성하고 블로그 제목을 선택해야 합니다.

세부정보를 입력하고 계정 생성 및 게시 시작 버튼을 클릭하여 진행합니다.
다음으로, 첫 번째 게시물을 작성하거나 사이트를 사용자 정의하거나 회원을 가져오는 등의 옵션이 제공되는 다음 화면으로 이동합니다.

Ghost 관리자 탐색을 선택하여 탐색하고 대시보드로 직접 이동합니다. 설정이 끝나면 Ghost의 관리 패널이 표시됩니다.

어두운 모드로 전환하려면 설정 페이지 하단의 설정 기어 버튼 옆에 있는 토글 스위치를 클릭하면 됩니다.
기본 게시물이 표시됩니다. 이를 게시 취소하거나 삭제하고 게시를 시작할 수 있습니다.

11단계 - 메일러 구성
Ghost는 블로깅 플랫폼 역할을 할 뿐만 아니라 뉴스레터 관리자 역할도 합니다. 일상적인 작업을 위해 Ghost와 함께 작동하는 모든 거래 메일 서비스를 사용할 수 있습니다. 그러나 Ghost를 통해 뉴스레터를 보내고 싶다면 공식적으로 지원되는 대량 메일러는 Mailgun뿐입니다. 다른 뉴스레터 서비스를 사용할 수도 있지만, 그 경우 Ghost의 Zapier 통합 기능을 사용해야 합니다.
먼저 거래 이메일을 위한 SMTP 서비스를 구성해 보겠습니다. /var/www/html/ghost/config.production.json 파일을 편집하기 위해 엽니다.
$ nano /var/www/html/ghost/config.production.json
다음 줄을 찾습니다.
"mail": {
"transport": "Direct"
},
다음 코드로 바꿉니다.
"mail": {
"from": "'HowtoForge Support' [email protected]",
"transport": "SMTP",
"options": {
"host": "YOUR-SES-SERVER-NAME",
"port": 465,
"service": "SES",
"auth": {
"user": "YOUR-SES-SMTP-ACCESS-KEY-ID",
"pass": "YOUR-SES-SMTP-SECRET-ACCESS-KEY"
}
}
},
여기서는 저렴하고 월 요금이 필요 없는 Amazon SES 메일 서비스를 사용하고 있습니다.
프롬프트가 표시되면 Ctrl + X를 눌러 파일을 저장하고 Y를 입력합니다. 완료되면 변경 사항을 적용하기 위해 Ghost 애플리케이션을 재시작합니다.
$ ghost restart
뉴스레터 설정을 구성하려면 설정 >> 이메일 뉴스레터 섹션으로 이동합니다.

Mailgun 구성 링크를 클릭하여 확장합니다.
Mailgun 지역, 도메인 및 API 키를 입력합니다.

상단 오른쪽의 저장 버튼을 클릭하여 설정을 저장합니다.
뉴스레터 배달을 테스트하려면 새 테스트 게시물을 만들고 게시를 클릭한 다음 이메일 전용 옵션을 선택합니다. 게시물도 게시하려면 게시 및 이메일 옵션을 선택합니다.

계속, 최종 검토 버튼을 클릭하여 진행합니다. 다음 페이지에서 최종 확인을 다시 요청합니다.

지금 이메일 전송 버튼을 클릭하여 뉴스레터를 전송합니다. 메일이 전송되면 다음 메시지가 표시됩니다.

게시물에 대한 이메일을 확인합니다.

12단계 - Ghost 업데이트
Ghost 업데이트에는 두 가지 유형이 있습니다 - 마이너 업데이트와 메이저 업데이트.
먼저 마이너 업데이트를 실행하려면 전체 백업을 수행하십시오. 모든 게시물, 회원, 테마, 이미지, 파일 및 리디렉션 파일의 백업을 생성합니다.
$ cd /var/www/html/ghost
$ ghost backup
업데이트 명령을 실행하여 마이너 업데이트를 수행합니다.
$ ghost update
메이저 업데이트를 수행하려면 Ghost의 공식 세부 업데이트 가이드를 따라야 합니다. 현재 버전과 업데이트하려는 메이저 버전에 따라 단계가 달라집니다.
결론
이로써 Nginx를 사용하여 Debian 12 서버에 Ghost CMS를 설정하는 방법에 대한 튜토리얼이 종료됩니다. 질문이나 피드백이 있으면 아래 댓글로 공유해 주세요.
새 게시물을 받은 편지함에서 받기
스팸은 없습니다. 언제든지 구독 해지 가능합니다.