Skip to content

Instantly share code, notes, and snippets.

@dreiggy
Forked from OnkelDom/docker-systemd.md
Created September 30, 2021 07:34
Show Gist options
  • Save dreiggy/19a89bbde8bbcbfbb2001f874dc028b8 to your computer and use it in GitHub Desktop.
Save dreiggy/19a89bbde8bbcbfbb2001f874dc028b8 to your computer and use it in GitHub Desktop.
My Setup to manage docker containers with systemd services

Setup Docker Systemd on Ubuntu 20.04

This is my docker systemd setup. I stored no configs or environment vars in this gist.

Install Docker

# Install Dependencies
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release

# Add Docker Repo
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Install Docker
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

Install Docker-Compose

$ sudo curl -sSL https://github.com/docker/compose/releases/download/`curl -s https://github.com/docker/compose/tags | \
grep "compose/releases/tag" | sed -r 's|.*([0-9]+\.[0-9]+\.[0-9]+).*|\1|p' | head -n 1`/docker-compose-`uname -s`-`uname -m` \
-o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose

Configure and Restart Daemon

$ cat <<EOF | sudo tee /etc/docker/daemon.json
{
    "experimental": true,
    "exec-opts": ["native.cgroupdriver=systemd"],
    "ipv6": false,
    "fixed-cidr-v6": "2001:db8:1::/64",
    "log-driver": "json-file",
    "log-opts": {
      "max-size": "250m"
    },
    "metrics-addr": "0.0.0.0:9323",
    "storage-driver": "overlay2",
    "no-new-privileges": true
}
EOF

$ sudo systemctl restart docker.service

# Enable at startup
$ sudo systemctl enable docker.service

Systemd-Resolv Stubliner (if adguard runs)

Disable systemd listener for port 53

$ sudo mkdir /etc/systemd/resolved.conf.d

$ cat <<EOF | sudo tee /etc/systemd/resolved.conf.d/adguardhome.conf
[Resolve]
DNS=127.0.0.1
DNSStubListener=no
EOF

$ sudo mv /etc/resolv.conf /etc/resolv.conf.backup
$ sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

$ sudo systemctl restart systemd-resolved

Logrotate Rules

# Traefik Access Log
$ cat <<EOF | sudo tee /etc/logrotate.d/traefik
/opt/docker-traefik/*.log {
    daily
    rotate 7
    compress
    delaycompress
    create 0640 root root
    missingok
    dateext
    dateformat _%Y%m%d
    postrotate
      /usr/bin/systemctl restart traefik.service 1>/dev/null
    endscript
}
EOF

# Bitwarden Access Log
$ cat <<EOF | sudo tee /etc/logrotate.d/bitwarden
/opt/docker-bitwarden/*.log {
    daily
    rotate 7
    compress
    delaycompress
    create 0640 root root
    missingok
    dateext
    dateformat _%Y%m%d
}
EOF

Systemd-unit traefik.service

$ cat <<EOF | sudo tee /etc/systemd/system/traefik.service
[Unit]
Description=Traefik
Documentation=https://doc.traefik.io
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="CLOUDFLARE_API_EMAIL="
Environment="CLOUDFLARE_API_KEY="
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/touch /opt/docker-%N/acme.json /opt/docker-%N/access.log
ExecStartPre=-/usr/bin/chmod 600 /opt/docker-%N/acme.json /opt/docker-%N/access.log
ExecStartPre=-/usr/bin/mkdir -p /opt/docker-%N/rules
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --publish 80:80 \
  --publish 443:443 \
  # Use custom DNS for traefik cert renew
  --dns 1.0.0.1 \
  --dns 1.1.1.1 \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  --volume /opt/docker-%N:/opt \
  --env TZ=Europe/Berlin \
  --env CF_API_EMAIL=${CLOUDFLARE_EMAIL} \
  --env CF_API_KEY=${CLOUDFLARE_API_KEY} \
  --label traefik.enable="true" \
  --label traefik.http.routers.http-catchall.entrypoints="http" \
  --label traefik.http.routers.http-catchall.rule="HostRegexp(`{host:.+}`)" \
  --label traefik.http.routers.http-catchall.middlewares="redirect-to-https" \
  --label traefik.http.middlewares.redirect-to-https.redirectscheme.scheme="https" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="api@internal" \
  traefik:latest \
    --global.checkNewVersion=true \
    --global.sendAnonymousUsage=true \
    --entryPoints.http.address=:80 \
    --entryPoints.https.address=:443 \
    --entryPoints.traefik.address=:8080 \
    --entryPoints.metrics.address=:8082 \
    --serversTransport.insecureSkipVerify=true \
    --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22 \
    --api=true \
    --log=true \
    --log.level=DEBUG \
    --log.format=json \
    --accessLog=true \
    --accessLog.filePath=/opt/access.log \
    --accessLog.bufferingSize=100 \
    --accessLog.filters.statusCodes=200,300-302,400-410,500-502 \
    --accesslog.fields.names.StartUTC=drop \
    --accesslog.format=json \
    --metrics.prometheus=true \
    --metrics.prometheus.addEntryPointsLabels=true \
    --metrics.prometheus.addServicesLabels=true \
    --metrics.prometheus.entryPoint=metrics \
    --providers.docker=true \
    --providers.docker.exposedByDefault=false \
    --entrypoints.https.http.tls.certresolver=dns-cloudflare \
    --entrypoints.https.http.tls.domains[0].main=${DOMAINNAME} \
    --entrypoints.https.http.tls.domains[0].sans=*.${DOMAINNAME} \
    --providers.docker.network=proxy \
    --providers.docker.swarmMode=false \
    --providers.file.directory=/opt/rules \
    --providers.file.watch=true \
    #--certificatesResolvers.dns-cloudflare.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory \
    --certificatesResolvers.dns-cloudflare.acme.email=${CLOUDFLARE_EMAIL} \
    --certificatesResolvers.dns-cloudflare.acme.storage=/opt/acme.json \
    --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare \
    --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53 \
    --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.delayBeforeCheck=90
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now traefik.service && sudo journalctl -feu traefik.service

Systemd-unit posteio.service

$ cat <<EOF | sudo tee /etc/systemd/system/posteio.service
[Unit]
Description=Poste.io
Documentation=https://poste.io/doc/
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname mail.${DOMAINNAME} \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/data \
  --env HTTP_PORT="8080" \
  --env HTTPS_PORT="8443" \
  --env HTTPS="OFF" \
  --env DISABLE_CLAMAV="true" \
  --env TZ="Europe/Berlin" \
  --publish 25:25 \
  --publish 110:110 \
  --publish 143:143 \
  --publish 465:465 \
  --publish 587:587 \
  --publish 993:993 \
  --publish 995:995 \
  --publish 4190:4190 \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`mail.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="8080" \
  analogic/poste.io:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now posteio.service && sudo journalctl -feu posteio.service

