CI / Lint de idioma (R9) (push) Successful in 4s
CI / Go (protocols) (push) Failing after 5s
CI / TypeScript (auth) (push) Failing after 6s
CI / TypeScript (storage) (push) Successful in 12s
CI / Build (webmail) (push) Successful in 1m38s
CI / Stack completa (push) Skipped
CI / Trivy (dependências, segredos e Dockerfiles) (push) Failing after 1m32s
CI / Imagem (auth) (push) Failing after 11s
CI / Imagem (migrations) (push) Failing after 11s
CI / Imagem (protocols) (push) Failing after 11s
CI / Imagem (rspamd) (push) Failing after 11s
CI / Imagem (storage) (push) Failing after 11s
CI / Imagem (webmail) (push) Failing after 11s
Release now pushes to git.lucasrguerra.dev.br instead of ghcr.io, tags each architecture separately (no artifact upload, no gha cache) and joins them with imagetools. GITHUB_OUTPUT and GITHUB_STEP_SUMMARY stay: they are the runner's own interface and the GITEA_* equivalents are not set. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
105 lines
4.8 KiB
Bash
105 lines
4.8 KiB
Bash
# LambdaMail - production environment
|
|
#
|
|
# Copy this into Coolify's environment editor, or to .env on the host, and
|
|
# replace every value marked CHANGE. The stack refuses to start without the
|
|
# required ones rather than falling back to a default, because a default
|
|
# secret in a published repository is not a secret.
|
|
#
|
|
# Generate each secret with: openssl rand -base64 36
|
|
# except POSTGRES_PASSWORD and REDIS_PASSWORD, which go inside connection URIs
|
|
# and must be URL-safe - see the note above them.
|
|
|
|
# --- Container images -------------------------------------------------------
|
|
# Published by .gitea/workflows/release.yml for linux/amd64 and linux/arm64.
|
|
# Pin IMAGE_TAG to a released version or a sha- tag to roll back.
|
|
IMAGE_NAMESPACE=git.lucasrguerra.dev.br/lucasrguerra/lambdamail
|
|
IMAGE_TAG=latest
|
|
|
|
# --- Identity ---------------------------------------------------------------
|
|
# MAIL_DOMAIN is the domain you send and receive as.
|
|
# PRIMARY_MAIL_HOST is the host the MX record points at; its PTR must match.
|
|
MAIL_DOMAIN=example.com # CHANGE
|
|
PRIMARY_MAIL_HOST=mail.example.com # CHANGE
|
|
WEBMAIL_HOST=mail.example.com # CHANGE - where the web UI is served
|
|
ADMIN_HOST= # optional separate host for /admin
|
|
PUBLIC_IPV4=203.0.113.10 # CHANGE - the VPS public IPv4
|
|
# Leave empty unless IPv6 has a matching PTR and is covered by SPF. Half
|
|
# configured IPv6 is a common cause of rejection (PLAN.md premises).
|
|
PUBLIC_IPV6=
|
|
|
|
# --- Secrets ----------------------------------------------------------------
|
|
# These two are substituted into connection URIs - postgres://user:PASS@db/... and
|
|
# redis://:PASS@redis:6379 - so they must contain no character that means
|
|
# something in a URL. Use hex:
|
|
#
|
|
# openssl rand -hex 24
|
|
#
|
|
# NOT `openssl rand -base64`, whose alphabet includes "/" and "+". A "/" ends
|
|
# the authority component, so the host is parsed as part of the password and
|
|
# every connection fails authentication - which surfaces as the migrations
|
|
# container exiting 1 while Postgres itself reports healthy.
|
|
POSTGRES_DB=lambdamail
|
|
POSTGRES_USER=lambdamail
|
|
POSTGRES_PASSWORD=CHANGE-generate-with-openssl-rand-hex-24
|
|
REDIS_PASSWORD=CHANGE-generate-with-openssl-rand-hex-24
|
|
# Signs webmail and admin sessions. Minimum 32 characters; the auth service
|
|
# refuses to start below that.
|
|
JWT_SECRET=CHANGE-generate-with-openssl-rand-at-least-32-chars
|
|
# Encrypts DKIM private keys, TOTP secrets and provider tokens at rest.
|
|
# LOSING THIS MAKES EVERY STORED SECRET UNRECOVERABLE - back it up separately
|
|
# from the database (PLAN.md risk R9).
|
|
LAMBDAMAIL_MASTER_KEY=CHANGE-generate-with-openssl-rand-at-least-32-chars
|
|
|
|
# --- DNS automation ---------------------------------------------------------
|
|
# Token scope: Zone.DNS:Edit plus Zone.Zone:Read on the zone. Leave empty to
|
|
# manage the 13 records by hand; the service then logs that sync is off.
|
|
CLOUDFLARE_API_TOKEN=
|
|
DNS_SYNC_INTERVAL_SECONDS=21600
|
|
|
|
# --- TLS --------------------------------------------------------------------
|
|
# traefik: read the certificate Coolify's proxy already manages (default).
|
|
# acme: obtain it here via DNS-01. Required for DANE, and only then.
|
|
TLS_MODE=traefik
|
|
COOLIFY_PROXY_DIR=/data/coolify/proxy
|
|
COOLIFY_PROXY_NETWORK=coolify
|
|
TRAEFIK_ACME_FILENAME=acme.json
|
|
CERT_POLL_INTERVAL_SECONDS=60
|
|
PROTOCOLS_SPOOL_DIR=/var/lambdamail/spool
|
|
# Used only when TLS_MODE=acme.
|
|
ACME_EMAIL=
|
|
ACME_DIRECTORY_URL=
|
|
|
|
# --- Transport security -----------------------------------------------------
|
|
# Start at testing. Promote to enforce only once TLS-RPT reports come back
|
|
# clean: enforce with a broken certificate silently blackholes inbound mail.
|
|
MTA_STS_MODE=testing
|
|
OUTBOUND_MTA_STS_ENABLED=true
|
|
# DANE stays off under TLS_MODE=traefik. The key changes at every renewal and
|
|
# the published TLSA record stops matching, which permanently rejects mail at
|
|
# every validating MTA (PLAN.md section 5.1).
|
|
OUTBOUND_DANE_ENABLED=false
|
|
DNSSEC_RESOLVER=1.1.1.1:53
|
|
MAX_MESSAGE_BYTES=52428800
|
|
ARC_SEAL_ENABLED=false
|
|
|
|
# --- Smarthost --------------------------------------------------------------
|
|
# Most VPS providers block outbound port 25. If the preflight reports it
|
|
# blocked, set a relay here; it is added to the published SPF automatically.
|
|
RELAY_HOST=
|
|
RELAY_PORT=587
|
|
RELAY_USER=
|
|
RELAY_PASS=
|
|
# The SPF term that authorises the relay, exactly as your provider documents
|
|
# it. Set this: it cannot be derived from RELAY_HOST, and getting it wrong is
|
|
# worse than leaving it out. Brevo's relay is smtp-relay.brevo.com, but
|
|
# brevo.com publishes the SPF of their corporate mail - the sending ranges are
|
|
# at spf.brevo.com, so the value here is "include:spf.brevo.com".
|
|
RELAY_SPF_INCLUDE=
|
|
|
|
# --- Storage ----------------------------------------------------------------
|
|
STORAGE_DRIVER=local
|
|
S3_ENDPOINT=
|
|
S3_BUCKET=
|
|
S3_ACCESS_KEY=
|
|
S3_SECRET_KEY=
|