70 lines
5.6 KiB
Markdown
70 lines
5.6 KiB
Markdown
# Roundcube Webmail (Docker)
|
||
|
||
Docker-based Roundcube Webmail stack with config baked into a custom image and secrets supplied via environment variables. Suitable for deployment behind a reverse proxy (e.g. Traefik) with a private container registry and CI/CD.
|
||
|
||
## Architecture
|
||
|
||
- **Custom image**: Built from the official [Roundcube image](https://hub.docker.com/r/roundcube/roundcubemail). The Dockerfile copies this repo’s config files into the image; no config is mounted from the host at runtime.
|
||
- **Secrets and per-deployment values**: All sensitive and site-specific settings (DB credentials, session key, IMAP/SMTP hosts, plugin DSNs, etc.) are read from environment variables at runtime. The image is safe to push to a registry.
|
||
- **Stack**:
|
||
- **webmail**: Roundcube (custom image). Connects to MariaDB for Roundcube DB and, if using the password plugin, to a separate DB (e.g. Postfix/mailbox) via a Unix socket. Enigma plugin uses a named volume for GPG keys.
|
||
- **db**: MariaDB for Roundcube’s own database (user prefs, etc.).
|
||
- **Networks**: Internal `backend` (webmail ↔ db) and external `traefik` for the reverse proxy. The compose file assumes Traefik and a `traefik` network already exist.
|
||
|
||
## Repository layout
|
||
|
||
| Path | Purpose |
|
||
| ---------------------- | ------------------------------------------------------------------------------------------------- |
|
||
| `config/` | Main Roundcube config (`config.inc.php`, `config.smtp.inc.php`). Values are read from env in PHP. |
|
||
| `plugins/enigma/` | Enigma (PGP) plugin config. |
|
||
| `plugins/managesieve/` | Managesieve plugin config; host from env. |
|
||
| `plugins/password/` | Password-change plugin config; DB DSN built from env. |
|
||
| `docker-compose.yml` | Stack definition; webmail image points at the image produced by the build pipeline. |
|
||
| `Dockerfile` | Extends official Roundcube image and copies the config files above. |
|
||
| `.env.example` | Template for required and optional env vars (no secrets). |
|
||
|
||
## Environment variables
|
||
|
||
Copy `.env.example` to `.env` and set values. Required for a working stack:
|
||
|
||
- **Database (Roundcube)**: `DB_ROOT_PASSWORD`, `DB_PASSWORD`, `DB_NAME`, `DB_USER` (and thus `ROUNDCUBEMAIL_DB_*` used by the app).
|
||
- **IMAP/SMTP**: `ROUNDCUBEMAIL_DEFAULT_HOST`, `ROUNDCUBEMAIL_DEFAULT_PORT`, `ROUNDCUBEMAIL_SMTP_SERVER`, `ROUNDCUBEMAIL_SMTP_PORT`.
|
||
- **Session key**: `ROUNDCUBEMAIL_DES_KEY` — must be exactly 24 characters; used to encrypt stored IMAP passwords in the session.
|
||
|
||
Optional / plugin-related:
|
||
|
||
- `ROUNDCUBEMAIL_SUPPORT_URL`, `ROUNDCUBEMAIL_PLUGINS`, `ROUNDCUBEMAIL_UPLOAD_MAX_FILESIZE`.
|
||
- **Managesieve**: `ROUNDCUBEMAIL_MANAGESIEVE_HOST` (e.g. `tls://mail.example.com:4190`).
|
||
- **Password plugin**: `ROUNDCUBEMAIL_PASSWORD_DB_USER`, `ROUNDCUBEMAIL_PASSWORD_DB_PASSWORD`, `ROUNDCUBEMAIL_PASSWORD_DB_NAME` (DB used for mailbox password changes).
|
||
- **Image tag**: `IMAGE_TAG` (default `latest`) to pin the webmail image.
|
||
|
||
The webmail service expects the host’s MySQL socket at `/var/run/mysqld/mysqld.sock` for the password-plugin DB; adjust the volume mount if your socket path differs.
|
||
|
||
## Docker Compose and Traefik
|
||
|
||
- **Image**: The `webmail` service uses a single image tag (e.g. `your-registry/your-org/mail-roundcube:latest`). Set the image name in `docker-compose.yml` to match the image built and pushed by your CI.
|
||
- **Traefik labels**: The sample labels in `docker-compose.yml` are for TLS and host-based routing. Replace the `Host(...)` rules and any other host-specific labels with your own hostnames and middleware.
|
||
- **Volumes**: `roundcube-keys` is used by the Enigma plugin and is marked `external: true`; create it (or adjust) before first deploy. `temp` is for Roundcube temp files.
|
||
|
||
## CI/CD (Woodpecker)
|
||
|
||
Three pipelines:
|
||
|
||
1. **ci** — Lint and format (Prettier, yamllint). Runs on pull requests and pushes to the default branch.
|
||
2. **build** — Builds the Docker image and pushes it to your container registry. Depends on `ci`. Configure registry URL and repo name in the pipeline file and in `package.json` scripts if you use them locally.
|
||
3. **deploy** — Triggers a webhook (e.g. reverse-proxy or stack redeploy). Depends on `ci` and `build` so the new image is pushed before the webhook runs.
|
||
|
||
Required secrets (in your CI): registry login, webhook URL, and any notification tokens you use. Do not commit `.env` or real secrets; use CI secret storage.
|
||
|
||
## Local build and run
|
||
|
||
- **Build image**: From the repo root, run your usual Docker build (e.g. `docker build -t your-registry/your-org/mail-roundcube:latest .`). The `package.json` scripts are optional helpers; point them at your registry if desired.
|
||
- **Run stack**: Ensure `.env` is populated, create the external volume for Enigma if needed, then `docker compose up -d`. For the password plugin to work, the host must run MySQL/MariaDB and expose the socket at `/var/run/mysqld/mysqld.sock`, or you must change the webmail volume and plugin config accordingly.
|
||
|
||
## Security notes
|
||
|
||
- Never commit `.env` or any file containing real credentials. `.env.example` is a template only.
|
||
- The 24-character `ROUNDCUBEMAIL_DES_KEY` must be unique and kept secret; it encrypts session data.
|
||
- Keep registry and CI credentials in your CI secret store, not in the repo.
|
||
- Traefik labels in the repo are examples; replace hostnames and middleware names with your own before use.
|