The Little Website That Could
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.
Background
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 Github 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 run 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_USER=postmaster@mg.example.com
- EMAIL_PASSWORD=1234567890
- LETSENCRYPT_HOST=example.com
- LETSENCRYPT_EMAIL=user@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_EMAIL=user@example.com
# 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
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 docker-compose pull
.
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!