Setting Up a Self-Hosted Ghost Blog Instead of Naver Blog
Setting Up a Self-Hosted Ghost Blog Instead of Naver Blog
I had been using Naver Blog for a long time. While it was convenient, there were often delays when it came to inserting ads and receiving revenue. So, as both a learning experience and a solution, I decided to build a Ghost blog on my home server.
Since I had already set up a cloud storage system on my main home server, I considered installing Ghost on the same physical machine. However, adding both GitLab and Ghost posed too much risk, so I opted to use a separate physical server. That “separate server” is just a second-hand computer I bought for 50,000 KRW (~$35), upgraded with a few parts, and connected to the network.
Previously, I had used CentOS, but this time I went with Ubuntu for the entire setup.
Specs:
- CPU: Intel(R) Core(TM) i5-3470 @ 3.20GHz
- RAM: DDR3 8GB × 2
- Motherboard: HARRISON2
- Disk: SSD 250GB, HDD 500GB (planned to add)
During the initial OS installation, I got stuck for a while because the BIOS boot setting was on "dual." After fixing that, I successfully installed Ubuntu.
Setup steps:
- Purchased domain and linked A records for subdomains
- Installed GitLab
- Disabled some built-in services like Nginx
- Initially, I intended to use the built-in Nginx, but it didn’t allow me to insert custom server blocks. Since Ghost requires those, I disabled the default Nginx setup.
- Installed Ghost
Database issues:
I first tried using MariaDB, and everything seemed fine until I accessed the post analytics page — which triggered queries unsupported by MariaDB and caused 400 errors. Ghost officially supports MySQL 8, Ubuntu 20+, and Node.js 20+
(https://ghost.org/docs/faq/node-versions/)
Switching to MySQL community edition solved the issue.
I had existing data, so I backed it up and moved it.
During the MySQL install, I encountered a “FROZEN” error, which I resolved with:
sudo rm
/etc/mysql/FROZEN
Then another error appeared:
mysqld: Error on realpath() on '/var/lib/mysql-files' (Error 2 - No such file or directory)
To fix it:
sudo mkdir
-p /var/lib/mysql-filessudo chown
mysql:mysql /var/lib/mysql-filessudo chmod
750 /var/lib/mysql-files
SSL setup:
Used Let's Encrypt Certbot:
apt install certbot python3-certbot-nginx -y
certbot --nginx -d gitlab.example.com -d pages.example.com -d blog.example.com
sudo certbot renew --dry-run
I’ve had issues with auto-renewal in the past, so I plan to monitor this and add a cron job if it fails to run on schedule.
Update Ghost config:
Edit config.production.json
to set the url
to https
.
Change Ghost content directory:
I mounted a 500GB HDD and updated the Ghost config to point to the new content path.
More details: https://blog.secondpage-zone.com/ubuntu-maunteu-seoljeong/
Make sure Ghost has permission to access the directory.
ghost stop
vi /var/www/ghost/config.production.json # Update contentPath: "/mnt/your-mounted-directory"
ghost start
Next steps:
Now comes the blog customization. Aside from the theme, small tweaks can be done via code injection, offering a lot of flexibility.
Overall, I’m very satisfied with the setup.