Getting Started
Install Zimphony Webmail
Install the Zimphony Docker package with a clear two-container architecture, safe environment handling, startup checks, and first-run directory sync.
Overview
Zimphony Webmail is installed as a Docker Compose package around an existing Zimbra environment. Zimbra remains the mail backend. Zimphony provides the Webmail and Domain Admin Portal layer.
This public guide uses placeholders only. Replace them on the installation host, not in Git, screenshots, support tickets, or public documentation.
[APP_HOST]
[PRIMARY_DOMAIN]
[ADMIN_EMAIL]
[LICENSE_SERVER_URL]
[REDACTED]Supported deployment architecture
The canonical Zimphony Docker package runs exactly 2 containers:
frontend:3000backend:8000
The frontend serves both / and /admin. API traffic is routed to the backend. There is no separate admin-frontend container.
Browser
|
v
Frontend :3000
|
+--> / and /admin
+--> /api/*
+--> /api/admin/* → Backend :8000A reverse proxy such as Nginx or Caddy can terminate HTTPS and route public requests to the local Docker services. Keep the public examples generic and use [APP_HOST] when documenting a customer installation.
Prerequisites
- A 64-bit Linux host capable of running Docker Engine and the Docker Compose plugin.
- DNS and HTTPS planning for
https://[APP_HOST]/. - Network access from the Zimphony backend to the existing Zimbra SOAP endpoints.
- A reverse proxy such as Nginx or Caddy for public HTTPS access.
- Host-side environment files or Docker secrets for credentials and deployment settings.
- For paid editions, a license key and license check signing secret delivered through the approved license flow.
04 Install Docker Engine
For Ubuntu 22.04, install Docker Engine from the official Docker repository. Review the official Docker Ubuntu installation guide before running commands on a production host.
sudo apt-get update sudo apt-get install -y ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io05 Install Docker Compose plugin
Docker Compose v2 uses the
docker composecommand. Install the Compose plugin from the same official Docker repository.sudo apt-get update sudo apt-get install -y docker-compose-plugin docker compose version06 Prepare the package
Create a release directory on the host, extract the supplied Zimphony package there, and work from that package directory. Keep the original package archive and any provided SHA256 checksum available for upgrade and rollback review.
sudo mkdir -p /opt/zimphony-webmail cd /opt/zimphony-webmail sudo unzip /path/to/zimphony-webmail-[REDACTED].zip cd zimphony-webmail-[REDACTED]Do not rename a release directory in a way that hides which package is installed. Do not copy secrets into the Docker image, frontend bundle, or Git repository.
07 Configure environment safely
Environment files and Docker secrets must stay on the host and in backend-only runtime configuration. Secrets must not be baked into images, committed to Git, copied into
frontend.env, or exposed to the browser/client bundle.Examples of sensitive backend-only values include
LICENSE_CHECK_SIGNING_SECRET,ZIMPHONY_LICENSE_KEY, Zimbra credentials, and database settings.APP_HOST=[APP_HOST] PRIMARY_DOMAIN=[PRIMARY_DOMAIN] ADMIN_EMAIL=[ADMIN_EMAIL] LICENSE_SERVER_URL=[LICENSE_SERVER_URL] LICENSE_CHECK_SIGNING_SECRET=[REDACTED] ZIMPHONY_LICENSE_KEY=[REDACTED] ZIMBRA_ADMIN_EMAIL=[ADMIN_EMAIL] ZIMBRA_ADMIN_PASSWORD=[REDACTED] DATABASE_URL=[REDACTED]Use
[REDACTED]in documentation. Do not use masked strings such as********copied from a real credential field, because they can be mistaken for evidence of a real secret.08 Start the package
Validate the Compose file, start the package, and inspect the running services.
docker compose config --services docker compose up -d docker compose psThe service list should include:
backend frontendThe service list should not include:
admin-frontend09 First-run initialization
After the containers are running, complete the first-run checks before handing the installation to users. Confirm the frontend, backend health endpoint, Domain Admin Portal route, license state for paid editions, and Zimbra connectivity.
For Domain Admin Portal access, open
https://[APP_HOST]/adminand then continue to Enable Domain Admin Access for the intended administrative mailbox.10 GAL/directory initial sync
Autocomplete uses a local GAL snapshot. Run the initial directory sync after the first installation so the backend can build the first local snapshot.
docker compose exec backend zimphony-directory-syncThe sync reads users and distribution lists, then creates or updates the local snapshot atomically. If a sync fails, Zimphony keeps the last-known-good snapshot. Public logs and documentation should show only numeric summaries, not customer directory dumps.
Expected summary shape:
status=success users=<number> distribution_lists=<number> duration_ms=<number>The regular schedule is
02:00and12:00in the installation timezone.- Directory sync does not run on login.
- Directory sync does not run merely because Compose starts.
- Directory sync does not run on every autocomplete keystroke.
- Autocomplete searches the local snapshot.
11 Health checks
When local access to the Docker host is available, check the frontend and backend directly:
curl -fsS http://127.0.0.1:3000/ curl -fsS http://127.0.0.1:8000/healthIf local access is not available, use the public HTTPS host for the installation:
https://[APP_HOST]/ https://[APP_HOST]/adminDo not replace these placeholders with a real customer URL in public documentation.
12 Admin and Webmail access
https://[APP_HOST]/opens Zimphony Webmail through the frontend container.https://[APP_HOST]/adminopens the Domain Admin Portal through the same frontend container./api/*and/api/admin/*must route to the backend container.
Domain Admin Portal is domain-scoped. It is not a customer self-service license portal and it must not expose secrets or deployment-wide tenant data to the wrong context.
13 Upgrade procedure
- Back up the database, backend data, Docker volumes, and host environment files.
- Verify the new artifact SHA256 checksum against the supplied release information.
- Extract the new package into a new release directory.
- Preserve customer environment files and data; do not copy secrets into Git or images.
- Validate the Compose service list.
- Start the updated backend and frontend.
- Verify local health checks.
- Verify
https://[APP_HOST]/adminandhttps://[APP_HOST]/.
# From the new package directory, after backup and SHA256 verification: docker compose config --services docker compose up -d --build backend frontend docker compose ps14 Rollback
Rollback by returning to the previous package directory while preserving the same customer volumes, database, and environment files unless the release notes instruct otherwise.
# From the previous package directory: docker compose up -d docker compose psDo not use these commands as a rollback shortcut:
docker compose down -v docker system prune -a docker volume prune
Troubleshooting
Use sanitized checks only. Do not paste real customer logs, hostnames, domains, mailbox lists, message bodies, credentials, or license values into public documentation.
| Symptom | Likely cause | Safe check |
|---|---|---|
| Frontend does not load | Frontend container is stopped, reverse proxy is misrouted, or port 3000 is unavailable. | Run docker compose ps, check sanitized frontend logs, then test http://127.0.0.1:3000/. |
| Backend health check fails | Backend container is stopped, environment is incomplete, or a dependency is unavailable. | Run docker compose ps, check sanitized backend logs, then test http://127.0.0.1:8000/health. |
| /admin keeps loading | The /admin path is not reaching the frontend or /api/admin/* is not reaching the backend. | Confirm the proxy routes /admin to frontend:3000 and /api/admin/* to backend:8000. |
| License unavailable | License environment is missing, the license server URL is unreachable, or backend-only credentials are not loaded. | Verify backend env keys are present with redacted values only, then check sanitized backend logs. |
| Mailbox provider unavailable | Zimbra SOAP connectivity, hostname, TLS, or credentials need review. | Check configured placeholders on the host, test network reachability, and avoid pasting mailbox data into logs or tickets. |
| GAL autocomplete is empty | The first GAL snapshot has not been created or the last sync failed. | Run docker compose ps, check sanitized logs, run the initial sync again, and verify numeric users/DL counts. |
| GAL sync command fails | Backend is not running, credentials are incomplete, or Zimbra directory access failed. | Run docker compose ps, rerun docker compose exec backend zimphony-directory-sync, and keep only numeric summary output. |
| Thai autocomplete does not find entries | Directory data or search normalization needs review. | Confirm the GAL sync completed and compare sanitized numeric counts, not customer mailbox lists. |
| Signature image send fails | The upload, storage, or send path needs review. | Check sanitized backend logs and confirm no credential, domain, or message body is copied into public documentation. |
| Windows-874 Thai displays incorrectly | Thai MIME decoding needs compatibility handling. | Confirm the message path supports windows-874, cp874, and tis-620 without exposing a real customer email body. |
Security checklist
- Use placeholders in public documentation:
[APP_HOST],[PRIMARY_DOMAIN],[ADMIN_EMAIL],[LICENSE_SERVER_URL], and[REDACTED]. - Keep
LICENSE_CHECK_SIGNING_SECRET,ZIMPHONY_LICENSE_KEY, Zimbra credentials, and database settings on the host/backend side only. - Do not place secrets in
frontend.env, Docker images, Git, public documentation, or browser/client bundles. - Do not disclose customer hostnames, customer IP addresses, internal Zimbra hostnames, PMG IP addresses, Redis endpoints, admin API keys, license secrets, or customer-identifying database paths.
- Do not add private migration runbooks or private mail-security operational details to this public page.
- Keep rollback backups available before upgrade work begins.
- Review logs before sharing them and remove customer data, credentials, domains, mailbox lists, and message bodies.
