# Written by the inbuxa installer {{.Version}} for {{.Domain}}. # # This is the whole deployment. Bring it up again with `docker compose up -d` # from this directory. Secrets are in .env beside it and the administrator's # password is in credentials.txt -- both readable only by root. # # The mail server's plain HTTP port is published on loopback only and reached # over the private network below, which is why the front ends talk to it as # http://: that leg never leaves this machine. name: {{.Project}} services: server: image: {{.ServerImage}} hostname: {{.MailHost}} restart: unless-stopped ports: - "{{.ServerBind}}:8080" {{- range .MailPorts}} - "{{.}}:{{.}}" {{- end}} volumes: - inbuxa-etc:/opt/stalwart/etc - inbuxa-data:/opt/stalwart/data {{- if .CABundle}} # The system roots plus the private ACME CA, so the server can reach it. - ./ca-bundle.crt:/etc/ssl/certs/ca-certificates.crt:ro {{- end}} environment: # The front ends, which is what registers their OAuth clients and sets # the cross-origin allowlist (contract C-6 and C-14). The webmail's # secret is generated by the installer and given to both sides. {{- if .ConsoleURL}} INBUXA_ADMIN_URL: {{.ConsoleURL}} {{- end}} {{- if .WebmailURL}} INBUXA_WEBMAIL_URL: {{.WebmailURL}} INBUXA_WEBMAIL_CLIENT_SECRET: ${WEBMAIL_CLIENT_SECRET:?WEBMAIL_CLIENT_SECRET is missing from .env} {{- end}} networks: stack: ipv4_address: {{.ServerIP}} {{- if .Console}} console: image: {{.ConsoleImage}} restart: unless-stopped depends_on: [server] # Not read-only, unlike the webmail: this image writes the api-base-url # into index.html when it starts, which is what lets one image serve any # installation. A read-only root makes it restart forever instead. tmpfs: [/tmp, /var/cache/nginx, /var/run] ports: - "{{.ConsoleBind}}:8080" environment: # Written into index.html at start, so one image serves any # installation. The browser talks to the server directly from here. API_BASE_URL: {{.ServerPublicURL}} networks: stack: ipv4_address: {{.ConsoleIP}} {{- end}} {{- if .Webmail}} webmail: image: {{.WebmailImage}} restart: unless-stopped depends_on: [server] # Immutable: read-only root, no volume, sessions in memory. A restart # signs everyone out; nothing else is lost, because nothing else is kept. read_only: true tmpfs: [/tmp] ports: - "{{.WebmailBind}}:8080" environment: MAIL_SERVER_URL: http://server:8080 APP_SECRET: ${APP_SECRET:?APP_SECRET is missing from .env} APP_NAME: inbuxa IMMUTABLE: "1" SESSION_FILE: "" TRUST_PROXY: "1" IMAGE_PROXY: "1" {{- if not .Local}} # Sign-in goes through the mail server's own page, as the first-party # client the server registered for this URL. OAUTH_CLIENT_ID: ihasmail-inbuxa OAUTH_CLIENT_SECRET: ${WEBMAIL_CLIENT_SECRET:?WEBMAIL_CLIENT_SECRET is missing from .env} PUBLIC_URL: {{.WebmailURL}} {{- if .ConsoleURL}} ADMIN_URL: {{.ConsoleURL}} {{- end}} # The server pushes changes here instead of holding a connection per # tab. If it cannot reach it, every tab falls back to the relay. PUSH_URL: {{.WebmailURL}} {{- end}} networks: stack: ipv4_address: {{.WebmailIP}} {{- end}} {{- if .Proxy}} caddy: image: {{.CaddyImage}} restart: unless-stopped depends_on: [server] ports: - "80:80" - "443:443" - "443:443/udp" volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - caddy-data:/data - caddy-config:/config {{- if .ACMECARoot}} - ./acme-ca-root.pem:/etc/caddy/acme-ca-root.pem:ro {{- end}} networks: stack: ipv4_address: {{.CaddyIP}} {{- end}} networks: stack: ipam: config: - subnet: {{.Subnet}} volumes: inbuxa-etc: inbuxa-data: {{- if .Proxy}} # Certificates and the ACME account. Losing this means asking for every # certificate again, which is how rate limits are reached. caddy-data: caddy-config: {{- end}}