Systemd-unit bitwarden.service

$ cat <<EOF | sudo tee /etc/systemd/system/bitwarden.service
[Unit]
Description=Bitwarden
Documentation=https://github.com/dani-garcia/bitwarden_rs/wiki
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="SMTP_HOST="
Environment="SMTP_FROM="
Environment="SMTP_FROM_NAME="
Environment="SMTP_PORT="
Environment="SMTP_USER="
Environment="SMTP_PASS="
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/touch /opt/docker-%N/access.log
ExecStartPre=-/usr/bin/chmod 660 /opt/docker-%N/access.log
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/data \
  --env TZ="Europe/Berlin" \
  --env ADMIN_TOKEN="" \
  --env DISABLE_ADMIN_TOKEN="false" \
  --env ROCKET_PORT="8080" \
  --env WEBSOCKET_ENABLED="true" \
  --env SIGNUPS_ALLOWED="false" \
  --env SIGNUPS_VERIFY="true" \
  --env INVITATIONS_ALLOWED="true" \
  --env INVITATION_ORG_NAME="OnkelDom.eu" \
  --env DOMAIN="https://%N.${DOMAINNAME}" \
  --env SMTP_HOST="${SMTP_HOST}" \
  --env SMTP_FROM="${SMTP_FROM}" \
  --env SMTP_FROM_NAME="${SMTP_FROM_NAME}" \
  --env SMTP_PORT="${SMTP_PORT}" \
  --env SMTP_USERNAME="${SMTP_USER}" \
  --env SMTP_PASSWORD="${SMTP_PASS}" \
  --env HELO_NAME="server.${DOMAINNAME}" \
  --env SMTP_SSL="true" \
  --env SMTP_TIMEOUT="15" \
  --env LOG_FILE="/data/access.log" \
  --env LOG_LEVEL="warn" \
  --env EXTENDED_LOGGING="true" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.tls="true" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="8080" \
  --label traefik.http.routers.%N-ws-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-ws-rtr.rule="HostHeader(`%N.${DOMAINNAME}`) && Path(`/notifications/hub`)" \
  --label traefik.http.middlewares.%N-ws="bw-stripPrefix@file" \
  --label traefik.http.routers.%N-ws.service="%N-websocket" \
  --label traefik.http.services.%N-websocket.loadbalancer.server.port="3012" \
  bitwardenrs/server:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now bitwarden.service && sudo journalctl -feu bitwarden.service

