Set up Ghost with Podman on a VPS
I recently moved this website / blog from Jekyll to Ghost, just to try it out after hearing quite a lot of nice buzz about it lately.
I had this small personal VPS at hand, so I decided to give it some space there, and use Podman (and its quadlets feature) to set it up. This leverages Systemd to run your docker images. Here is a quick walkthrough, should anyone be interested:
Obviously, you need a VPS with SSH access. It must have its firewall open to the web on port 443. My VPS is running Ubuntu, so my install commands will reflect this. I also chose to use root mode to run the quadlets, but there are other options available.
Setup
First, install Podman:
sudo apt install podman podman-docker podman-toolbox
Pull the required images from docker:
sudo podman pull docker.io/mysql:8
sudo podman pull docker.io/ghost:5-alpine
sudo podman pull docker.io/caddy:alpine
The Systemd services
Create a MySQL container file at /etc/containers/systemd/mysql.container
with this content:
[Unit]
Description=Blog MySQL Container
After=network-online.target
[Container]
ContainerName=blog-mysql
AddCapability=SYS_NICE
Image=docker.io/mysql:8
Volume=/srv/containers/blog/mysql/var/lib/mysql:/var/lib/mysql:Z
Pod=blog.pod
Secret=blog_db_name,type=env,target=MYSQL_DATABASE
Secret=blog_db_user,type=env,target=MYSQL_USER
Secret=blog_db_password,type=env,target=MYSQL_PASSWORD
Secret=blog_db_rootpassword,type=env,target=MYSQL_ROOT_PASSWORD
[Service]
Restart=always
[Install]
WantedBy=default.target
RequiredBy=blog-ghost.service
Create a Ghost container file at /etc/containers/systemd/ghost.container
Do not forget to change yourdomain.com
with your domain.
[Unit]
Description=Ghost Container
After=blog-db.service
[Container]
ContainerName=blog-ghost
Environment=database__client=mysql database__connection__host=blog-mysql url=http://yourdomain.com
Image=docker.io/ghost:5-alpine
Pod=blog.pod
Secret=blog_db_name,type=env,target=database__connection__database
Secret=blog_db_user,type=env,target=database__connection__user
Secret=blog_db_password,type=env,target=database__connection__password
Volume=/srv/containers/blog/var/lib/ghost/content:/var/lib/ghost/content:Z
[Service]
Restart=always
[Install]
WantedBy=default.target
You need to set up the secrets used in these two files to access MySQL. Let’s do it:
printf $(tr -dc A-Za-z0-9 </dev/urandom | head -c 13) | sudo podman secret create blog_db_rootpassword -
printf $(tr -dc A-Za-z0-9 </dev/urandom | head -c 13) | sudo podman secret create blog_db_password -
printf "gdb" | sudo podman secret create blog_db_name -
printf "guser" | sudo podman secret create blog_db_user -
You also need to have the files stored on your filesystem, so let’s create the directories that are mounted in the images:
sudo mkdir -p /srv/containers/blog/var/lib/ghost/content
sudo mkdir -p /srv/containers/blog/mysql/var/lib/mysql
Now, add a blog.network
file at /etc/containers/systemd/blog.network
[Unit]
Description=Custom blog Podman network
[Network]
NetworkName=blog
Driver=bridge
And a blog.pod
file at /etc/containers/systemd/blog.pod
[Unit]
Description=Blog Pod
[Pod]
PodName=blog
Network=blog.network
PublishPort=3001:2368
Caddy set up
Let’s use Caddy to serve the app to the internet. I chose to leave Caddy out of the blog pod context because I use it to proxy other toy servers on that VPS.
Create the service file at /etc/containers/systemd/caddy.container
[Container]
ContainerName=caddy
Image=docker.io/caddy:alpine
PublishPort=80:80
PublishPort=443:443
Volume=/srv/containers/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
Volume=/srv/containers/caddy/data:/data
Volume=/srv/containers/caddy/config:/config
Network=host
[Service]
Restart=always
[Install]
WantedBy=default.target
And create the Caddy directory:
sudo mkdir -p /srv/containers/caddy
Add a Caddyfile
at /srv/containers/caddy/Caddyfile
with the following content:
{
# email to use on Let's Encrypt
email [email protected]
}
www.yourdomain.com {
redir https://yourdomain.com{uri}
}
yourdomain.com {
reverse_proxy 127.0.0.1:3001
}
Do not forget to update the file with your email and domain.
Go live
Now let’s open the gates...
sudo systemctl daemon-reload
sudo systemctl enable caddy
sudo systemctl start caddy
sudo systemctl enable blog-pod
sudo systemctl start blog-pod
And visit yourdomain.com/ghost
to start blogging!
Sources

