job "trilium" { datacenters = ["dc1"] type = "service" constraint { attribute = "${node.unique.name}" value = "odroid7" } group "trilium" { count = 1 # Prestart restore task task "restore" { driver = "docker" lifecycle { hook = "prestart" sidecar = false } config { image = "litestream/litestream:latest" args = [ "restore", "-if-replica-exists", "-if-db-not-exists", "-o", "/alloc/tmp/trilium.db", "sftp://root:odroid@192.168.4.63/mnt/Shares/litestream/trilium.db" ] volumes = [ "/mnt/configs/trilium:/data" ] } } # Main trilium task task "trilium" { driver = "docker" config { image = "triliumnext/trilium:stable" force_pull = true # This ensures the image is always pulled memory_hard_limit = "2048" ports = ["http"] volumes = [ "/mnt/configs/trilium:/home/node/trilium-data/data", "/mnt/Public/configs/trilium/backup:/home/node/backup", "/mnt/Public/configs/trilium/config:/home/node/trilium-data/config" ] } env { TRILIUM_DATA_DIR="/home/node/trilium-data/data" TRILIUM_BACKUP_DIRxx="/home/node/backup" TRILIUM_CONFIG_INI_PATH="/home/node/trilium-data/config/config.ini" } resources { cpu = 100 memory = 128 } service { name = "trilium" tags = [ "trilium", "web", "urlprefix-/trilium", "tools", "traefik.http.routers.triliumlan.rule=Host(`trilium.service.dc1.consul`)", "traefik.http.routers.triliumwan.rule=Host(`tril.fbleagh.duckdns.org`)", "traefik.http.routers.triliumwan.middlewares=dex@consulcatalog", "traefik.http.routers.triliumwan.tls=true", ] port = "http" check { type = "tcp" interval = "10s" timeout = "2s" } } } #inside group "trilium" ...rsync sidecar to copy trilium native backup to public task "rsync-sidecar" { driver = "docker" lifecycle { hook = "poststart" sidecar = true } config { image = "alpine:latest" command = "/bin/sh" memory_hard_limit = "2048" args = [ "-c", # 1. Install rsync # 2. Enter infinite loop # 3. Rsync data -> backup # 4. Sleep 30 mins (1800 seconds) "apk add --no-cache rsync && while true; do echo '[Sidecar] Starting rsync...'; rsync -av --delete /data/ /backup/; echo '[Sidecar] Done. Sleeping 30m...'; sleep 1800; done" ] # Ensure these match the paths you want to sync volumes = [ "/mnt/configs/trilium:/data", # Source "/mnt/Public/configs/trilium/backup:/backup" # Destination ] } resources { cpu = 50 memory = 50 } } # Litestream sidecar for continuous replication task "litestream" { driver = "docker" lifecycle { hook = "poststart" # runs after main task starts sidecar = true } config { image = "litestream/litestream:latest" args = [ "replicate", "/data/document.db", "sftp://root:odroid@192.168.4.63/mnt/Shares/litestream/trilium.db" ] volumes = [ "/mnt/configs/trilium:/data" ] } } network { port "http" { static = 6699 to = 8080 } } } }