Ghost CMS · 12 min read · Oct 14, 2025
Rocky Linux 9에 Ghost CMS 배포하는 방법

Ghost는 전문적인 블로그를 만들 수 있도록 도와주는 오픈 소스 블로깅 플랫폼입니다. 2013년에 WordPress의 복잡함을 대체하기 위해 출시되었습니다. JavaScript로 작성되었으며 Node.js 라이브러리로 구동됩니다.
이 튜토리얼에서는 Rocky Linux 9에서 Nginx와 MySQL을 사용하여 Ghost CMS를 설치하는 방법을 살펴보겠습니다. Nginx 서버를 사용하여 블로그를 호스팅하고 Let’s Encrypt SSL 인증서를 사용하여 설치를 안전하게 보호할 것입니다.
필수 조건
- Rocky Linux 9에서 실행되는 서버.
- sudo 권한이 있는 비루트 사용자.
- 서버를 가리키는 완전한 도메인 이름(FQDN). 우리의 목적을 위해
ghost.example.com을 도메인 이름으로 사용할 것입니다. - 모든 것이 업데이트되었는지 확인하십시오.
$ sudo dnf update - 기본 유틸리티 패키지를 설치합니다. 일부는 이미 설치되어 있을 수 있습니다.
$ sudo dnf install wget curl nano unzip yum-utils -y
1단계 - 방화벽 구성
첫 번째 단계는 방화벽을 구성하는 것입니다. Rocky Linux는 Firewalld 방화벽을 사용합니다. 방화벽의 상태를 확인하십시오.
$ sudo firewall-cmd --state
running
방화벽은 서로 다른 영역과 함께 작동하며, 공용 영역이 우리가 사용할 기본 영역입니다. 방화벽에서 활성화된 모든 서비스와 포트를 나열합니다.
$ sudo firewall-cmd --permanent --list-services
다음과 같은 출력이 표시되어야 합니다.
cockpit dhcpv6-client ssh
Wiki.js는 작동하기 위해 HTTP 및 HTTPS 포트가 필요합니다. 이를 열어줍니다.
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service=https --permanent
변경 사항을 적용하기 위해 방화벽을 다시 로드합니다.
$ sudo firewall-cmd --reload
2단계 - Nginx 설치
Rocky Linux 9는 이전 버전의 Nginx를 제공합니다. 최신 버전을 설치하려면 공식 Nginx 리포지토리를 다운로드해야 합니다.
공식 Nginx 리포지토리를 만들기 위해 /etc/yum.repos.d/nginx.repo 파일을 생성하고 엽니다.
$ sudo nano /etc/yum.repos.d/nginx.repo
다음 코드를 붙여넣습니다.
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
파일을 저장하려면 Ctrl + X를 누르고 프롬프트가 나타나면 Y를 입력합니다.
Nginx 서버를 설치합니다.
$ sudo dnf install nginx -y
설치를 확인합니다.
$ nginx -v
nginx version: nginx/1.22.1
Nginx 서버를 활성화하고 시작합니다.
$ sudo systemctl enable nginx --now
서버의 상태를 확인합니다.
$ sudo systemctl status nginx
? nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2022-10-25 08:27:47 UTC; 2s ago
Docs: http://nginx.org/en/docs/
Process: 1650 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
Main PID: 1651 (nginx)
Tasks: 2 (limit: 5912)
Memory: 1.9M
CPU: 7ms
CGroup: /system.slice/nginx.service
??1651 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
??1652 "nginx: worker process"
Oct 25 08:27:47 ghost.example.com systemd[1]: Starting nginx - high performance web server...
3단계 - Node.js 설치
Ghost 설치 프로그램은 작동하기 위해 Nodejs가 필요합니다. 다음 명령을 실행하여 Node 16을 설치합니다.
$ curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -
Node를 설치합니다.
$ sudo dnf install -y nodejs
Node 설치를 확인합니다.
$ node --version
v16.18.0
이 튜토리얼을 작성할 당시 Node 18이 출시되었으며 LTS 버전입니다. Ghost는 아직 이를 지원하지 않습니다. 최신 Node 버전에 대한 Ghost 문서를 확인하십시오. Ghost가 Node 18을 지원하게 되면 다음 명령을 사용하여 Node 18을 설치하십시오.
$ curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
$ sudo dnf install -y nodejs
4단계 - MySQL 설치
Rocky Linux 9는 최신 버전의 MySQL을 제공합니다. 단일 명령으로 설치할 수 있습니다.
$ sudo dnf install mysql-server
MySQL 버전을 확인합니다.
$ mysql --version
mysql Ver 8.0.30 for Linux on x86_64 (Source distribution)
MySQL 서비스를 활성화하고 시작합니다.
$ sudo systemctl enable mysqld --now
서비스 상태를 확인합니다.
$ sudo systemctl status mysqld
? mysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2022-10-25 09:00:26 UTC; 3s ago
Process: 2920 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Process: 2942 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)
Main PID: 3021 (mysqld)
Status: "Server is operational"
Tasks: 39 (limit: 5912)
Memory: 404.4M
CPU: 4.686s
CGroup: /system.slice/mysqld.service
??3021 /usr/libexec/mysqld --basedir=/usr
Oct 25 09:00:18 ghost.example.com systemd[1]: Starting MySQL 8.0 database server...
Oct 25 09:00:18 ghost.example.com mysql-prepare-db-dir[2942]: Initializing MySQL database
Oct 25 09:00:26 ghost.example.com systemd[1]: Started MySQL 8.0 database server.
기본적으로 Unix 인증을 사용하여 MySQL 셸에 로그인할 수 있습니다. 그러나 보안 설정 마법사를 실행할 수 없습니다. 따라서 MySQL 버전 8.0.28 이상에 대해 다음 단계가 필요합니다. MySQL 셸에 들어갑니다.
$ sudo mysql
다음 명령을 실행하여 루트 사용자의 비밀번호를 설정합니다. 숫자, 대문자, 소문자 및 특수 문자가 혼합되어 있는지 확인하십시오.
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourPassword12!';
셸을 종료합니다. 이 단계의 단점은 더 이상 Unix 인증을 사용하여 MySQL 셸에 로그인할 수 없다는 것입니다.
mysql> exit
MySQL 보안 설치 스크립트를 실행합니다.
$ sudo mysql_secure_installation
비밀번호의 강도를 확인하는 Validate Password Component를 설치하라는 메시지가 표시됩니다. 설치하려면 Y를 누르십시오.
Securing the MySQL server deployment.
Connecting to MySQL using a blank password.
VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?
Press y|Y for Yes, any other key for No: Y
다음으로 비밀번호 검증 정책의 수준을 설정하라는 메시지가 표시됩니다. 가장 강력한 2를 선택하십시오. 그런 다음 루트 비밀번호를 생성하라는 메시지가 표시됩니다. 주어진 요구 사항에 맞는 비밀번호를 입력하십시오. 비밀번호로 계속 진행할 것인지 묻는 질문에 Y를 눌러 진행하십시오.
There are three levels of password validation policy:
LOW Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2
Please set the password for root here.
New password:
Re-enter new password:
Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y
마지막으로 익명 사용자를 제거하고 원격 루트 로그인을 금지하며 테스트 데이터베이스를 제거하고 권한 테이블을 다시 로드할 것인지 묻는 질문에 Y를 눌러 진행하십시오.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y
Success.
Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y
Success.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y
- Dropping test database...
Success.
- Removing privileges on test database...
Success.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.
All done!
이로써 MySQL 설치 및 보안 프로세스가 완료되었습니다.
5단계 - Ghost 설치
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 도구는 블로그를 구성하기 위해 여러 질문을 할 것입니다.
- 이 튜토리얼을 작성할 당시 Ghost-CLI는 Ubuntu 외의 다른 OS를 지원하지 않습니다. 설치를 계속 진행할 것인지 묻는 질문이 있을 것입니다. Y를 눌러 계속 진행하십시오.
- 블로그 URL: https 프로토콜과 함께 전체 블로그 URL을 입력하십시오. (
https://ghost.example.com) - MySQL 호스트 이름: Ghost 설치와 MySQL이 동일한 서버에 있으므로 기본값인
localhost를 사용하려면 Enter를 누르십시오. - MySQL 사용자 이름: MySQL 사용자 이름으로
root를 입력하십시오. - MySQL 비밀번호: 이전에 생성한 루트 비밀번호를 입력하십시오.
- Ghost 데이터베이스 이름: Ghost 데이터베이스의 이름을 지정하십시오. (
ghostdb) - Sudo 비밀번호: 상승된 명령을 수행하기 위해 시스템의 sudo 비밀번호를 입력하십시오.
- Ghost MySQL 사용자 설정?: 설치 프로그램은 Ghost를 위한 별도의 MySQL 사용자를 생성할 것인지 묻습니다. Y를 눌러 진행하십시오.
- Nginx 설정?: 일반적으로 Ghost-CLI는 Nginx 설치를 감지하고 블로그를 위해 자동으로 구성합니다. 그러나 현재 Nginx 설치를 감지할 수 없습니다. 따라서 설치 프로그램은 이 단계를 자동으로 건너뜁니다. 우리는 Nginx를 수동으로 구성할 것입니다.
- SSL 설정?: Nginx 구성을 건너뛰었기 때문에 CLI 도구는 SSL 설정도 건너뜁니다.
- systemd 설정?: Ghost는 Ghost를 위한 시스템 서비스를 설정할 것인지 묻습니다. Y를 눌러 진행하십시오.
- Ghost 시작?: Y를 눌러 Ghost 설치를 시작하십시오. 서비스가 시작되지만 작동하려면 Nginx와 SSL을 구성해야 합니다.
6단계 - SSL 설치
진행하기 전에 도메인에 대한 Certbot 도구와 SSL 인증서를 설치해야 합니다.
Certbot을 설치하기 위해 Snapd 패키지 설치 프로그램을 사용할 것입니다. Snapd는 항상 최신 안정 버전의 Certbot을 포함하므로 사용해야 합니다.
Snapd 도구는 작동하기 위해 Epel 리포지토리가 필요합니다.
$ sudo dnf install epel-release -y
Snapd를 사용하여 Certbot을 설치합니다. Snapd를 설치합니다.
$ sudo dnf install snapd -y
Snap 서비스를 활성화하고 시작합니다.
$ sudo systemctl enable snapd.socket --now
Snapd가 작동하도록 필요한 링크를 생성합니다.
$ sudo ln -s /var/lib/snapd/snap /snap
$ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh
snapd 버전이 최신인지 확인합니다.
$ sudo snap install core
$ sudo snap refresh core
Certbot을 설치합니다.
$ sudo snap install --classic certbot
다음 명령을 사용하여 Certbot 명령이 /usr/bin 디렉토리에서 실행될 수 있도록 심볼릭 링크를 생성합니다.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
SSL 인증서를 생성합니다.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d ghost.example.com
위 명령은 서버의 /etc/letsencrypt/live/ghost.example.com 디렉토리에 인증서를 다운로드합니다.
Diffie-Hellman 그룹 인증서를 생성합니다.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
SSL 갱신이 잘 작동하는지 확인하기 위해 프로세스의 드라이런을 수행합니다.
$ sudo certbot renew --dry-run
오류가 없으면 모든 준비가 완료된 것입니다. 인증서는 자동으로 갱신됩니다.
7단계 - Nginx 구성
편집을 위해 /etc/nginx/conf.d/ghost.conf 파일을 생성하고 엽니다.
$ sudo nano /etc/nginx/conf.d/ghost.conf
다음 코드를 ghost.conf 파일에 붙여넣습니다. ghost.example.com의 모든 인스턴스를 귀하의 도메인으로 교체하십시오.
## enforce HTTPS
server {
listen 80;
listen [::]:80;
server_name ghost.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ghost.example.com;
access_log /var/log/nginx/ghost.access.log;
error_log /var/log/nginx/ghost.error.log;
client_max_body_size 20m;
http2_push_preload on; # Enable HTTP/2 Server Push
ssl_certificate /etc/letsencrypt/live/ghost.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ghost.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/ghost.example.com/chain.pem;
ssl_session_timeout 1d;
# Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
ssl_protocols TLSv1.2 TLSv1.3;
# Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
# prevent replay attacks.
#
# @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
ssl_early_data on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
add_header X-Early-Data $tls1_3_early_data;
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;
}
}
# This block is useful for debugging TLS v1.3. Please feel free to remove this
# and use the `$ssl_early_data` variable exposed by NGINX directly should you
# wish to do so.
map $ssl_early_data $tls1_3_early_data {
"~." $ssl_early_data;
default "";
}
위 구성은 모든 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 reload nginx
8단계 - SELinux 구성
Nginx가 네트워크에 연결할 수 있도록 허용합니다.
$ sudo setsebool -P httpd_can_network_connect 1
9단계 - 사이트 실행
이제 웹 브라우저에서 https://ghost.example.com을 열어 설치를 확인할 수 있습니다. 성공적인 설치를 나타내는 다음 페이지가 표시됩니다.

