There could not have been a better way to start 2017 than by fixing this website. What started as a small task of self-hosting actually spiraled into many smaller projects. The additional time demands, along with a full-time job, culminated to breaking ivanarellano.com for nearly a year. And yet I've been able to script a way, a convenient one, to spin-up this website and a photography site. Enter Docker Compose.
First, I have to explain how Docker can be a downside. I quickly started writing scripts after going through an enormous amount of setup steps for each container. All setup scripts can then be fired in a correct sequence from another script to re-create this website, like a reset.
For added convenience, I saved each script onto private gists, so that I could download and execute them in a terminal, with something like
wget -qO - https://gist.github.com/ivanarellano/[gist_hash]/raw/start_website.sh | sudo bash.
Initializing containers this way isn't so bad at first, but there are too many pieces to maintain. There are also unforeseen issues. Containers can fail to restart after a server restart. The scripts needed constant documentation for every new solution. The tech debt was real and I started regretting containers.
How it went uphill, with Docker Compose
Docker Compose is able to run multiple containers with only one file to describe dependencies. After installing it, you should be able to use
docker-compose from your terminal. All of your container dependencies are then listed in a file named
docker-compose.yaml. Here is a sample based on this website:
# Describes a Ghost blog with a host name, build variant, Mailgun info, and Let's Encrypt info my_blog: image: ghost volumes: - /my_path/blog:/var/lib/ghost environment: - VIRTUAL_HOST=example.com - NODE_ENV=production - EMAIL_SERVICE=Mailgun - EMAIL_USERfirstname.lastname@example.org - EMAIL_PASSWORD=1234567890 - LETSENCRYPT_HOST=example.com - LETSENCRYPT_EMAILemail@example.com restart: always # Describes a Koken photo gallery with a host name and Let's Encrypt info my_photo_gallery: image: koken/koken-lemp volumes: - /data/koken/www:/usr/share/nginx/www - /data/koken/mysql:/var/lib/mysql environment: - VIRTUAL_HOST=sub.example.com - LETSENCRYPT_HOST=sub.example.com - LETSENCRYPT_EMAILfirstname.lastname@example.org # Describes an Nginx web server that proxies to other container's nginx server nginx-proxy: image: jwilder/nginx-proxy ports: - "##:##" - "##:##" volumes: - /my_path/certs:/etc/nginx/certs:ro - /etc/nginx/vhost.d - /usr/share/nginx/html - /var/run/docker.sock:/tmp/docker.sock:ro - /my_path/vhost.d:/etc/nginx/vhost.d restart: always # Describes a container that automatically creates Let's Encrypt certifications for each other container # If you use this, consider donating: https://letsencrypt.org/donate/ letsencrypt: image: jrcs/letsencrypt-nginx-proxy-companion volumes: - /my_path/certs:/etc/nginx/certs:rw - /var/run/docker.sock:/var/run/docker.sock:ro volumes_from: - nginx-proxy restart: always
It's straightforward to run this script with
docker-compose up. You can optionally add
-d to run detached containers in the background. Containers can be stopped with
docker-compose stop and upgraded with
The website's future
This website is going to be my grounds for ideas, thoughts, and stories. Though, less of the stories at the start. It's going to be about discovering new hobbies, game programming, some math, and it's going to be messy while I try to explain it all. Here's to 2017!