Systemd-Unit grafana.service

$ cat <<EOF | sudo tee /etc/systemd/system/grafana.service
[Unit]
Description=Grafana Server
Documentation=https://grafana.com/docs/grafana/latest/
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="GF_ADMIN_USER="
Environment="GF_ADMIN_PASS="
Environment="SMTP_HOST="
Environment="SMTP_FROM="
Environment="SMTP_FROM_NAME="
Environment="SMTP_PORT=587"
Environment="SMTP_USER="
Environment="SMTP_PASS="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/var/lib/grafana \
  --env GF_INSTALL_PLUGINS="grafana-clock-panel,grafana-simple-json-datasource,grafana-piechart-panel,percona-percona-app,ryantxu-ajax-panel,macropower-analytics-panel,grafana-github-datasource,sbueringer-consul-datasource,camptocamp-prometheus-alertmanager-datasource" \
  --env GF_SECURITY_ADMIN_USER="${GF_ADMIN_USER}" \
  --env GF_SECURITY_ADMIN_PASSWORD="${GF_ADMIN_PASS}" \
  --env GF_USERS_ALLOW_SIGN_UP="false" \
  --env GF_USERS_AUTO_ASSIGN_ORG_ROLE="Viewer" \
  --env GF_DEFAULT_INSTANCE_NAME="${GF_ADMIN_USER}" \
  --env GF_SERVER_PROTOCOL="http" \
  --env GF_SERVER_ROOT_URL="https://%N.${DOMAINNAME}" \
  --env GF_EMAILS_WELCOME_EMAIL_ON_SIGN_UP="true" \
  --env GF_ALERTING_ENABLED="true" \
  --env GF_ALERTING_EXECUTE_ALERTS="true" \
  --env GF_SMTP_ENABLED="true" \
  --env GF_SMTP_HOST="${SMTP_HOST}:${SMTP_PORT}" \
  --env GF_SMTP_USER="${SMTP_USER}" \
  --env GF_SMTP_PASSWORD="${SMTP_PASS}" \
  --env GF_SMTP_SKIP_VERIFY="false" \
  --env GF_SMTP_FROM_ADDRESS="${SMTP_FROM}" \
  --env GF_SMTP_FROM_NAME="${SMTP_FROM_NAME}" \
  --env GF_METIRICS_ENABLED="true" \
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="3000" \
  grafana/grafana:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now grafana.service && sudo journalctl -feu grafana.service

