Skip to content

Latest commit

 

History

History
180 lines (126 loc) · 6.45 KB

README.md

File metadata and controls

180 lines (126 loc) · 6.45 KB

Deploying a docker-compose.yml to a server

Ansible role to deploy a docker-compose.yml into a home directory, best used with bigsudo.

This README describes the features, see TUTORIAL.md for a tutorial with opinionated patterns to acheive eXtreme DevOps.

Example

This role tests itself and you can start copying:

  • Dockerfile: will work by default for a CRUDLFA+ project, offer compressed and cached static file service and a spooler.
  • .gitlab-ci.yml: builds and pushes docker image to the GitLab image registry, provides a deployment job YAML template (macro), as well as 3 example deployment configurations for different deployment use cases
  • docker-compose.yml: for local and ephemeral deployments
  • docker-compose.traefik.yml: for yourlabs.traefik support
  • docker-compose.persist.yml: addon to use for persistent deployments, ie. are specified in .gitlab-ci.yml, requires docker-compose.traefik.yml

You need to change:

  • .gitlab-ci.yml: there are a few # UNCOMMENT ABOVE AND REMOVE BELOW comments, do as it says, so that you use yourlabs/ansible
  • ci.yourlabs.io with your server in .gitlab-ci.yml
  • Gitlab CI variable to set: $CI_SSH_KEY, it should contain an ed25510 private key, you can create one with: ssh-keygen -t ed25519 -a 100
  • Dockerfile: change the command argument --module=wsgi:application with the appropriate path to your wsgi application, remove bigsudo setup if you want and uncomment what you want

Then, you can customize all you want!

Other bigsudo commands you may use:

  • enable a backup systemd timer with: bigsudo yourlabs.compose backup home=/home/$CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME
  • on review deployment CI server, to remove unused images and volumes and networks: bigsudo yourlabs.docker prunecron @ci.your.host, this prevents the review-deployments from filling up disk space

You may also get more general and conceptual description on the blog article about eXtreme DevOps

Documentation of features

The purpose of this role is to automate deployment of a merge of docker-compose.yml files into a directory on a host, and automate stuff around that.

From within a directory with a docker-compose.yml file, you can deploy it in $host:/home/staging with the following command:

bigsudo yourlabs.compose home=/home/staging $user@$host

If $user@$host is not defined, then it will execute on localhost.

You can pass several compose files and environment variables will be proxied when it generates the final one:

FOO=bar bigsudo yourlabs.compose \
    home=/home/staging \
    compose_django_image=$YOUR_IMAGE \
    compose=docker-compose.yml,docker-compose.staging.yml

Directory generation

This role can also pre-create directories with a given uid, gid and mode, with the io.yourlabs.compose.mkdir label as such:

volumes:
- "./log/admin:/app/log"
labels:
- "io.yourlabs.compose.mkdir=./app/log:1000:1000:0750"

This will result in the creation of the {{ home }}/log/admin directory with owner 1000 and group 1000 and mode 0750.

Environment generation

Another interresting feature is automatic environment provisionning with each variable declared in service environment that is defined at runtime. For example with this in docker-compose.yml:

environment:
- FOO

Then executing the yourlabs.compose role with the FOO variable defined as such:

FOO=bar bigsudo yourlabs.compose home=/home/test

Will result in the following environment:

environment:
- FOO=bar

YAML overrides on the CLI

You can also add or override service values with the compose_servicename_keyname variable. Example overridding the compose[services][django][image] value on the fly:

bigsudo yourlabs.compose home=/home/test compose_django_image=yourimage

You can empty values on the fly if you want, just pass empty values, ie. to make compose[services][django][build] empty pass compose_django_build= without value. In the case where you don't clone your repo in the home directory, then docker-compose would yell if it doesn't find the path to the Dockerfile, this circumvents that limitation:

bigsudo yourlabs.compose home=/home/test compose_django_build=

Network automation

Networks can also be a bit tricky to manage with docker-compose, for example we typically have a web network with a load balancer such as traefik. This appends the web network to the django service, and that it will automatically attach the network if present by declaring the web network as external in the docker-compose.yml file it deploys:

bigsudo yourlabs.compose home=/home/test compose_django_networks=web

If you're doing the docker-compose.yml of your load balancer then you have the opposite issue: docker-compose.yml declares a web network as external, but docker-compose up will not create it and would fail as such:

ERROR: Network web declared as external, but could not be found. Please
create the network manually using `docker network create lol` and try again.

This role does prevent this issue by parsing docker-compose.yml for external networks and use the docker_network ansible module to pre-create on the host it if necessary.

As ansible role

Finnaly, you can use this role like any other ansible role, if you want to wrap it in more tasks in your repo:

- name: Ensure docker was setup once on this host
  include_role: name=yourlabs.compose
  vars:
    home: /home/yourthing
    compose_django_image: foobar
    compose_django_build:
    compose_django_networks:
    - web

Backups

Automated backups are enabled for deployments with a home argument. It will setup 3 scripts in /home:

  • ./backup.sh: create a local dump and backup in restic
  • ./restore.sh: list restic snapshots, run it with a restic snapshot hash as argument to restore the snapshot
  • ./prune.sh: remove old backups

It will create 1 systemd services and systemd timer,

  • backup-PROJECTNAME.service
  • backup-PROJECTNAME.timer

Hacking

To develop this role on localhost:

# build the image
docker build -t test .

# run bigsudo as such:
bigsudo . home=/tmp/test compose_django_build= compose_django_image=test compose=docker-compose.yml,docker-compose.persist.yml

Note that it will always try to run the backup script prior to updating it. If you change it, you need to rm backup.sh prior to running yourlabs.compose again so that it updates backup.sh.