Ghost로 개발 블로그 만들고 셀프 호스팅 (2) 설치 과정에서의 트러블슈팅 및 명령어 학습
지난 포스팅에서는 디지털오션에서 가상서버(드롭렛)를 생성하고, 블로그를 호스팅할 도메인을 설정하는 부분을 다뤘다.
이번 포스팅은 우분투 환경에 Ghost및 관련 프로그램들을 설치하는 과정과 각 과정에서 맞닥뜨린 문제들에 대해 다루고 있다. 참고로 나의 경우 드롭렛의 우분투 버전은 Ubuntu 22.04 (LTS) x64 였고, 설치 과정은 공식 사이트의 가이드를 참조했다. 우분투를 처음 사용해보는 것이었기 때문에, 매 스텝마다 사용되는 명령어를 조금씩 학습하면서 설치를 진행해 보았다.
우분투 환경에 로그인해 사용자 설정 및 권한 부여하기
- SSH로 로그인하기 : <your_server_ip>에는 디지털오션에서 받은 드롭렛의 ip를 입력하면 된다.
ssh root@<your_server_ip>
- 사용자 추가 : <user>에는 ghost라는 이름은 사용하면 안 된다는 것에 주의하자. 다음 명령어를 실행하고 이어서 비밀번호와 (필요시) 이름 등을 설정한다
adduser <user>
- 슈퍼 사용자 권한 부여 후 로그인
usermod -aG sudo <user>
- usermod는 기존 사용자의 속성(e.g. 권한, 아이디, 그룹 등)을 수정할 수 있는 명령어다.
-a
(append): 사용자를 기존 그룹에 추가할 때 사용한다.-G
(groups): 지정된 그룹에 사용자를 추가한다.usermod -aG <그룹명> <사용자명>
이런 식으로 사용한다.sudo
그룹은 슈퍼유저 권한을 가진 사용자 그룹으로, 이 그룹에 속한 사용자는sudo
명령을 사용해 관리자(root) 권한이 필요한 작업을 수행할 수 있다.
- 추가한 사용자로 로그인
su - <user>
su -
(substitute user) : 유저를 전환할 때 사용하는 명령어
패키지 목록 갱신 및 업그레이드
다음 두 명령어를 순서대로 실행한다.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get update
는 설치 가능한 패키지 목록(리스트)을 업데이트하는 것이지만 실제로 패키지를 설치하거나 업그레이드하지는 않는다. 최신 버전이 있는지 확인할 수 있도록 패키지 저장소에서 정보만 가져오는 단계라고 보면 된다.sudo apt-get upgrade
는 update에서 가져온 목록에 따라, 시스템에 설치된 패키지들을 최신 버전으로 업그레이드하는 명령어다.
패키지 설치
1. Nginx 설치 및 설정
# 설치
sudo apt-get install nginx
Nginx는 '리버스 프록시' 로 사용된다. 리벅스 프록시는 사용자와 서버 사이에서 요청을 대신 전달해 주는 역할을 하는 서버다. 사용자가 블로그에 접속하면 요청이 먼저 리버스 프록시(여기서는 Nginx)로 가고, Nginx가 그 요청을 실제 서버(여기서는 Ghost 서버)로 전달해 주는 방식이다.
Ghost도 자체적으로 서버의 기능을 하지만, 리버스 프록시를 두었을 때의 이점인 보안성 향상과 성능 향상(Ngnix에서 지원하는 고속 캐싱 등) 등의 이유로 이를 설치하는 것으로 보인다.
# 설정
sudo ufw allow 'Nginx Full'
Nginx 웹 서버를 위한 포트(HTTP 80번, HTTPS 443번)를 모두 열어주는 명령어로, Nginx 웹 서버를 설정하고 외부에서 해당 웹 서버에 접근할 수 있도록 한다.
참고로 ufw(Uncomplicated Firewall) 는 리눅스 계열 운영체제에서 사용하는 방화벽 관리 프로그램으로, 특정 포트를 허용하거나 차단하는 기능을 한다.
2. mysql 설치
블로그와 관련된 모든 정보는 MySQL에 저장되므로, 설치를 해 주자.
sudo apt-get install mysql-server
그러나 내 경우 mysql을 설치하고 실행하려 할 때 다음과 같은 오류가 발생해 실행에 실패했다.
메시지를 읽어보니 oom-kill 문제가 발생했다는 것인데, 이는 Out-Of-Memory를 읭미하는 것으로 mysql을 실행하기에 메모리가 부족하다는 것이다.
지금 생각해보니 Prerequisites에 '최소 1GB 메모리를 탑재한 서버' 라고 돼 있었는데 내가 드롭렛을 선택할 때 가장 싼 512MB 메모리로 선택해서 이런 문제가 발생한 것이 아닌가 싶다.
드롭렛 유형을 업그레이드하는 것이 근본적인 해결책이 될 수 있겠지만, 지금 단계에서 추가 비용을 쓰고 싶지 않아 swap 파일 생성을 통해 일시적으로 문제를 해결했다.
메모리 용량에 비해 너무 많은 프로그램이 컴퓨터에서 돌아가면 메모리가 부족해질 수 있는데, RAM이 부족할 때 하드디스크나 SSD의 일부 디스크 공간을 스왑 영역으로 사용하여 메모리를 확장한다고 한다. 스왑 파일은 RAM이 부족할 때 데이터를 저장하는 공간으로, 메모리가 부족할 때 임시로 데이터를 저장할 수 있다.
sudo fallocate -l 1G /swapfile
명령어로 1GB 크기의 스왑 파일을 생성한다sudo chmod 600 /swapfile
파일에 권한을 설정한다. 600은 root 사용자만 이 파일을 읽고 쓸 수 있도록 제한하는 것이다.sudo mkswap /swapfile
생성한 스왑 파일을 스왑 영역으로 설정한다sudo swapon /swapfile
스왑 파일을 활성화한다echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
명령어는 스왑 파일을 시스템 재부팅 시 자동으로 활성화한다
이렇게 설정하고 sudo systemctl restart mysql 을 통해 mysql 서버를 재시작하니 문제가 해결되었다.
- node.js 설치
나의 경우 v18.20.4를 설치했다. 여기서 지원되는 버전과 권장되는 버전을 확인하자.
# Download and import the Nodesource GPG key
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
# Create deb repository
NODE_MAJOR=18 # Use a supported version
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
# Run update and install
sudo apt-get update
sudo apt-get install nodejs -y
- ghost cli 설치
sudo npm install ghost-cli@latest -g
- ghost 설치
ghost는 루트 폴더가 아니라, 하위 디렉토리를 생성해 그 안에 설치해야 한다.
- 디렉토리 생성 : 'sitename' 부분을 원하는 사이트명으로 설정한다.
sudo mkdir -p /var/www/sitename
- 디렉토리의 소유자 및 소유 그룹 변경
sudo chown <user>:<user> /var/www/sitename
- 디렉토리 권한 설정 : 775번은 소유자와 소유 그룹은 모든 권한을 가지도록 설정하고, 다른 사용자들은 읽기와 실행만 가능한 권한이다.
sudo chmod 775 /var/www/sitename
- 생성한 디렉토리로 들어가 ghost를 설치한다
cd /var/www/sitename
ghost install
- Ghost를 설치하는 과정에서 configuration을 위한 following questions에 답한다.
- Blog URL : e.g. https://sohyun.dev
- MySQL hostname : e.g. localhost
- MySQL username / password : mysql 설치하면서 설정했던 대로 입력
- Ghost database name : mySQL root 유저로 사용한다면 자동으로 세팅이 된다. root 이외의 유저로 사용한다면 mySQL에 미리 ghost를 위한 데이터베이스를 생성해두고 유저에게 권한을 부여한 후 해당 데이터베이스명을 입력하면 된다
- ghost MySQL user / NGINX / SSL / systemd를 셋업할지 물어보는데, 모두 yes라고 답했다.
- ghost를 설치, 실행한 후 어드민 페이지에 접속하려면 <url>/ghost로 접속하면 된다.
issue : 포스팅 시 이미지를 첨부했는데 브라우저에서 보여지지 않는 이슈
- 포스팅에 첨부한 이미지 중 일부는 보여지고, 일부는 보여지지 않아 의아했다. 그런데 또 모바일에서는 다 이미지가 잘 보여졌다. 확인해보니, 잘 보여지는 이미지의 경우 https://로 시작하는 링크를 갖고 있었고 잘 보여지지 않는 이미지는 http://로 시작하는 링크를 갖고 있었다.
- 혼합 콘텐츠(Mixed Content) 차단 문제가 발생한 것이다. 이는 https로 제공되는 웹사이트가 http로 제공되는 리소스를 로드하려고 할 때 발생한다고 한다. 보안상의 이유로 https 페이지에 http 콘텐츠를 로드할 경우 브라우저가 이를 차단하는 것이다.
- 이런 문제가 발생한 이유는 Ghost 설치 과정에서 Blog URL 설정 시 http://sohyun.dev 로 설정을 했기 때문이다. 그래서 이후에 Ghost CMS를 통해 이미지를 업로드하면 기본적으로 이미지 링크가 http로 시작하게 됐다.
- 해결 방법 : config.production.json 파일을 열어 url을 https로 시작하도록 수정해준 후 서버를 재시작하니 문제가 해결됐다. 이 파일은 ghost가 설치된 디렉토리 내에 있다.