Learning more about Docker

I’ve been mostly heads-down on parenting for a few years now. A- wasn’t keen on babysitters, so my computing time consisted of a couple of hours during the graveyard shift, after our little night-owl finally settled into bed. I felt like I was treading water: keep Emacs News going, check in and do some consulting once in a while so that the relationship doesn’t go cold, do my weekly reviews, try to automate things here and there.

I definitely felt the gaps between the quick-and-dirty coding I did and the best practices I saw elsewhere. I felt a little anxious about not having development environments and production deployment processes for my personal projects. Whenever I messed up my blog or my web-based tracker, I stayed up extra late to fix things, coding while tired and sleepy and occasionally interrupted by A- needing extra snuggling. I updated whenever I felt it was necessary for security, but the risk discouraged me from trying to make things better.

Lately, though, I feel like I’ve been able to actually have some more focused time to learn new things. A- is a little more used to a bedtime routine, and I no longer have to reserve as much energy and patience for dealing with tantrums. She still sleeps really late, but it’s manageable. And besides, I’d tracked the time I spent playing a game on my phone, so I knew I had a little discretionary time I could use more effectively.

Docker is one of the tools on my to-learn list. I think it will help a lot to have environments that I can experiment with and recreate whenever I want. I tried Vagrant before, but Docker feels a lot lighter-weight.

I started by moving my sketch viewer into a Docker container. It’s a basic Node server with read-only access to my sketches, so that was mostly a matter of changing it to be configured via environment variables and mounting the sketches as a volume. I added dockerfile-mode to my Emacs, made a Dockerfile and a .dockerignore file following the tutorial for Dockerizing a Node.js web app, tried it out on my laptop, and pushed the image to my private Docker hub so that I could pull the image on my server. It turned out that Linode’s kernel had overlay built in instead of compiled as a module, so I followed this tip to fix it.

cat << EOF > /etc/systemd/system/containerd.service.d/override.conf
[Service]
ExecStartPre=
EOF

I also needed to uninstall my old docker.io and docker-compose, add the Docker PPA, and install docker-ce in order to get docker login to work properly on my server.

The next step was to move my web interface for tracking – not Quantified Awesome, but the button-filled webpage I’ve been using on my phone. I used lots of environment variables for passwords and tokens, so I switched to using --env-file file instead.

In order to move Quantified Awesome or my blog into Docker, I needed a MySQL container that could load my backups. docker-compose.yml Loading the SQL was just a matter of mounting the backup files in /docker-entrypoint-initdb.d, and mounting a directory as /var/lib/mysql should help with data persistence. If I added a script that created a user and granted access from '%', I could access the MySQL inside the Docker container from my laptop. I didn’t want my MySQL container to be publicly exposed on my server, though. It turned out that Docker bypassed ufw by setting iptables rules directly, so I followed the other instructions in this Stackoverflow answer and added these to the end of my /etc/ufw/after.rules:

# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16

-A DOCKER-USER -j ufw-user-forward

-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12

-A DOCKER-USER -j RETURN
COMMIT
# END UFW AND DOCKER

There’s more discussion on docker and ufw, but I don’t quite have the brainspace right now to fully understand it.

Anyway. Progress. sketches.sachachua.com is in a Docker container, and so is my button-based time tracker. I have a Docker container that I can use to load SQL backups, and I can connect to it for testing. The next step would probably be to try moving Quantified Awesome into a Docker container that talks to my MySQL container. If I can get that working, then I can try moving my blog into a container too.

Yesterday was for sleeping. Today I wanted to clean up my notes and post them, since I’ll forget too much if I keep going. More coding will have to wait for tomorrow–or maybe the day after, if I use some time for consulting instead. But slow progress is still progress, and it’s nice to feel like more of a geek again.