Systemd-Unit adguard.service

$ cat <<EOF | sudo tee /etc/systemd/system/adguard.service
[Unit]
Description=AdGuard
Documentation=https://github.com/AdguardTeam/AdGuardHome/wiki
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/work
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/conf
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N/work:/opt/adguardhome/work \
  --volume /opt/docker-%N/conf:/opt/adguardhome/conf \
  --publish 53:53/tcp \
  --publish 53:53/udp \
  --publish 80:80/tcp \
  --publish 67:67/udp \
  --publish 68:68/tcp \
  --publish 68:68/udp \
  --publish 853:853/tcp \
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="3000" \
  adguard/adguardhome:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now adguard.service && sudo journalctl -feu adguard.service

Systemd-Unit adguard_exporter.service

$ cat <<EOF | sudo tee /etc/systemd/system/adguard_exporter.service
[Unit]
Description=AdGuard Prometheus Exporter
Documentation=https://github.com/ebrianne/adguard-exporter
Requires=docker.service
After=docker.service adguard.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="ADGUARD_USER="
Environment="ADGUARD_PASS="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --env TZ="Europe/Berlin" \
  --env adguard_protocol="https" \
  --env adguard_hostname="adguard" \
  --env adguard_username="${ADGUARD_USER}" \
  --env adguard_password="${ADGUARD_PASS}" \
  --env interval="60s" \
  --env log_limit="10000" \
  ebrianne/adguard-exporter:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now adguard_exporter.service && sudo journalctl -feu adguard_exporter.service

Systemd-Unit unifi.service (controller)

$ cat <<EOF | sudo tee /etc/systemd/system/unifi.service
[Unit]
Description=Unifi Controller
Documentation=https://help.ui.com/
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/unifi/data \
  --env TZ="Europe/Berlin" \
  --publish 3478:3478/udp \
  --publish 10001:10001/udp \
  --publish 1900:1900/udp \
  --publish 8443:8443 \
  --publish 8080:8080 \
  --publish 8843:8843 \
  --publish 8880:8880 \
  --publish 6789:6789 \
  --publish 5514:5514 \
  --label traefik.enable="true" \
  #--label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.tls="true" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.scheme="https" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="8443" \
  jacobalberty/unifi:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now unifi.service && sudo journalctl -feu unifi.service

Systemd-Unit unifi_exporter.service

$ cat <<EOF | sudo tee /etc/systemd/system/unifi_exporter.service
[Unit]
Description=Unifi Exporter
Documentation=https://github.com/unifi-poller/unifi-poller/wiki
Requires=docker.service
After=docker.service unifi.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="UNIFI_USER="
Environment="UNIFI_PASS="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --env TZ="Europe/Berlin" \
  --env UP_PROMETHEUS_DISABLE="false" \
  --env UP_PROMETHEUS_REPORT_ERRORS="false" \
  --env UP_PROMETHEUS_HTTP_LISTEN="0.0.0.0:9130" \
  --env UP_UNIFI_DEFAULT_URL="https://unifi:8443" \
  --env UP_UNIFI_DEFAULT_USER="${UNIFI_USER}" \
  --env UP_UNIFI_DEFAULT_PASS="${UNIFI_PASS}" \
  --env UP_UNIFI_DEFAULT_SAVE_DPI="true" \
  --env UP_INFLUXDB_DISABLE="true" \
   golift/unifi-poller:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now unifi_exporter.service && sudo journalctl -feu unifi_exporter.service

Systemd-Unit prometheus.service

