My initial goal was to create a small video tube site with the following features:
User registration and login
Comments section? (only if time allows it)
Most of the features above (with the exception of user management & comments section) would already be handled by our own service / video API. This led me to thinking that I could whip this together pretty quickly, as it would just be a couple pages of HTML + some CSS + SYNQ API usage. I didn't quite know what I wanted to do for user management at this point, but I figured I'd do some "DB backend password hash + session token -> browser cookie thing" (having had some prior experience with this).
Anyway, I wanted this to be an exercise in using docker - the idea being that others could simply check out my project and run it with no real effort! This meant that most of my time on this project would be spent on creating the scaffolding around the website, and not really designing & creating a working website itself (this was a 2 day hackathon project).
So reading about Docker, it's pretty important to note the concepts of the `Docker-daemon` and the `Docker context`. Ideally, you want everything to be inside the docker context in terms of your 'project', aka you want nothing do do with the 'host' filesystem if possible. File systems behave differently on different hosts (and so do networks) and you can't really make any assumptions that things will run on your colleague's computer unless you go 'full docker'.
So I did exactly that, I put everything (except for the Makefile) in a directory called `docker-context` like this:
Knowing that literally everything inside the docker context (when you run `docker build <context>`) gets sent to the docker daemon, having the 'context' represented as directory should help make you feel more conscious about what you put inside it.
Expanding the scope a bit (adding another container)
Now the frontend needed a backend / database to connect to, so here I thought it would be great to just 'spin up another container!'. And if the two containers are on the same docker network, they should just work together.
So I had to do some minor "refactoring", by wrapping everything i've made so far (named 'web', as it's the web frontend to this frontend <-> backend setup), and making a new directory named 'postgres' (as I decided to use PostgreSQL for my backend needs).
You can see the same kind of docker container 'pattern' going here for the 'postgres' service. A 'docker-context' directory (with basically nothing inside it this time, a schema definition + the Dockerfile), next to a Makefile that builds and runs the docker commands related to that Dockerfile.
The project now has 3 levels of Makefiles! This might seem 'bad' at first glance (and maybe it really is), but It's all in the name of 'modularization', where the makefile over only calls the lower level makefiles to build their own 'part' of the 'whole'. The innermost Makefile is where we build the actual applications, and the outer ones are more of a 'docker scaffolding' (think of it as docker-compose without docker-compose: setting up a docker network & launching / managing multiple containers from a single entrypoint / file).
The end results?
Tada! The above image is what you should get if you run the same code! (get source here)
The repo was just recently updated to working condition & tested as of 2017-07-01 (packages are a fragile thing, even if docker isn't!, also switching over to the alpine versions of container images). If you test it and you can't get it to run / work, feel free to create an issue on the github project for it!
I know whenever people say 'feel free to explore...', most people probably won't bother?! But... feel free to explore this (quite ugly, no CSS provided) docker project / incomplete website here!
Want to have your own video hackathon? Sign up and try our video API for free for 14 days!