services: backup: image: python:3.11-alpine volumes: - "{{ swarm_base }}:/mnt/source:ro" - "{{ backup_base }}/volumes/backups:/backups" - "{{ backup_base }}/volumes/work:/work" - "{{ backup_base }}/volumes/scripts:/scripts" {% if borg_repo.startswith('ssh://') %} - "{{ backup_base }}/volumes/ssh:/root/.ssh:ro" {% endif %} environment: - TZ={{ timezone }} - DEPLOYMENT_TIME={{ deployment_time }} - BACKUP_RETENTION_DAYS={{ backup_retention_days | default(14) }} - NTFY_TOPIC={{ ntfy_topic }} - PYTHONUNBUFFERED=1 - BORG_REPO={{ borg_repo }} - BORG_PASSPHRASE={{ borg_passphrase }} - BORG_COMPRESSION={{ borg_compression }} - BORG_KEEP_DAILY={{ borg_keep_daily }} - BORG_KEEP_WEEKLY={{ borg_keep_weekly }} - BORG_KEEP_MONTHLY={{ borg_keep_monthly }} command: > sh -c " apk add --no-cache borgbackup openssh-client && chmod +x /scripts/*.py && mkdir -p /scripts/logs && {% if homelab_build %} python3 /scripts/backup.py /mnt/source --blocklist {{ blocklist }} --work-dir /work --backup-dir /backups {% else %} echo '0 2 * * * cd /scripts && python3 backup.py /mnt/source --blocklist {{ blocklist }} --work-dir /work --backup-dir /backups >> logs/backup-$$(date +\\%Y\\%m\\%d).log 2>&1' > /etc/crontabs/root && echo '0 4 * * * cd /scripts && python3 cleanup.py /backups --blocklist {{ blocklist }} --retention-days ${BACKUP_RETENTION_DAYS} >> logs/cleanup-$$(date +\\%Y\\%m\\%d).log 2>&1' >> /etc/crontabs/root && crond -f {% endif %} " networks: - proxy deploy: mode: replicated replicas: 1 update_config: parallelism: 1 failure_action: rollback order: start-first delay: 5s monitor: 30s placement: constraints: - node.role == manager networks: proxy: external: true