open-productive-stack/README.md
2026-06-26 09:34:11 +02:00

296 lines
9.8 KiB
Markdown

# Open Productive Stack
## Overview
This repository contains a productive stack of open-source applications for team collaboration and communication. The stack includes:
### Core Infrastructure
- **Traefik**: Edge router that handles routing, TLS (Let's Encrypt) and load balancing for all services
- **PostgreSQL**: Relational database for applications requiring PostgreSQL
- **MariaDB**: MySQL-compatible database for applications requiring MySQL
- **Adminer**: Database management tool for easy database administration
- **WireGuard**: VPN gateway; SSH is reachable only from within the VPN subnet
- **MTA-STS**: Static policy host for mail transport security
### Code Hosting & CI
- **Forgejo**: Self-hosted Git forge (replaces GitLab) at `git.${DOMAIN}`, SSH on port 2424
- **Forgejo Actions Runner**: CI runner with an isolated Docker-in-Docker engine for `.forgejo/workflows`
### Mail
- **Mailcow**: Complete mail server solution with SMTP, IMAP, antivirus, and webmail
### Collaboration Tools
- **Nextcloud**: Self-hosted file sync and share platform (with Collabora/Talk)
- **OnlyOffice**: Online office suite for document editing and collaboration
- **OpenProject**: Project management and team collaboration software
- **HedgeDoc**: Collaborative markdown notes editor for team documentation
### Web Publishing
- **Drupal**: Headless content management system (CMS), PHP-FPM + NGINX, Redis cache
- **Next.js**: Decoupled frontend (`${DOMAIN}`) consuming the Drupal backend
All components are containerized using Docker for easy deployment, scaling, and management, creating a complete productivity environment for teams.
## Requirements
You need [docker](https://docs.docker.com/get-started/get-docker/) and with [docker compose plugin](https://docs.docker.com/compose/). You may want to follow the [post installation instructions](https://docs.docker.com/engine/install/linux-postinstall/).
At least 6 cores with 16GB RAM 100GB SSD would be sufficent.
## Diagnostics
Run the unified diagnostics script from the repository root:
```bash
./diagnostic.sh
```
This combines the previous `diagnostic.sh` and `health_check.sh` checks.
## Mail Security
### Current Status
- ✅ SPF, DKIM, DMARC configured
- ✅ MTA-STS policy enforced (`https://mta-sts.nasarek.dev/.well-known/mta-sts.txt`)
- ✅ TLS-RPT configured
- ✅ TLS certificates valid on all mail ports
- ⚠️ DNSSEC: Enable at DNS provider and ensure DS/DNSKEY are published
- ⚠️ TLSA (DANE): Add records after DNSSEC is active (see `/var/deploy/scripts/README-TLSA.md`)
### TLSA Record Automation
Automated TLSA record updates are available. See `/var/deploy/scripts/README-TLSA.md` for setup instructions.
The automation monitors certificate changes and updates TLSA records automatically when certificates are renewed.
## Install
### Prerequisites
1) Copy the env and docker-compose.override.yml to the service directories via the script.
Add your specific settings in `set-config.sh`, then:
```
./copy_overrides.bash
```
2) Set your env variables in `./core/.env`, `./drupal/.env`, `./forgejo/.env`, `./hedgedoc/.env`, `./onlyoffice/.env`, `./nextcloud/.env`, `./openproject/.env`.
3) Generate mailcow config
```bash
cd mailcow
./geneare_config.bash
```
4) Copy config to .env
```bash
cp mailcow.conf .env
```
5) Create infrastructure via script:
```
./create_infra.bash
```
### Core environment
1) Start traefik, mariadb, postgres and adminer with:
```bash
docker compose -f core/docker-compose.yml up -d
```
### Drupal + Next.js
1) Set your env variables in `drupal/.env` and `nextjs/.env.local`.
2) Start the stack (NGINX, Drupal PHP-FPM, Redis and the Next.js frontend).
```bash
docker compose -f drupal/docker-compose.yml up -d
```
#### Additional steps
You may want to use Redis Caching.
1) add to drupal/sites/default/settings.php:
```php
// Redis Configuration
$settings['redis.connection']['interface'] = 'PhpRedis';
$settings['redis.connection']['host'] = 'redis';
$settings['redis.connection']['port'] = 6379;
$settings['cache']['default'] = 'cache.backend.redis';
$settings['cache']['bins']['bootstrap'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['discovery'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['config'] = 'cache.backend.chainedfast';
```
4) Visit your Domain and install Drupal site.
### Forgejo
Git forge (replaces GitLab). Uses the shared Postgres DB and Traefik. SSH is
served over the Traefik `forgejo-ssh` TCP entrypoint on port 2424.
1) Start Forgejo.
```bash
docker compose -f forgejo/docker-compose.yml up -d
```
2) Create the first admin user (headless install is enabled, so skip the web installer).
```bash
docker exec -u 1000 forgejo forgejo admin user create \
--admin --username <you> --email <you@domain> --random-password
```
3) Visit `https://git.${DOMAIN}` and log in. Add your SSH key under
*Settings → SSH/GPG Keys*. Clone URLs use `git@git.${DOMAIN}:<owner>/<repo>.git`
on SSH port 2424.
#### CI runner (Forgejo Actions)
1) Generate a registration token and put it in `forgejo-runner/.env`:
```bash
docker exec -u 1000 forgejo forgejo actions generate-runner-token
```
2) Start the runner (registers automatically on first boot; CI jobs run in
an isolated Docker-in-Docker engine).
```bash
docker compose -f forgejo-runner/docker-compose.yml up -d
```
Workflows live in each repo under `.forgejo/workflows/*.yml` (GitHub-Actions syntax).
#### Migrating from GitLab
A helper script migrates all GitLab projects (code, issues, MRs, labels,
milestones, releases, wiki). See `forgejo/migrate-from-gitlab.sh`.
### Hedgedoc
1) Start containers.
```bash
docker compose -f hedgedoc/docker-compose.yml up -d
```
2) Add your user.
```bash
source hedgedoc/.env
docker exec hedgedoc bin/manage_users --pass ${HEDGEDOC_USER_PASSWORD} --add ${HEDGEDOC_USER_EMAIL}
```
### Mailcow
1) Start containers.
```bash
cd mailcow && docker compose up -d
```
4) Visit DOMAIN/admin and log in with admin:admin.
5) Consider the post installation steps, i. e.
[watchdog](https://docs.mailcow.email/de/post_installation/firststeps-authorize_watchdog_and_bounces/)
[dmarc](https://docs.mailcow.email/de/post_installation/firststeps-dmarc_reporting/)
[dkim](https://docs.mailcow.email/getstarted/prerequisite-dns/) (You get your dkim key when you registered your email domain in mailcow ui)
### OnylOffice
1) Start containers.
```bash
docker compose -f onlyoffice/docker-compose.yml up -d
```
### Nextcloud
1) Start OnlyOffice first!
2) Start containers.
```bash
docker compose -f nextcloud/docker-compose.yml up -d
```
3) Visit nextcloud domain and login with your .env credentials.
#### Nextcloud Office with Collabora
Collabora container is included for document editing. Configure via Nextcloud admin panel:
1) Install **Nextcloud Office** app from Apps menu.
2) Go to **Settings****Administration****Office**.
3) Select **"Use your own server"** and enter: `https://office.yourdomain.com`.
4) Configure WOPI allowlist with Collabora's IP:
```bash
# Get Collabora IP.
docker inspect nextcloud-collabora --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
# Set allowlist.
docker exec -u www-data nextcloud php occ config:app:set richdocuments wopi_allowlist --value="COLLABORA_IP"
# Enable local servers.
docker exec -u www-data nextcloud php occ config:system:set allow_local_remote_servers --value=true --type=boolean
```
See `/var/deploy/nextcloud/COLLABORA-QUICK-SETUP.md` for details.
### Openproject
1) Start containers.
```bash
docker compose -f openproject/docker-compose.yml up -d
```
2) Visit openproject domain and login with admin:admin and set new password.
## SSH over VPN (WireGuard)
SSH access is secured behind a WireGuard VPN. Port 22 is only reachable from within the VPN subnet (`10.13.13.0/24`).
### Server-side setup
**1. Configure `core/.env`**
```env
WG_SERVERURL=your.server.hostname.or.ip
WG_PEERS=laptop,phone # or a number, e.g. "3"
TZ=Europe/Berlin
```
**2. Start the WireGuard container**
```bash
docker compose -f core/docker-compose.yml up -d wireguard
```
Peer configs and QR codes are generated automatically in:
```
core/volumes/wireguard/config/peer_<name>/
peer_<name>.conf ← import this on the client
peer_<name>.png ← scan this QR code on mobile
```
**3. Apply firewall rules**
Run *after* confirming the VPN works (see client setup below):
```bash
sudo bash scripts/secure-ssh-vpn.sh [--dry-run]
```
This opens ports 80, 443, 25, 465, 587, 143, 993, 4190, 2424, 51820 and restricts SSH to VPN clients only. To also restrict mail client ports (IMAP, submission) to VPN:
```bash
sudo bash scripts/secure-ssh-vpn.sh --mail-vpn-only
```
### Local client setup
#### Linux
```bash
sudo apt install wireguard
# Copy peer config from the server
scp user@your-server:/var/deploy/core/volumes/wireguard/config/peer_laptop/peer_laptop.conf \
~/.config/wireguard/wg0.conf
sudo wg-quick up wg0
# Connect on boot:
sudo systemctl enable wg-quick@wg0
```
#### macOS
```bash
brew install wireguard-tools
# Or use the App Store app: "WireGuard"
# Import peer_laptop.conf via File → Import Tunnel(s) from File
```
#### Windows
Download [WireGuard for Windows](https://www.wireguard.com/install/), then:
*Add Tunnel → Import tunnel(s) from file* → select `peer_laptop.conf`.
#### Android / iOS
Scan the QR code at `core/volumes/wireguard/config/peer_<name>/peer_<name>.png` with the WireGuard app.
### Verify the tunnel
```bash
# On the server — check connected peers
docker exec wireguard wg show
# From the client — SSH should work only after connecting to VPN
ssh user@10.13.13.1
```
## Roadmap
- Tweak the core components and subservices for petter performance.
- More automatisation when installing the environment.
- Add more services
- [ ] Matrix/Synapse + Element
- Fix all the Nextcloud errors
+ Your web server is not properly set up to resolve `.well-known` URLs, failed on: `/.well-known/webfinger` For more details see the documentation ↗.