Install it · 6 of 8
On a platform you already run
The console and the webmail as one compose file, on Dokploy, Coolify, Portainer or plain Docker Compose, in front of an inbuxa server on another machine.
Who needs this: Anyone who already runs containers on a machine of their own, with a platform that puts a proxy and certificates in front of them, and wants the console and the webmail there rather than on the mail server.
On this page
The console and the webmail reach the mail server only over its HTTPS address, so they can run anywhere that reaches it. Keeping them off the mail host is the recommended arrangement.
If the machine can run the installer
inbuxa join does everything on this page in one run,
with Caddy in front. This page is for a machine where a platform already
owns ports 80 and 443 and runs the containers.
The examples use mail.example.com for the mail server, and
admin.example.com and webmail.example.com for the two front ends.
1. Tell the server where they are
The server only lets the console and the webmail sign people in, and only answers their browsers, at addresses it knows. Make a shared secret for the webmail:
openssl rand -base64 48
Set these in the server's environment, then restart the server:
INBUXA_ADMIN_URL=https://admin.example.com
INBUXA_WEBMAIL_URL=https://webmail.example.com
INBUXA_WEBMAIL_CLIENT_SECRET=<the shared secret>
The addresses must match the ones browsers will use exactly: no trailing slash, no path. From them the server registers both sign-ins and allows both origins. Without the secret it registers no webmail, and says so in its log.
Then exempt the platform machine from the server's automatic bans. Every webmail sign-in reaches the server from that machine's address, so one person's mistyped passwords could get it banned, and everyone with it. In the console, under Settings › Security › Allowed IPs, add the address the server sees the platform machine at.
2. The compose file
services:
console:
image: registry.coffeylabs.org/inbuxa/inbuxa-admin:latest
restart: unless-stopped
environment:
API_BASE_URL: https://mail.example.com
webmail:
image: registry.coffeylabs.org/inbuxa/inbuxa-webmail:latest
restart: unless-stopped
environment:
MAIL_SERVER_URL: https://mail.example.com
PUBLIC_URL: https://webmail.example.com
ADMIN_URL: https://admin.example.com
APP_NAME: inbuxa
APP_SECRET: ${APP_SECRET}
OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET}
volumes:
- webmail-data:/data
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
volumes:
webmail-data:
Set two secrets in the platform's environment for this application, not in the file:
APP_SECRET: a new random value, fromopenssl rand -base64 48. It seals the webmail's sessions.OAUTH_CLIENT_SECRET: the shared secret from step 1, the same value the server has.
Each container serves plain HTTP on port 8080 and publishes no port. The platform's proxy reaches them over its own network and adds TLS.
Which tag
Use the tag that matches the server. :latest goes with a 2026.x
server. A 27.1 release candidate, which is what a server moved from
Stalwart runs, takes :27.1-rc for both.
3. On your platform
- Dokploy or Coolify: make a Docker Compose application from the file.
Give the
consoleservice the hostnameadmin.example.comand thewebmailservicewebmail.example.com, both on port 8080, in the platform's domain settings. Their proxy gets and renews the certificates. - Portainer: make a stack from the file. Portainer has no proxy of its own, so put the one you already use in front of the two services. The console and webmail pages have nginx and Caddy examples.
- Plain Docker Compose: the same file, with
ports: ["127.0.0.1:8081:8080"]on the console andports: ["127.0.0.1:8082:8080"]on the webmail, and your reverse proxy in front of those.
Point the two hostnames at the platform machine in DNS. The mail server's own records don't change.
Replacing a webmail you run now
You can keep the hostname your people already use. Change the service's image to the one above, replace its environment with the variables above, and give it a new, empty volume. Keep the old service's volume until you're sure, rather than mounting it into the new one.
INBUXA_WEBMAIL_URL on the server must be that hostname. Everyone signs in
again once, because sessions don't carry over from another app.
Check it worked
https://admin.example.comshows the console's sign-in, and signing in lands on its dashboard. If it says Failed to fetch, the browser can't reachmail.example.com, or the server doesn't list the console's address: see the console's page.https://webmail.example.comsends you to the server's sign-in page and back. A sign-in that bounces straight back meansPUBLIC_URLandINBUXA_WEBMAIL_URLdon't agree.https://webmail.example.com/api/healthanswers"ok":true.
Updating
Change the tag, or pull :latest again, and redeploy. The console and the
webmail hold no mail, so updating them never touches the server's data.
Update them after the server, not before.