Creating practical services with volumes, subdomains, passing credentials¶
Harbor is a complete framework for building flexible multi-container environments, to complete it’s mission Harbor provides set of tools and patterns described in this documentation chapter.
Connecting domains, subdomains and optionally SSL¶
Domains and subdomains are automatically discovered by JWilder’s Docker-Gen, when a container is started.
Docker-gen container, later called “service discovery” collects environment variables - including VIRTUAL_HOST and VIRTUAL_PORT for each running container, then generates NGINX configuration file and calls reload.
Similar mechanism is practiced by docker-letsencrypt-nginx-proxy-companion to automatically connect Let’s Encrypt certificate - LETSENCRYPT_HOST and LETSENCRYPT_EMAIL environment variables are required to do so.
Example:
version: 2.4
services:
app_web_mattermost:
image: mattermost/mattermost-prod-web:5.23.2
depends_on:
- app_mattermost
environment:
APP_HOST: "app_mattermost"
APP_PORT: "8000"
# gateway configuration
VIRTUAL_HOST: "mattermost.${MAIN_DOMAIN}${DOMAIN_SUFFIX}"
VIRTUAL_PORT: "80"
LETSENCRYPT_HOST: "mattermost.${MAIN_DOMAIN}${DOMAIN_SUFFIX}"
LETSENCRYPT_EMAIL: "${LETSENCRYPT_EMAIL}"
MAIN_DOMAIN=riotkit.org
DOMAIN_SUFFIX=.localhost
LETSENCRYPT_EMAIL=noreply@riotkit.org
MAIN_DOMAIN, DOMAIN_SUFFIX and LETSENCRYPT_EMAIL convention
- Use MAIN_DOMAIN to specify a main domain if hosting services under multiple subdomains
- DOMAIN_SUFFIX, on development environment set to “.localhost” - in result on Linux you will be able to access services like on production but under localhost sudomain eg. my-subdomain.riotkit.org.localhost. Please note: When using
harbor :deployment:apply
the DOMAIN_SUFFIX is automatically erased when deploying to production server - LETSENCRYPT_EMAIL allows to have a globally defined e-mail address for all services
Passing credentials and configuration options¶
Most universal way to configure services is to pass environment variables.
Passwords, sensitive data and common values shared between services put in .env
file, then encrypt it using Ansible Vault command harbor :env:encrypt
.
In result a .env-prod
file will be produced. Don’t commit .env
to git - add it to ignore, commit .env-prod
instead.
When deploying to production server with harbor :deployment:apply
mechanism the .env-prod
will be decrypted on-the-fly and placed as .env
on the destination server.
version: 2.4
services:
postgres:
image: postgres:12.4
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "${DB_PASSWD}"
POSTGRES_DATABASE: "mydb"
expose:
- 5432
volumes:
- ./data/pg:/var/lib/pgsql
DB_PASSWD=my-passwd
Note: .env
is read by docker-compose and by RKD in makefile.yaml by default. It is a good place to put your configuration options
Volumes¶
In previous chapter we were talking about naming conventions, remember? There is a distinction for static and dynamic volumes.
- Static volumes are kept in GIT repository, those are usually versioned configuration files
- Dynamic volumes are application data (database binary files, user file uploads)
version: 2.4
services:
my-website:
image: nginx:1.19
environment:
VIRTUAL_HOST: "my-website.localhost"
VIRTUAL_PORT: "80"
volumes:
# in www-data we keep other cloned git repositories managed by Harbor
- ./apps/www-data/my-website:/var/www/html
- ./container/my-website/nginx.conf:/etc/nginx/nginx.conf:ro
postgres:
image: postgres:12.4
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "${DB_PASSWD}"
POSTGRES_DATABASE: "mydb"
expose:
- 5432
volumes:
- ./data/pg:/var/lib/pgsql