I worked on optimizing these setup instructions for a long time. I believe this is now a quick and simple set of instructions to get your swarm up and running, including management tools.
- A VM or server running Ubuntu 20.04 LTS that is reachable using SSH.
- At least ~30G worth of storage, though that won't get you far, i.e. you will have to prune your containers very frequently. I recommend at minimum 40G, and personally would go with at least 100G.
What you'll have when you are done:
Default Endpoint | Product | Description |
---|---|---|
- | Docker Swarm | The core swarm |
https://registry.yourdomain.com:5000 | Docker Registry | Your own private docker registry. Needed to deploy your own containers to your swarm |
https://traefik.yourdomain.com | Traefik | The automatic reverse proxy, including its admin UI. Lets Encrypt will automatically create SSL certificates for you |
https://swarmpit.yourdomain.com | Swarmpit | Manage your swarm and monitor resources (using influxdb) |
https://keycloak.yourdomain.com | Keycloak | SSO server |
https://yourdomain.com:25 | Postfix | A SMTP server to forward emails to you |
https://gateone.yourdomain.com | GateOne | An HTTPS based SSH client |
https://droppy.yourdomain.com | Droppy | File storage server with a web interface |
https://yourdomain.com | nginx | Webserver to serve public files uploaded using Droppy |
If you don't want or need any of these services, just remove them from docker-compose.yml. With all these services combined, I believe you are well set-up for deploying your app stack.
I actually recommend that you fork this repository, as it allows you to
- Manage all input parameters (environment variables mentioned below) in Github Secrets
- Use Github's Actions to deploy whenever you make any change. This repository includes an auto-deployment workflow, see deploy.yml.
If you don't want to do that, you can also just download the docker-compose.yml file and deal with setting variables yourself.
Partitions:
- At least 15G root partition
- At least 5G /var/log
- Rest /var/lib
sudo -s
apt update
apt-get upgrade -y
apt install mailutils apt-transport-https ca-certificates curl software-properties-common apache2-utils
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
apt update
apt install docker-ce -y
# Optionally limit log size
journalctl --vacuum-size=100M
systemctl start docker
And on the master node:
docker swarm init
On the worker nodes, install Docker as above, but then execute the following commands once per worker.
On master:
docker swarm join-token worker
Copy the result to the worker node, for example:
docker swarm join --token SWMTKN-1-sdrgddrg0988sr9sdgrddafvsefsgsg098drgrag-wfdr098drgrd8g 172.173.174.175:2377
(Optional, not needed if you have a good SSH connection): Make browser-based SSH client work temporarily, without SSL
docker run -t --name=gateone -p 8000:8000 dezota/gateone
sudo -s
curl -L https://github.com/docker/compose/releases/download/1.26.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
adduser -g docker github
su - github
ssh-keygen
mv .ssh/id_rsa.pub .ssh/authorized_keys
cat .ssh/id_rsa
rm .ssh/id_rsa
cat .ssh/authorized_keys
exit
Store the hostname, private key (id_rsa) and public key (id_rsa.pub) in Github secrets (or set through environment variables in docker-compose file). Example:
DOCKER_SSH_HOST=mydomain.com
DOCKER_SSH_PRIVATE_KEY=`cat id_rsa`
DOCKER_SSH_PUBLIC_KEY=`cat id_rsa.pub`
curl -fsSL https://raw.githubusercontent.com/MatchbookLab/local-persist/master/scripts/install.sh | sudo bash
docker volume create -d local-persist -o mountpoint=/var/lib/docker-registry --name=docker-local-persist
docker volume create -d local-persist -o mountpoint=/var/lib/droppy --name=droppy
docker volume create -d local-persist -o mountpoint=/var/lib/droppy/public/ --name=droppy-public
(see https://github.com/MatchbookLab/local-persist)
Install domain, username, hashed password, and email in Github Secrets (or set through environment variables in docker-compose file). For example:
TRAEFIK_DASHBOARD_DOMAIN=mydomain.com
TRAEFIK_DASHBOARD_USERNAME=admin
TRAEFIK_DASHBOARD_HASHED_PASSWORD=`openssl passwd -apr1 "$PASSWORD"`
LETSENCRYPT_EMAIL=me@example.com
Basic authentication is handled by Traefic, not by the registry, so there is not need to configure anything here. Just store the hostname, username and hashed password in Github secrets (or set through environment variables in docker-compose file).
WARNING: Hostname has to include port number!
Example:
REGISTRY_DOMAIN=mydomain.com:5000
REGISTRY_USERNAME=myuser
REGISTRY_HASHED_PASSWORD=`htpasswd -Bbn myuser mypassword`
Just put in Github secrets (or set through environment variables in docker-compose file). Example:
KEYCLOAK_ADMIN_USERNAME=user
KEYCLOAK_ADMIN_PASSWORD=password
To enable a mail forwarder, define the following variable in Github Secrets (or set through environment variables in docker-compose file):
SMF_CONFIG=user@mydomain.com:test@gmail.com;user@mydomain2.com:test@gmail.com
Start deploy on Github. Or, copy the docker-compose.yml from this repository root, and install using "docker deploy" (after setting all the variables mentioned above). Done.
curl https://myuser:mypassword@$REGISTRY_DOMAIN:5000/v2/_catalog