$ cat <<EOF | sudo tee /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Documentation=https://prometheus.io/docs
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/file_sd
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/rules
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/db
ExecStartPre=-/usr/bin/chown -R nobody:nogroup /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/etc/prometheus \
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="9090" \
  prom/prometheus:latest \
    --config.file=/etc/prometheus/prometheus.yml \
    --storage.tsdb.path=/etc/prometheus/db \
    --storage.tsdb.retention.time=14d \
    --web.console.libraries=/usr/share/prometheus/console_libraries \
    --web.console.templates=/usr/share/prometheus/consoles \
    --web.enable-lifecycle \
    --enable-feature=remote-write-receiver \
    --log.format=json \
    --web.enable-admin-api \
    --web.external-url=https://%N.${DOMAINNAME}
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now prometheus.service && sudo journalctl -feu prometheus.service

Systemd-Unit alertmanager.service

$ cat <<EOF | sudo tee /etc/systemd/system/alertmanager.service
[Unit]
Description=Alertmanager
Documentation=https://prometheus.io/docs/alerting/latest/alertmanager/
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/db
ExecStartPre=-/usr/bin/chown -R nobody:nogroup /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/etc/alertmanager \
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="9093" \
  prom/alertmanager:latest \
    --config.file=/etc/alertmanager/alertmanager.yml \
    --storage.path=/etc/alertmanager/db \
    --log.format=json \
    --web.external-url=https://%N.${DOMAINNAME}
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now alertmanager.service && sudo journalctl -feu alertmanager.service

Systemd-Unit alertbot.service

$ cat <<EOF | sudo tee /etc/systemd/system/alertbot.service
[Unit]
Description=Alertbot for Telegram
Documentation=https://github.com/metalmatze/alertmanager-bot
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="TG_CHAT_ID="
Environment="TG_BOT_TOKEN="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/data \
  --env TZ="Europe/Berlin" \
  --env TELEGRAM_ADMIN="${TG_CHAT_ID}" \
  --env TELEGRAM_TOKEN="${TG_BOT_TOKEN}" \
  metalmatze/alertmanager-bot:latest \
    --alertmanager.url=http://alertmanager:9093 \
    --log.level=info \
    --store=bolt \
    --bolt.path=/data/bot.db
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now alertbot.service && sudo journalctl -feu alertbot.service

Systemd-Unit blackbox_exporter.service

$ cat <<EOF | sudo tee /etc/systemd/system/blackbox_exporter.service
[Unit]
Description=Blackbox Exporter
Documentation=https://github.com/prometheus/blackbox_exporter
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/wget https://raw.githubusercontent.com/prometheus/blackbox_exporter/master/blackbox.yml -O /opt/docker-%N/blackbox_exporter.yml
ExecStartPre=-/usr/bin/chown -R nobody:nogroup /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/etc/blackbox_exporter \
  --env TZ="Europe/Berlin" \
  prom/blackbox-exporter:latest \
    --config.file=/etc/blackbox_exporter/blackbox_exporter.yml \
    --log.format=json
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now blackbox_exporter.service && sudo journalctl -feu blackbox_exporter.service

Systemd-Unit consul.service

$ cat <<EOF | sudo tee /etc/systemd/system/consul.service
[Unit]
Description=Consul
Documentation=https://www.consul.io/docs
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/conf
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/db
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N/db:/consul/data \
  --volume /opt/docker-%N/conf:/consul/config \
  --env TZ="Europe/Berlin" \
  --publish 8500:8500 \
  --publish 8301:8301 \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="8500" \
  hashicorp/consul:latest \
    agent -config-file=/consul/config/config.json -config-dir=/consul
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now consul.service && sudo journalctl -feu consul.service

Systemd-Unit consul_exporter.service

$ cat <<EOF | sudo tee /etc/systemd/system/consul_exporter.service
[Unit]
Description=
Documentation=
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="" \ # FIXME PORT
  :latest # FIXME IMAGE
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now consul_exporter.service && sudo journalctl -feu consul_exporter.service

Systemd-Unit consul_template.service

