Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.
/ docker-infra Public archive

Automated, secure Docker hosting infrastructure.

License

Notifications You must be signed in to change notification settings

hulloitskai/docker-infra

Repository files navigation

docker-infra

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.

Effects

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).

Prerequisites

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 like mkpasswd)
  • ssh-keygen (for making SSH keys; alternatively you can use existing keys)

Infrastructure Configuration

  1. Create an auth/directory with the following pieces of data:

    • admin.passhash: a password hash generated using hash512. 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 as id_ed25519.pub.
  2. 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 = "..."
  3. 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.

  4. Run make apply to automatically generate the infrastructure on DigitalOcean and Cloudflare.

Deploying Docker Containers

docker-infra is configured to make container deployment as seamless as possible.

Configuration

  1. Run make mch-create to create a Docker Machine corresponding to grapevine. You only have to do this step once.
  2. 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.
  3. When you are done with deploying to the remote Docker daemon, switch back to the local daemon by running . unmachine.env.sh.

Deploying

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.


Other Considerations

  • 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 a docker-compose.yml, and deploy them together using docker stack deploy.
  • Consider encrypting auth/* and terraform.tfvars with git-secret.