diff --git a/.env.example b/.env.example index ed5bf50..3eb45cf 100644 --- a/.env.example +++ b/.env.example @@ -14,11 +14,13 @@ DATA_ROOT=/opt/eternitymail STALWART_SMTP_PORT=25 STALWART_SUBMISSION_PORT=587 STALWART_IMAPS_PORT=993 +# Leave empty to bind the Stalwart admin interface on all host interfaces. STALWART_ADMIN_BIND=127.0.0.1 STALWART_ADMIN_PORT=8081 STALWART_RECOVERY_ADMIN= # Roundcube port bindings +# Leave empty to bind Roundcube on all host interfaces. ROUNDCUBE_BIND=127.0.0.1 ROUNDCUBE_PORT=8091 diff --git a/.gitignore b/.gitignore index 4c49bd7..0efc5d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .env +tmp \ No newline at end of file diff --git a/README.md b/README.md index 4f38d4a..8cfda7a 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ The host bindings are configurable in `.env`: - SMTP: `STALWART_SMTP_PORT` (default `25`) - Submission: `STALWART_SUBMISSION_PORT` (default `587`) - IMAPS: `STALWART_IMAPS_PORT` (default `993`) -- Stalwart administration: `STALWART_ADMIN_BIND` and `STALWART_ADMIN_PORT` (defaults `127.0.0.1:8081`) -- Roundcube: `ROUNDCUBE_BIND` and `ROUNDCUBE_PORT` (defaults `127.0.0.1:8091`) +- Stalwart administration: `STALWART_ADMIN_BIND` and `STALWART_ADMIN_PORT` (defaults `127.0.0.1:8081`); set `STALWART_ADMIN_BIND=` to listen on all host interfaces +- Roundcube: `ROUNDCUBE_BIND` and `ROUNDCUBE_PORT` (defaults `127.0.0.1:8091`); set `ROUNDCUBE_BIND=` to listen on all host interfaces The Stalwart and Roundcube containers communicate over the private `eternitymail` Docker network. diff --git a/docker-compose.yml b/docker-compose.yml index 4dee341..124d3f7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,7 @@ services: - "${STALWART_SMTP_PORT:-25}:25/tcp" - "${STALWART_SUBMISSION_PORT:-587}:587/tcp" - "${STALWART_IMAPS_PORT:-993}:993/tcp" - - "${STALWART_ADMIN_BIND:-127.0.0.1}:${STALWART_ADMIN_PORT:-8081}:8080/tcp" + - "${STALWART_ADMIN_BIND-127.0.0.1}:${STALWART_ADMIN_PORT:-8081}:8080/tcp" volumes: - ${DATA_ROOT:-/opt/eternitymail}/stalwart/etc:/etc/stalwart @@ -74,7 +74,7 @@ services: condition: service_healthy ports: - - "${ROUNDCUBE_BIND:-127.0.0.1}:${ROUNDCUBE_PORT:-8091}:80" + - "${ROUNDCUBE_BIND-127.0.0.1}:${ROUNDCUBE_PORT:-8091}:80" volumes: - ${DATA_ROOT:-/opt/eternitymail}/roundcube-config:/var/roundcube/config:ro diff --git a/scripts/README.md b/scripts/README.md index 7c965f9..5d5c6c8 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -2,6 +2,52 @@ These scripts support the EternityMail Docker Compose deployment. Run them from the repository root. +## `install-stalwart-cli.sh` + +Installs the latest official `stalwart-cli` release on Linux. The upstream installer places the binary in the system executable path, normally `/usr/local/bin`. + +Requirements: + +- Linux +- `curl` +- `sudo`, unless the script is run as root + +Usage: + +```bash +chmod +x scripts/install-stalwart-cli.sh +./scripts/install-stalwart-cli.sh +``` + +Verify the installation with: + +```bash +stalwart-cli --version +``` + +## `install-stalwart-cli.ps1` + +Installs the latest official `stalwart-cli` release on Windows using the upstream PowerShell installer. The official installer uses a user-local executable directory and updates the user PATH. + +Requirements: + +- Windows PowerShell 5.1 or PowerShell 7+ +- Internet access to GitHub Releases + +Usage from PowerShell: + +```powershell +.\scripts\install-stalwart-cli.ps1 +``` + +Open a new terminal if the current shell cannot find the command, then verify it: + +```powershell +stalwart-cli --version +``` + +The scripts always download the current release from the official Stalwart CLI GitHub repository. Review the upstream release and installer before using them in a restricted or audited environment. + ## `generate-des-key.sh` Generates a random 24-character alphanumeric value for Roundcube's `RC_DES_KEY` setting. diff --git a/scripts/install-stalwart-cli.ps1 b/scripts/install-stalwart-cli.ps1 new file mode 100644 index 0000000..f08e5bf --- /dev/null +++ b/scripts/install-stalwart-cli.ps1 @@ -0,0 +1,21 @@ +[CmdletBinding()] +param() + +$ErrorActionPreference = 'Stop' +$installerUrl = 'https://github.com/stalwartlabs/cli/releases/latest/download/stalwart-cli-installer.ps1' +$tempFile = Join-Path ([System.IO.Path]::GetTempPath()) 'stalwart-cli-installer.ps1' + +try { + Invoke-WebRequest -Uri $installerUrl -OutFile $tempFile + & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $tempFile +} +finally { + Remove-Item -LiteralPath $tempFile -Force -ErrorAction SilentlyContinue +} + +if (Get-Command stalwart-cli -ErrorAction SilentlyContinue) { + stalwart-cli --version +} +else { + Write-Warning 'stalwart-cli was installed, but the current shell PATH does not include its install directory. Open a new terminal and run stalwart-cli --version.' +} diff --git a/scripts/install-stalwart-cli.sh b/scripts/install-stalwart-cli.sh new file mode 100644 index 0000000..dc713dd --- /dev/null +++ b/scripts/install-stalwart-cli.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +installer_url="https://github.com/stalwartlabs/cli/releases/latest/download/stalwart-cli-installer.sh" + +if ! command -v curl >/dev/null 2>&1; then + printf '%s\n' 'curl is required to install stalwart-cli.' >&2 + exit 1 +fi + +if [[ "${EUID}" -eq 0 ]]; then + curl --fail --silent --show-error --location --proto '=https' --tlsv1.2 "$installer_url" | sh +else + if ! command -v sudo >/dev/null 2>&1; then + printf '%s\n' 'Run this script as root or install sudo for a system-wide installation.' >&2 + exit 1 + fi + + curl --fail --silent --show-error --location --proto '=https' --tlsv1.2 "$installer_url" | sudo sh +fi + +command -v stalwart-cli >/dev/null 2>&1 && stalwart-cli --version