$ cat <<EOF | sudo tee /etc/systemd/system/consul_template.service
[Unit]
Description=Consul Template
Documentation=https://github.com/hashicorp/consul-template
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/templates
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/consul_template \
  --volume prometheus/file_sd:/consul_template/file_sd \
  --env TZ="Europe/Berlin" \
  hashicorp/consul-template:light \
    -config /consul-template/config/config.hcl
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now consul_template.service && sudo journalctl -feu consul_template.service

Systemd-Unit loki.service

$ cat <<EOF | sudo tee /etc/systemd/system/loki.service
[Unit]
Description=Grafana Loki
Documentation=https://grafana.com/docs/loki
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/db
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/opt \
  --env TZ="Europe/Berlin" \
  --publish 3100:31200 \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="3100" \
  grafana/loki:latest \
    /usr/bin/loki -config.file=/opt/loki.yaml
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now loki.service && sudo journalctl -feu loki.service

Systemd-Unit watchtower.service

$ cat <<EOF | sudo tee /etc/systemd/system/watchtower.service
[Unit]
Description=Watchtower
Documentation=https://containrrr.dev/watchtower/
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N-contabo \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  --env TZ="Europe/Berlin" \
  --env WATCHTOWER_CLEANUP="true" \
  --env WATCHTOWER_REMOVE_VOLUMES="true" \
  --env WATCHTOWER_INCLUDE_STOPPED="true" \
  --env WATCHTOWER_NO_STARTUP_MESSAGE="false" \
  --env WATCHTOWER_SCHEDULE="0 30 12 * * *" \
  --env WATCHTOWER_NOTIFICATIONS="email" \
  --env WATCHTOWER_NOTIFICATION_EMAIL_FROM="watchtower@${DOMAINNAME}" \
  --env WATCHTOWER_NOTIFICATION_EMAIL_TO="tg@${DOMAINNAME}" \
  --env WATCHTOWER_NOTIFICATION_EMAIL_SERVER="smtp-to-telegram" \
  --env WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT="2525" \
  --env WATCHTOWER_NOTIFICATION_EMAIL_DELAY="2" \
  --env WATCHTOWER_NOTIFICATIONS_LEVEL="info" \
  containrrr/watchtower:latest
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now watchtower.service && sudo journalctl -feu watchtower.service

Systemd-Unit smtp-to-telegram.service

$ cat <<EOF | sudo tee /etc/systemd/system/smtp-to-telegram.service
[Unit]
Description=SMTP to Telegram
Documentation=https://github.com/KostyaEsmukov/smtp_to_telegram
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="TG_CHAT_ID="
Environment="TG_BOT_TOKEN="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --publish 2525:2525 \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --env TZ="Europe/Berlin" \
  --env ST_TELEGRAM_CHAT_IDS="${TG_CHAT_ID}" \
  --env ST_TELEGRAM_BOT_TOKEN="${TG_BOT_TOKEN}" \
  --env ST_TELEGRAM_MESSAGE_TEMPLATE="{subject}\\n\\n{body}" \
  dominiklenhardt/smtp_to_telegram:latest-amd64
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now smtp-to-telegram.service && sudo journalctl -feu smtp-to-telegram.service

Systemd-Unit vmstorage.service

$ cat <<EOF | sudo tee /etc/systemd/system/vmstorage.service
[Unit]
Description=ViktoriaMetriks Storage
Documentation=https://github.com/VictoriaMetrics/VictoriaMetrics
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="VMUSERNAME="
Environment="VMPASSWORD="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/db
#ExecStartPre=-/usr/bin/chown -R nobody:nogroup /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/victoria-metrics-data \
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="8428" \
  victoriametrics/victoria-metrics:latest \
    -loggerFormat=json \
    -loggerLevel=INFO \
    -httpAuth.username="${VMUSERNAME}" \
    -httpAuth.password="${VMPASSWORD}"
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N
LimitAS=infinity
LimitRSS=infinity
LimitCORE=infinity
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now vmstorage.service && sudo journalctl -feu vmstorage.service

Systemd-Unit vmagent.service

