Another chapter in the ever growing book that is the story of my blog, as is good and right for any developer.
This is now coming at you from docker-compose. The blog, I mean. It used to be on a normal digital ocean droplet running on bare metal (well, low tier instance so probably a vmware instance but you know what I mean). Even worse, to my great shame it was just a normal wordpress instance. Now, it’s still running on that same vmware instance and it’s still wordpress, but it’s using roots/bedrock.
roots/bedrock lets you manage wordpress as a composer dependency, including themes and plugins. Essentially that means the whole blog is now a git repo with a single composer.json and composer.lock file. Of course there’s a bit more to it with .env files and persistent stuff, but essentially that’s it. This is very cool on its own, but just moving one wordpress site to using composer isn’t cool enough, so I did the same for the archive. The archive was using some plugins that don’t even exist anymore, but I manged to find and patch their successors well enough to keep it afloat, so now that’s also managed with composer. That means I can easily upgrade and patch both blogs on my machine, test them here, and if everything work quickly run the same upgrade in a predictable manner in production. Cool.
But this server doesn’t just host wordpress, it’s also running my nrk_subs app, my cv app, and new as of today, my lolz aggregator. What I really want is to run everything in nice little docker containers so I can duplicate everything locally and develop it further there in the same way I would do at work, so that’s what I did. I first built the containers I needed for the blogs and then started incorporating the other projects which were already mostly containerized. So currently, this is the docker-compose.yml that manages everything here.
version: "3.8" services: database: build: context: "./database/docker" volumes: - "./storage/blog_and_archive.sql.gz:/docker-entrypoint-initdb.d/initdb.sql.gz" - "./database/data:/var/lib/mysql" container_name: "database" healthcheck: test: ["CMD", "mysqladmin", "ping", "--silent"] command: "--default-authentication-plugin=mysql_native_password" env_file: .env environment: MYSQL_DATABASE: $MYSQL_BLOG_DATABASE MYSQL_RANDOM_ROOT_PASSWORD: 1 blog: image: brbcoffee/blog-base env_file: .env depends_on: - database environment: DB_HOST: database:3306 DB_USER: $MYSQL_USER DB_PASSWORD: $MYSQL_PASSWORD DB_NAME: $MYSQL_BLOG_DATABASE WP_HOME: $WP_HOME_BLOG WP_SITEURL: $WP_SITEURL_BLOG XDEBUG_CONFIG: remote_host=172.17.0.1 volumes: - "./blog/:/var/www/blog" - "./storage/media/blog:/var/www/blog/web/app/uploads" archive: image: brbcoffee/blog-base env_file: .env depends_on: - database environment: DB_HOST: database:3306 DB_USER: $MYSQL_USER DB_PASSWORD: $MYSQL_PASSWORD DB_NAME: $MYSQL_ARCHIVE_DATABASE WP_HOME: $WP_HOME_ARCHIVE WP_SITEURL: $WP_SITEURL_ARCHIVE XDEBUG_CONFIG: remote_host=172.17.0.1 volumes: - "./archive/:/var/www/archive" - "./storage/media/archive:/var/www/archive/web/app/uploads" proxy: image: brbcoffee/proxy env_file: .env ports: - "80:80" - "443:443" depends_on: - blog - archive - cv - subs volumes_from: - blog - archive - lolz mailhog: image: mailhog/mailhog # ports: # - "1025:1025" # - "8025:8025" cv: image: brbcoffee/cv volumes: - "./storage/resume/CV.xml:/app/data/CV.xml" subs: image: "brbcoffee/subs" lolz: image: php:7.3-fpm environment: - APP_ENV=prod volumes: - "./lolz:/var/www/lolz" lolz-cron: image: brbcoffee/lolz-cron environment: - APP_ENV=prod volumes: - "./lolz:/app
As you can see a lot is managed in the .env file, and a lot of code is mounted in. The code mounting’s not necessary for everything, and I’ll be tweaking it going forward, but for now I mostly wanted to get it live so I had an MVP to work from. There are also a lot of brbcoffee/* images here, those are built in a Makefile specific to the project. I factored it out of the docker-compose.yml file in order to separate concerns a bit once the docker-compose.yml file started getting too hairy. The goal is to get rid of the droplet entirely and run the whole setup in kubernetes or something like that.
One hiccup was ssl. The rest has actually been working for weeks, but I couldn’t figure out a clean way to do ssl. In the end I decided I’m ok with not having the certificates automatically renew in version one and just fetched a wildcard with certbot and built it into the proxy container for now.
So there it is, all the stuff on brbcoffee now runs in docker containers under docker-compose. The blogs and the proxy are in the main repo, while the other services have their own repositories which are installed as git submodules. I can toggle a single .env variable and add a build arg and have node serve in dev mode, have the blog containers run xdebug, and have the python containers run a debugpy listener for fullstack local dev. Pretty cool stuff.