Click to change color scheme

Notes on codes, projects and everything

Deploying docker containers with HAProxy on a VPS

With most of my stuff more or less set, I guess it is time to start documenting the steps before I forget. So I heard a lot of good things about docker for quite some time, but haven’t really have the time to do it due to laziness (plus my relatively n00b-ness in the field of dev-ops). Just a few months ago, I decided to finally migrate away from webfaction (thanks for all the superb support) to a VPS so I can run more things on it.

The initial plan was to do it at the beginning of the year actually…

Anyway, as I am not really a sysadmin, so I really wanted the whole set up to be simple and stupid enough. The server is currently hosting my sites, as well as mybloggercon‘s. Therefore, the easier the setup is, the easier it is to maintain. I also wanted to prepare mybloggercon’s stuff to be easily detachable, so that it can be migrated easily when the traffic gets out of control.

So there are three components in the setup, namely the firewall, docker(-compose), and ufw. Thanks to the helpful guides @ digitalocean I managed to get the sites running in few hours (could be much shorter if I am not so n00bie). There’s nothing much to talk about in firewall settings, especially all I did was to follow the instructions detailed in the documents.

Docker

I actually started with just plain docker at first, as I wanted to get the site up and running fast. So if you flip through my command history you see a lot of manual docker run commands. It worked fine, until I needed to play with the settings and fix the wrongly defined ports, volume mapping etc. So eventually I started to put everything into a docker-compose file.

blog:
build: "/my/path/to/Dockerfile"
ports:
- "127.0.0.1:$WORDPRESS_PORT:80"
volumes:
- "/my/path/to/the/script:/var/www/html"
environment:
WORDPRESS_DB_HOST: "172.17.0.1:$MYSQL_PORT"
WORDPRESS_DB_PASSWORD: "some super secret password"
WORDPRESS_DB_NAME: "some_db_name"

mysql:
build: "/my/path/to/Dockerfile"
ports:
- "172.17.0.1:$MYSQL_PORT:3306"
volumes:
- "/my/path/to/the/data:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: "some super secret password"

The wordpress sites are currently running off “official” images, but it wasn’t really a “complete” image. I had to install some extensions manually in order to get the site running properly. So I defined a new image based on the official one with the following dockerfile.

FROM wordpress:latest
RUN docker-php-ext-install mbstring

Eventually I wanted the whole thing to be more automated, so I added restart policy into the docker compose, as follows.

blog:
build: "/my/path/to/Dockerfile"
ports:
- "127.0.0.1:$WORDPRESS_PORT:80"
volumes:
- "/my/path/to/the/script:/var/www/html"
environment:
WORDPRESS_DB_HOST: "172.17.0.1:$MYSQL_PORT"
WORDPRESS_DB_PASSWORD: "some super secret password"
WORDPRESS_DB_NAME: "some_db_name"
restart: always

mysql:
build: "/my/path/to/Dockerfile"
ports:
- "172.17.0.1:$MYSQL_PORT:3306"
volumes:
- "/my/path/to/the/data:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: "some super secret password"
restart: always

So if everything works properly, my containers should be restarted automatically after rebooting.

HAProxy

In order to deliver the container services, I was presented with a couple of options. However, I went with HAProxy because I don’t feel like setting up a webserver, regardless how light it is (eg. nginx). HAProxy also looked a lot easier to set up, just define a few sets of rules, then it should divert the requests to the right docker container. The following is a sample of my configuration (which is based on this guide).

frontend http-in
bind *:80
acl is_coolsilon_www hdr(host) -i www.coolsilon.com
use_backend docker_csl_static if is_coolsilon_www

backend docker_csl_static
balance roundrobin
option httpclose
option forwardfor
server s3 127.0.0.1:$MY_STATIC_PORT maxconn 32

Bonus: Mailserver

In short, I simply skipped setting up a mail server, and went with mailgun instead. There’s no good reason in this decision, except I don’t feel like going through the pain of setting one from scratch myself.

So pretty much that’s all. Next is to get SSL installed properly after letsencrypt is out in the wild.

leave your comment

name is required

email is required

have a blog?

This blog uses scripts to assist and automate comment moderation, and the author of this blog post does not hold responsibility in the content of posted comments. Please note that activities such as flaming, ungrounded accusations as well as spamming will not be entertained.