10단계 - 설정 완료
Ghost 블로그 설정을 마치려면 브라우저에서 https://ghost.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": "'Acme 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 메일 서비스를 사용하고 있습니다. 이는 매우 저렴하며 EC2 서비스를 사용하는 경우 평생 무료입니다.
Mailgun을 사용하여 뉴스레터 서비스를 사용하려면 다음 코드를 대신 입력하십시오.
"mail": {
"from": "'Acme Support' [email protected]",
"transport": "SMTP",
"options": {
"service": "Mailgun",
"host": "smtp.mailgun.org",
"port": 587,
"secure": true,
"auth": {
"user": "[email protected]",
"pass": "1234567890"
}
}
},
파일을 저장하려면 Ctrl + X를 누르고 프롬프트가 나타나면 Y를 입력합니다.
변경 사항을 적용하기 위해 Ghost 애플리케이션을 재시작합니다.
$ ghost restart
뉴스레터 설정을 구성하려면 설정 >> 이메일 뉴스레터 섹션으로 이동하십시오.

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

오른쪽 상단의 저장 버튼을 클릭하여 설정을 저장합니다.
뉴스레터 배달을 테스트하려면 게시물을 열고 설정을 열어 이메일 뉴스레터 옵션을 클릭하십시오. 다음으로 테스트 이메일을 보내서 작동하는지 확인하십시오. 오류가 없으면 뉴스레터 배달이 작동하는 것입니다.
12단계 - Ghost 업데이트
Ghost 업데이트에는 두 가지 유형이 있습니다 - 마이너 업데이트와 메이저 업데이트.
마이너 업데이트를 실행하려면 먼저 전체 백업을 수행하십시오.
$ cd /var/www/html/ghost
$ ghost backup
업데이트 명령을 실행하여 마이너 업데이트를 수행합니다.
$ ghost update
메이저 업데이트를 수행하려면 Ghost의 공식 상세 업데이트 가이드를 따라야 합니다. 현재 버전과 업데이트하려는 메이저 버전에 따라 단계가 달라집니다.
결론
이로써 Rocky Linux 9 서버에서 Nginx를 사용하여 Ghost CMS를 설정하는 방법에 대한 튜토리얼이 마무리되었습니다. 질문이나 피드백이 있으시면 아래 댓글로 남겨주세요.
새 게시물을 받은 편지함에서 받기
스팸은 없습니다. 언제든지 구독 해지 가능합니다.