This website was generated using Pelican!
More interestingly, it is hosted using Docker <http://docker.com/>_!
You can take a look at the Repo on GitHub to get all the details,
scripts and Dockerfiles used, but I will provide here a short summary
of the idea behind this approach.
There are 4 containers that make this website running:
- Pelican (Git + SSH + Pelican)
- Nginx HTTP Server
- Reverse HTTP Proxy
Pelican (Git + SSH + Pelican)
The pelican container is responsible for building this static
website. It provides a Git repository via an SSH connection (by
deriving from the debian-git-ssh image). The Git repository is
enhanced with a post-receive hook, that forces the generation of
the website and its deployment.
This process is very generic, and any other tool for static site
generation could be used instead of Pelican. The way I link to think
about this container is as a simple service that takes in input a Git
repository and outputs a website. This point of view is driven by the
fact that the container does not store any data. Instead, we use a
data container to do make data persistent. This has the advantage
that we can re-build, modify, remove the pelican container
without loosing data.
A data container is a container that exports some volumes. The
image website-data exports two volumes: /git and
/www. The pelican container will have access to both volumes,
handle the repo stored in the /git volume and output the
generate site in /www.
Ideally, one could design a backup container that takes volumes in
input and makes backups using S3 or other cloud provider... This
will probably stay in my TODO list for a while :)
Nignx HTTP Server
In order to publish the static website, I use a rather standard
nginx installation. The main difference is that linking volumes
accross containers requires them to have the same name (i.e., you
cannot link /www to /var/html/www). Therefore, I extended
the nginx basic Dockerfile, and created a sym-link between the volume
and the directory where nginx looks for the website.
One of the advantages of this design is the possibility of
instantiating multiple servers that have access to the same
data-container. This makes it possible to experiment with different
webservers, or perform A/B testing.
To avoid having to change DNS entries for each subdomain, I am using
the nginx reverse proxy image jwilder/nginx-proxy . This is a
really nice trick, in which the reverse-proxy configuration file is
automatically (re-)generated everytime a new container is started with
the environment variables VHOST_HOST. Each time I start a new
webserver container, I just need to specify a different vhost name,
and the reverse proxy will be automatically setup.
More details are available in the original author's blog post.
I had been wanting to experiment with this idea of micro-services for
a while. Although, this design is far from perfect, I think it fits
nicely into (my?) understanding of micro services: highly specialized
components that are interchangeable and non-persistent.