2023-03-16 16:07:45 +01:00

141 lines
9.6 KiB
Markdown

---
sidebar_position: 1
---
KleckRelay requires a total of 3 services to run (this will probably change in future):
1. The database (a PostgreSQL database)
2. The server (the backend)
3. The maid (a cron job that cleans up content)
:::info
This guide assumes you are using Docker and Docker Compose.
:::
### Creating docker-compose.yml
We will use a separate `.env` file to store sensitive information. This will be shared by multiple services.
Here's an example, you will need to change at least the passwords and the domain name:
```bash
# The domain of the API
API_DOMAIN=api.app.krl
# The domain of the app (that's the actual website)
APP_DOMAIN=app.krl
# The domain where you will receive emails
MAIL_DOMAIN=mail.app.krl
# A randomly generated string, this is used to generate all kind of tokens
KLECK_SECRET=secret_change_me
# The URL of the database
DB_URI=postgresql://user:PASSWORD_1@kleckrelay_database/mail
# A private key used to sign content
SERVER_PRIVATE_KEY=LS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLQpWZXJzaW9uOiBPcGVuUEdQLmpzIHY0LjEwLjEwCkNvbW1lbnQ6IGh0dHBzOi8vb3BlbnBncGpzLm9yZwoKeGNMWUJHUEcyRmdCQ0FEVUVKVVpIYWtlS2ZxTEF6UU9tVTBBK1NuWFI2bUttbEttT2YwUzZDZVBka0VVCmtNUXJLUkFHOGxpT3FIU00ydGcyMW95T2xBQnFRSlJXSlhuSHBBcDMxVWRHTG1BQ3VVT3lVc3poYy83VgpYc1RTdWtCKzlIQ2dvQTFrTjJqbFVBK24xSGduOVRBdlV0bEhMMjZIYXNrcE95YlhTYWFFMUJVYVJRWngKNjRqd2J2ckU2RlV1Y0t4MmxUaG5KdGpyOHJyMEgwUkdYRFVSc21Zamc0ZEp3MFcrU2w1aVpYKzJZUzI2CityOTk1RDNwY2pienVxemZ0OW9QRnNwekNKS2pUdGJyUkpYRXg4bHNrR2J4ZUpaQVlzL2NDd1Bab05IRwo1eE1VR3dKNW9PZFl0dlB2VlBURnBwelU0QWMrTVdreHppTEE2TnJ4ZlYvcS9DVGFBQ2ozM3BmYkFCRUIKQUFFQUIvNHpFTmt1aHA5eVpZNXhDakR2Y1FnRGUzeVJYQzdkOHdLREI4VEMyRWVxZXNINk4xQWR5cElTCjhpblVGSW1ZWDV5Z08vTDE1SHJqR3pEOU82SURLcVBncm1tdTR6ejRldTlyMGhlSEZOMGhPV1J4RUN1Mgp4cHNXZXVRdXBVOHJwU2RYOVVpSDZybVRNOEtocXpEVkNDaHZ0dEJJR0hLeVdyWElNU1gzcWMyOGc3VEYKSW91dk1SeDdpV3F4ZmdtMUtXbWlpRm9mRFJFWkFsTDhXQU5zZUhmUkNCWkdqT0srdFZJVTJlM2dubHJZCnJRUm12U1k3ak0yMzJFOHFiMWZmQTk1SVlvTk51U2RFNzhkdllBaTEycWk1dHVLNTh5TTJNK1ByVVJnRwprN2NYdmxqcVVjTDVhK0l1UE9iWDN3aHdOcDJpMDhMMC85NjRjSkFwZk41Q1ZwNlZCQURvbGMwN3Vlb0gKZHd3cDhFaC9HRkt1UlRNL1dkQTZxRmZtczZrSTdjZG5STFVHTlhQaGZ5Q2c0Nk84VEZjUDhLQ01hNjhaCmhzV0ZBcHhhdkxpLzBEMkliSE1QTkwra3F0SFRCRmtkNFA1ZHA5a2lMTlh6UmtLdFE4akNQamk1M2w5bgp0SkJuTVhkY2NDRjQxZHNvWlFDRVBjdklkeUVZMk5Zc2oyRlZOUHFtM3dRQTZXbnRsOGJGdkQzQk1nb2oKMlVpMzQrK0taVVg1RndBd3pPcVQxQXFxeC9XZmNnbmV5Y1RqcTB0WEFDcmZYK2E3OWVKbDlsNVc5VVpDClJ2dnJFUkdiRm1HS3Uxb01HZ3lVNkNWYStDalZXTHoyLzVUL2FIWUlHZkU4QzlOZHhNOG1LcmdpQ29HRwpKZ29wZXFsYTFLZThjMzVjd05iQzFhdFcvVndoalczMDJvVUVBSldXRVg2VzYwV28vd2J3Szd1c1k5c2kKQjVkTjlWblpwSEF6Y0tZaGwwRGZaVUFRWlhwWnAzWHhHNmkzUkJobjFDQ25Yakh4cnBycVZrSUtxT3Q2CjFTOEJSRk1scFdRZ1JYVkU2Z2ZJMGY3SWZJZ01KLzVFK09kNW5JTUtncnB5c0xodjZ5alVEeGo5YksyWgpzeEF1M0FXNW8rUGprdlEyWmNQTUNsbUJXUzIzUXpUTkVXRWdQR0ZBWlhoaGJYQnNaUzVqYjIwK3dzQ04KQkJBQkNBQWdCUUpqeHRoWUJnc0pCd2dEQWdRVkNBb0NCQllDQVFBQ0dRRUNHd01DSGdFQUlRa1FENi9mCkpjb3djS2tXSVFUbXN0UWxSdm12SnRUa3hlTVByOThseWpCd3Flay9DQURRSDlNeUEzdWRuWGhWdm1DbAowa2E2aXRaWXA1R0lya2gvQmFHdWYva3MrVk55amZ6cm9jbUlnYmkvOWZPM3BWbzMwV3JWdlErb2xZV2IKYXIzc005SitGZUxiZ251Rm1HM2xtbGlZdU5RWlFZWEd4SWNtVXdQVDlDVXNKRGQ1YlV6bk9reXRNNmoxCmRkZWM2ODZEMm5IVktvbi9pRks0T3FsbUFSdHhrOW1SaTB3OUpDWTl0V0RrZ205R29GTzFROFNrZjRRNwo3U0syakplcktNUTNHSnplVXl0dEhXNEhLRUZZb1JRR3J2eGJ4UERQMXRLaXpaYS9GTlJCUEJJVHo0UWkKemdvdjRCZDRTZW1Tc0cyTVRDUVdFeUxaRUd6MVpMM0szd2xwbDFhb1JVVnpFRUhtYmJhVXBCclQyUzl5CnJqRHI0ZU03VHEwb29oRFlNMnZPYUhSQng4TFlCR1BHMkZnQkNBQ3d6TEs2eDdYbHRXOUFyUnVjeXBmNgpLTk1lWFNaR2tQcVc5VHVUMk9BZDl6K0hLVUYvYk45M0VuS1pSRTJaU3hPaEN6amtxT2hUbmVkMkp2dWcKNnc1R3N4VHZxVjBXYW9EV2hNU1A5MWd2Q1I3ajcvTURqQkFZSFI1YmREWGZzazljUVZTWDgwRE8zTEloCldPWm85amVOZ1NkMlRuUnREalZ1cXFod1VyZERQcHRTM0Jzb2E5VG1GNHNTN3pOdTNGVDZ1amNuUDd6TgpjbHZmcTBLZ0E5Z0s2b21VUDVNcWR6OTY3ci9BMnZ0cld0R3FicEJwaEZlbnZuNVNqMlV4eG1TYWRhQysKSnNUNGhWN0pncGZVclV6cE1XbkJQeEVLWjIrTGM1WFNaekxFenhjZ2cyMWxWVXJnTTdBZVpEaHNBMHVSCnc4WVVJbG4rWXZWVTk1TnJTaDNsQUJFQkFBRUFCLzBjZDFqdnFlZ25yQ2JWaXdtL0hQK0xUN2R1VkNFdAppM3BOZy82cnQyZWVhNGpYQWxXQlpzNDBKY3c5MFRtTlRRRkVGTUo4VHBYWm9McjcweHNBdGRmK21pYnMKejZBbFU5Q2F1WlhNZUU3Q2cvMXRSZDBpM1JKYVQ1WHJzN0pZNmlUTS9kZlkvMW1YOVFEWlRhOExoMWs2CmQya2JLMWFqbUg0UjYzaGpYVzRVYldONzBVbTkrY0tPSjhQRENxWGFlWXExdmllTGRnN3ZRZWEyc3dzWQpOaFJDU3E1OG1ubmh2ZnR5RWhwdkVpbGRROFhsL1RIVXZ3ZjM5TElHTXNhQjZCNlN3RnJtemhsTXJFNXAKTm1YVnQ0by83MmtGNEdQYlVVa0JtL2ZCWU4zdkhacXBwcFNZVlg5Y08wUHNaQW5IZGJ3aXFRUlBaamd1Cm1KK1VhMzl4WVdHaEJBREhEWXFSVkwrOHFLODhwUm43WjA5cFNGaHZ0ZEtJWU1xcGJ0ZkVFMGRTTnNGVwoybXVRTkMxTjk4aUJMdDFWTVpkbFgvZDNyeEdoSFFhWDRWTzJadkdXMUowRzdaZTk3TWNLcmVYcG16ZkQKdlpPM0VDMytGQWpZRG9oeEs4UlBKTEd2QjNBakwrcm9iTldsUlQ4YWt4UmVsZ0hPc1F4ZHNiMzhTUUR5Clh6Y21rd1FBNDJGWVkvOXphSmY5VVhkaHR6blZZaHRjbXNPVlVwS3MvSkV5S2p5K2pKemZPM29rKzN3RQpoMWlDaFRCeXJFR1lwYktkVmdNMXA5RGRUNUVrRll0bCtBT1hjZHB1em4vZGdHdDFmNHM3c3Vsa2ExVnMKY2x6cW5nUkZLb216eXBhMmYyZ0owbnZSYzY2eHNKczdleDQ3NUF1OTZsK0g3S2ZZY3pMbWJSdVV2S2NECi9qa05QYjdWdTJFak5GaWs1eHBsckUvalFMU3VXSGQzOFNNeTN3blRHeDJ3WFlmUERIa1llUDJZZ1NqcQpxd1dod21jRWdSMFBYY3N6RGFZMGhlTnFlWU1xQkZpMkNsaCtSQVNKQ1Y3aDFlNER5cnE4cGFIR01ZRGkKc0srcmJsL2pMa2x6ZFBNU2tuck54QUp6UXN6OEZjekpWaEcwRTNSMjRJUll4NWZkb3Rmc1FjN0N3SFlFCkdBRUlBQWtGQW1QRzJGZ0NHd3dBSVFrUUQ2L2ZKY293Y0trV0lRVG1zdFFsUnZtdkp0VGt4ZU1Qcjk4bAp5akJ3cVdkTUIvOVNKZGt5am9PVEdNVFRhOUJaNk0vOCt6RzFIS2FNRTVjQyt4b3F4OG5MUUpBTy9KV0oKMDB4SDkxcW03N0F0WnhyMUpIK2x0c2RrRERoUXMrZHdISWpVV1haTjd3SnNwREV6NGY2c2tRRWVySzVXCmhtSzJhdGdDMkQxRmVidnJuQjBMS2xDY2o4ZDQzZzREamxuaEVHNkFIenYwUWxBRHI1VlNGRTdkaSs5TgpBcHV6WDFxVWdXbUxxSHVMY3hUQkJtYUo4S09mTWhwNWdCVE9aU2w3elc5RTU3T3NHblVHRERPVWg2VDIKTFEzNGt4Wi93ZEt1ZzQrYWRGRFphODZVRk5KL0duR1BVak9kbkNYZXZHVzVieXU0RHhmalI1Zk93TENDCmJxVWFHeGgwd2cvL0x1Wkh3T0NidHFkb0YvRFNFeDFVU2pzY1l4WUllcE91QW94OUhiWDUKPWd3d0EKLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0K
# A private key for DKIM (used for signing emails), reduces your spam score
DKIM_PRIVATE_KEY=LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlDV3dJQkFBS0JnUUMvV3V5SWovWDAvMk1sdmVQQlVhai9KQXVIQzNCdlpwUWUrS1ZPTDBwdEF3RzZndm1kCkV6dmljL00zRGsxVzJtR3NLaFVpY0lSMHd1MVlpZEVCcGdWa0FFU2MxSE95TjAwbDJDbmhxQTZ2TU1Md0xlVkoKYVVDRmEwOU4xMUQ3TWVHbFdrdStXY1hNTEMva1B0TW5KNmo2YUZhbVFCbEZJdHJTSnk1dnN4VVV1UUlEQVFBQgpBb0dBUE5FTURoY2JCOFBIWWk1bzNYOHpvK3R6MG5iYlJEeW81UE1IcnNLdTk5aVZ5dzVuZ1BtazljTCtVTWcxCjRsM0QzekQ4eUpaVU1ydmxMVmVYMnR0R0tNYUlyRHBIQXd6N0NWYk0zK0ZsZzVYZy9McE1GRVJWNllUQkVkSysKQ01YNXJ1aUFVYnE5TDZ2Rk5WYkZVQkZxbWQ2UXY5YUl1Vm5vck1jaUhGQUZzeVVDUVFEaUUxSUJUbzgwT0VyaQpubHByN1I0R3grSEtwb054SWloejVDZ0NvSytDUWMxbzZCMmppaU1GYjRvdFNSOEpwUzhhbk05TG9ySStOa2NuCnJ6Z0Y0bG4vQWtFQTJLOFd6S285VFRlUFZsNE9uOVBIeEI4dTEvSklRWjBxcHkyMlpRZmNDZHNsbXN5bDB2SGcKSUtnZ05HKzFFc0svdjVwRnhvQjdQUUx6V09NMVBjdmhSd0pBSzljOVR0MlNMYmxBNUdONiszVDNIcStDWE04ZgpyRC9JZ25qYlBXODF1ZGZTNHFZb29UODNmV1ZjOFYwOXRKd2czMU5MYThwNE1GSk1TQ2pWZjJhZXR3SkFGQlE5CmY1K3k2SW5pZlhWZjA0MnpjRWdYZGlsY2FzQWVxTGxDc3FBRTB1RDgzaGhpc1daNmgyd3M5ODcyTDVQZVl1bnYKMTFJbW1XUEJteFlLNC93Vmx3SkFibDd1dUlJWDdmbFRuYTRlUHA0VWVoK3o2R0x1OFVsM1RQQU00MHl6MjVKSwpjUnFJZzZXRTRpRkF4U2h0MnpYemRrODg1T1lQRVJobGppL3RzeHp0Wnc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
# Whether admins should be able to change global settings through the web interface (we recommend to keep this enabled)
USE_GLOBAL_SETTINGS=yes
# A comma-separated list of admins (email addresses)
ADMINS=marvin@kleckrelay.example,sarah@kleckrelay.example
```
Here's an example `docker-compose.yml` file, you will need to change at least the passwords and the domain name.
This file assumes that you have these folders in the same directory as the `docker-compose.yml` file:
* `db` - To store database data
* `tutorial` - To store tutorial files (used to explain how to set up your DNS records)
* `opendkim_keys` - To store DKIM keys
* `certs` - To store SSL certificates
* `letsencrypt` - To store Let's Encrypt certificates
```yaml
version: '3'
services:
kleckrelay_database:
image: 'postgres:latest'
container_name: kleckrelay_database
restart: on-failure:5
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: PASSWORD_1
POSTGRES_DB: mail
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mail"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- ./db:/var/lib/postgresql/data
ports:
- "35432:5432"
kleckrelay_server:
image: myzel394/kleckrelay-server
container_name: kleckrelay_server
restart: on-failure:5
depends_on:
kleckrelay_database:
condition: service_healthy
cap_add:
- NET_BIND_SERVICE
- SYS_PTRACE
ports:
- "25:25"
- "587:587"
volumes:
- ./tutorial:/tutorial
- ./opendkim_keys:/etc/opendkim/keys
- ./certs:/etc/ssl/certs
env_file:
- .env
kleckrelay_maid:
image: myzel394/kleckrelay-maid
container_name: kleckrelay_maid
restart: on-failure
depends_on:
kleckrelay_database:
condition: service_healthy
env_file:
- .env
nginx:
container_name: nginx
image: bunkerity/bunkerweb
restart: on-failure:5
ports:
- 80:8080
- 443:8443
volumes:
# Change to your own path where you would like to store your HTTPS certificates and
#uncomment the line
- ./letsencrypt:/etc/letsencrypt
environment:
- MULTISITE=yes
# Specify your domains here (including subdomains)
- SERVER_NAME=api.kleckrelay.com
- USE_REVERSE_PROXY=yes
- DISABLE_DEFAULT_SERVER=yes
- AUTO_LETS_ENCRYPT=yes
# If you want to receive a notification when your certificates are not automatically
# renewed and will expire soon, enter an email here
# - EMAIL_LETS_ENCRYPT=
- USE_BAD_BEHAVIOR=no
- api.kleckrelay.com_REVERSE_PROXY_URL=/
- api.kleckrelay.com_REVERSE_PROXY_HOST=http://kleckrelay_server:80
- api.kleckrelay.com_ALLOWED_METHODS=GET|POST|PUT|PATCH|DELETE|OPTIONS
# Security is too strict
- api.kleckrelay.com_BLOCK_ABUSERS=no