$ cat <<EOF | sudo tee /etc/systemd/system/vmagent.service
[Unit]
Description=ViktoriaMetriks Agent
Documentation=https://victoriametrics.github.io/vmagent.html
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="VMUSERNAME="
Environment="VMPASSWORD="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N/file_sd
ExecStartPre=-/usr/bin/touch /opt/docker-%N/scrape.yml
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/vmagent-remotewrite-data \
  --env TZ="Europe/Berlin" \
  victoriametrics/vmagent:latest \
    -loggerFormat=json \
    -loggerLevel=INFO \
    -enableTCP6=true \
    -promscrape.config="/vmagent-remotewrite-data/scrape.yml" \
    -remoteWrite.url="http://vmstorage:8428/api/v1/write"
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N
LimitAS=infinity
LimitRSS=infinity
LimitCORE=infinity
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now vmagent.service && sudo journalctl -feu vmagent.service

Systemd-Unit vmalert.service

$ cat <<EOF | sudo tee /etc/systemd/system/vmalert.service
[Unit]
Description=ViktoriaMetriks Alert
Documentation=https://victoriametrics.github.io/vmalert.html
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
Environment="VMUSERNAME="
Environment="VMPASSWORD="
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N:/victoria-metrics-data \
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="8880" \
  victoriametrics/vmalert:latest \
    -loggerFormat=json \
    -loggerLevel=INFO \
    -rule="/victoria-metrics-data/*.yml" \
    -datasource.url=http://vmstorage:8428 \
    -datasource.basicAuth.username=${VMUSERNAME} \
    -datasource.basicAuth.password=${VMPASSWORD} \
    -notifier.url=http://alertmanager:9093 \
    -remoteWrite.url=http://vmstorage:8428 \
    -remoteWrite.basicAuth.username=${VMUSERNAME} \
    -remoteWrite.basicAuth.password=${VMPASSWORD} \
    -remoteRead.url=http://vmstorage:8428 \
    -remoteRead.basicAuth.username=${VMUSERNAME} \
    -remoteRead.basicAuth.password=${VMPASSWORD} \
    -httpAuth.username="${VMUSERNAME}" \
    -httpAuth.password="${VMPASSWORD}" \
    -evaluationInterval=3s
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now vmalert.service && sudo journalctl -feu vmalert.service

Systemd-Unit .service (dummy)

$ cat <<EOF | sudo tee /etc/systemd/system/.service
[Unit]
Description=
Documentation=
Requires=docker.service
After=docker.service

[Service]
Environment="DOMAINNAME=onkeldom.eu"
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/mkdir /opt/docker-%N
ExecStartPre=-/usr/bin/docker network create --driver bridge --gateway 192.168.2.1 --subnet 192.168.2.0/26 --ip-range 192.168.2.0/26 proxy
ExecStart=/usr/bin/docker run --name=%N \
  --network proxy \
  --hostname %N \
  --volume /etc/localtime:/etc/localtime:ro \
  --volume /etc/timezone:/etc/timezone:ro \
  --volume /opt/docker-%N: \ # FIXME
  --env TZ="Europe/Berlin" \
  --label traefik.enable="true" \
  --label traefik.http.routers.%N-rtr.entrypoints="https" \
  --label traefik.http.routers.%N-rtr.rule="HostHeader(`%N.${DOMAINNAME}`)" \
  --label traefik.http.routers.%N-rtr.service="%N-svc" \
  --label traefik.http.services.%N-svc.loadbalancer.server.port="" \ # FIXME PORT
  :latest # FIXME IMAGE
ExecReload=/usr/bin/docker kill --signal=SIGHUP %N
ExecStop=/usr/bin/docker stop -t 2 %N ; /usr/bin/docker rm -f %N
SyslogIdentifier=%N

[Install]
WantedBy=multi-user.target
EOF

$ sudo systemctl enable --now .service && sudo journalctl -feu .service
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment