- Clone Juggler
git clone https://github.com/daniel-lerch/juggler.git /opt/juggler
- Configure environment variables
sudo cp /opt/juggler/res/juggler.sh /etc/profile.d/
- Copy Systemd unit files
sudo cp /opt/juggler/res/juggler.timer /opt/juggler/res/juggler.service /etc/systemd/system/
- Enable Systemd timer
sudo systemctl enable --now juggler.timer
Juggler simpfies management of Docker Compose services by using common patterns and providing tools.
Applications are split into groups which reside in /opt/<group-name>
.
Within its group, each application is located in its own subfolder with a docker-compose.yml
or juggler.sh
file.
Juggler can manage manage backups for arbitrary applications but we will focus on Docker Compose here.
To use an existing Compose file with Juggler, no changes are required.
Just run app up
and Juggler will take care of Docker Compose settings and provide you a simple backup mechanism.
With a juggler.sh
file you can add custom commands as functions with a cmd_
prefix.
Any variables you set will be available in the Compose file with the ${BASH_VARIABLE_NAME}
syntax.
Technically, Juggler scans a Compose file for variable names and adds them from Bash to a generated .env
file.
Juggler consists out of four main components:
bin/app
the bootstrapper executablelib/core.sh
the core modulelib/compose.sh
the Docker Compose modulelib/backup.sh
the Borg Backup module
Major challenges with Bash for a complex framework like Juggler
- Parse variables from
docker-compose.yml
files. Solution: Implemented in an external Python script. - Juggler cannot iterate through multiple apps because of dangling variables. Solution: Start an own Juggler process for each app.
- Creating a good help overview requires lots of additional functions. Solution: Only show compose commands and backup module.
- For multiple apps it is hard to determine whether a command is available. Solution: Only allow certain command for batch execution.
Exposed variables:
PROJECT_DIR
e.g. /opt/global/nginxPROJECT_DIR_UID
e.g. rootPROJECT_DIR_GID
e.g. rootPROJECT_NAME
e.g. nginxPROJECT_GROUP
e.g. globalPROJECT_TITLE
e.g. global/nginxPROJECT_FULLNAME
e.g. global-nginx
Optional variables:
JUGGLER_CONFIG_FILE
JUGGLER_PROJECT_PATH
defaults to ~/apps
Exposed variables:
COMPOSE_PROJECT_NAME
alias for PROJECT_FULLNAMECOMPOSE_FILE
e.g. /opt/global/nginx/docker-compose.ymlAPP_CONTAINER_NAME
e.g. global-nginx-app
Optional variables (for execdb
command):
MYSQL_DATABASE
MYSQL_USER
MYSQL_PASSWORD
Other optional variables:
DOCKER_CONTEXT
Exposed functions:
invoke_compose()
Invokes docker-compose with all required options
Optional callbacks:
update_images()
(optional callback) Builds custom images and pull images
Exposed variables (change to customize behavior):
BACKUP_DIRS
e.g. /opt/global/nginxBACKUP_EXCLUDE
e.g. /opt/global/nginx/log /opt/global/nginx/.envBACKUP_PRUNE
e.g. --keep-within=7d --keep-weekly=4 --keep-monthly=12BACKUP_CRONJOB
e.g. 0 (disabled) or 1 (enabled)
Optional variables (for automatic MySQL dumps to /var/opt/backup
):
MYSQL_DATABASE
MYSQL_ROOT_PASSWORD
Optional callbacks:
prepare_backup()
Exports data before Borg backup starts
Nextcloud (located in /opt/church/nextcloud
)
juggler.sh
Custom functions and environment variables
APP_IMAGE=nextcloud:latest
DB_IMAGE=mariadb:latest
DB_CONTAINER_NAME=$COMPOSE_PROJECT_NAME-db
MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
MYSQL_PASSWORD=password
function cmd_execw() {
invoke_composer exec -u www-data app bash
}
.env
Environment file generated by Jugglerdocker-compose.yml
Compose file template using variables
version: '2.1'
services:
app:
image: ${APP_IMAGE}
container_name: ${APP_CONTAINER_NAME}
environment:
- MYSQL_DATABASE
- MYSQL_USER
- MYSQL_PASSWORD
- MYSQL_HOST=db
db:
image: ${DB_IMAGE}
container_name: ${DB_CONTAINER_NAME}
environment:
- MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE
- MYSQL_USER
- MYSQL_PASSWORD
- $JUGGLER_CONFIG_FILE Global Juggler config file
ENABLE_PROJECT_GROUPS=1
# Change this variable to set custom default backup target
BACKUP_TARGET_DEFAULT="/var/opt/backup"
BACKUP_TARGET_DEFAULT_ENCRYPTION="none"
BACKUP_TARGET_DEFAULT_PASSPHRASE=""
# Add additional targets that can be selected manually
BACKUP_TARGET_REMOTE="[email protected]:/var/opt/backup"
BACKUP_TARGET_REMOTE_ENCRYPTION="repokey"
BACKUP_TARGET_REMOTE_PASSPHRASE="password"