Automated, secure Docker hosting infrastructure.
docker-infra
uses Terraform, and
CoreOS to generate a lightweight, easy-to-use infra
for remotely deploying and managing Docker containers on DigitalOcean.
Given a infra named plat and a domain named example.com,
docker-infra
is preconfigured to perform the following when make apply
is
run:
-
Create a CoreOS DigitalOcean Droplet named plat, which accepts connections on ports for SSH, HTTP, HTTPS, Docker Machine networking, and Docker Swarm networking; all other connections are rejected.
It only accepts key-based authentication (no password auth) based on the provided SSH keys (more details on this in the Infrastructure Configuration section below).
It also has some shell customizations that can be found in
files/
, which can be modified to your liking. -
Create a DigitalOcean Floating IP for above instance.
-
Point example.com to proxy the above Floating IP (as a "proxied" name, this will mask the true origin (i.e. the Floating IP), which will not be visible to clients).
-
Point plat.example.com directly at the above Floating IP (as an "exposed" name, this will expose the true origin, and so is a suitable address to use with SSH and Docker Machine).
The local development machine should have the following tools.
- Docker and Docker Machine (Docker Machine comes preinstalled with Docker for Mac and Docker for Windows)
- Terraform
hash512
(or some other SHA-512 password-hashing utility likemkpasswd
)ssh-keygen
(for making SSH keys; alternatively you can use existing keys)
-
Create an
auth/
directory with the following pieces of data:admin.passhash
: a password hash generated usinghash512
. The corresponding password will be the password for the primary user,admin
.id_ed25519.pub
: a public key for personal access to the server. Should be generated along with a corresponding private key using:ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519 -C "comment"
. See this article for a better explanation of the behind-the-scenes of this command.id_ed25519.terraform
,id_ed25519.terraform.pub
: the public-private key pair that Terraform will use to access the server to perform remote provisioning. Generated the same way asid_ed25519.pub
.
-
Modify
infra.auto.tfvars
to have following shape:// name is the name of your infra, which will be associated with // infrastructure names on Cloudflare and DigitalOcean, as well as the // name of the resulting Docker Machine. Keep it simple and whitespace-free. name = "..." // cf_domain is the Cloudflare domain you'd like to attach your infra to, // i.e. "stevenxie.me" cf_domain = "..."
-
Create a
terraform.tfvars
of the following shape:// Cloudflare cf_email = "..." cf_token = "..." // DigitalOcean do_token = "..."
These are secrets that should not be included in your version control system. This repository automatically ignores
terraform.tfvars
in the.gitconfig
. -
Run
make apply
to automatically generate the infrastructure on DigitalOcean and Cloudflare.
docker-infra
is configured to make container deployment as seamless
as possible.
- Run
make mch-create
to create a Docker Machine corresponding tograpevine
. You only have to do this step once. - Run
. machine.env.sh
to load the environment variables corresponding to this Docker Machine into the current shell. This step has to be run every time you want to access the remote Docker daemon. - When you are done with deploying to the remote Docker daemon, switch back
to the local daemon by running
. unmachine.env.sh
.
After sourcing the Docker Machine env variables, deploy a container / composition of containers / stack / swarm the same way you would on a local machine. For example, try:
docker run -d --name hello-world -p 80:8000 crccheck/hello-world
Visit your Droplet's domain or floating IP to see the results.
- Given that your domain is example.com, consider manually pointing www.example.com at example.com using a CNAME record.
- Consider using this infra as a Docker Swarm manager, using
docker swarm init
(while connected to the remote Docker daemon). Once this is configured, you can bundle Docker containers into a stack using adocker-compose.yml
, and deploy them together usingdocker stack deploy
. - Consider encrypting
auth/*
andterraform.tfvars
withgit-secret
.