Getting it all running

Photo credit: Unsplash: szolkin

I’ve covered the last major component so now it is time to build and get it all running.

Building the Images

A good place to start is to get all the images built and ready. I could build the images and push them into a Docker repository, but for my own purposes building them right on the server works fine.

# pull postgres container
docker pull postgres
# create data container
docker run --name pgdata postgres echo "data only"
# interact database console to create ghost database
docker run -it --rm --link pg:pg postgres psql -h pg -U postgres
# Restore backup
cat backup.sql.dump | docker run -i --rm --link pg:pg postgres psql -h pg -U postgres ghost

# Build ghost container
docker build -t ghost .

# Setup ssl
mkdir web/ssl
# Generate self signed cert with key, named self-ssl.crt self-ssl.key
# Build web container
docker build -t web web

# Build backup container
docker build -t backup backup

Adding the systemd units

Next I enable the systemd service files, the contents of which are in each post.

# Link and start postgres service
sudo systemctl enable pg.service
sudo systemctl start pg.service
# link and start ghost service
sudo systemctl enable ghost.service
sudo systemctl start ghost.service
# link and start web service
sudo systemctl enable web.service
sudo systemctl start web.service
# link and schedule backup service
sudo systemctl enable backup.service
sudo systemctl enable backup.timer
sudo systemctl start backup.timer


When it is time to upgrade various components, this is the process I follow.

If the update is to my static nginx web container, I update the files in git and pull the commits to the server. Then I rebuild the web container and run sudo systemctl restart web.service to load the new image as the running container. Because my systemd service file for the web service includes ExecStartPre=-/usr/bin/docker rm web, the old container will be removed before a new on is started, so the new container will be sure to pick up the latest tagged version from the rebuild.

If the update is to Ghost, I rebuild the image with the command docker build --no-cache -t ghost ., using --no-cache so that it doesn’t use the cached file system layer and pulls the newest version from After that is built, I can restart the ghost container with sudo systemctl restart ghost.service. The web process will also restart as it will crash when the ghost process ends because the containers are linked.

I haven’t yet upgraded Postgres, but I should just be able to pull the latest version and restart the process, assuming it isn’t a change that requires migration of the cluster. Updating the cluster files for a minor version upgrade instead of just a patch level upgrade should work similarly to how I’d upgrade a normal install, just being sure to run the commands inside a docker container with the pgdata container volume linked. I’ll definitely be sure to tar up that volume with the docker export functionality before trying such an upgrade.


I’m really enjoying this setup. CoreOS is keeping itself up-to-date. My components are easy to manage. I’m happy with the database backups and overall approach to everything. Ghost has been great to work with, and the convenience of accessing the Ghost interface anywhere is awesome. Writing in Markdown with the live preview is also great. I like the theme which is based on Bentley.

I have one more bonus post in this series examining the tech behind my website relaunch coming soon!