9.8 KiB
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
- 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 and with docker compose plugin. You may want to follow the post installation instructions.
At least 6 cores with 16GB RAM 100GB SSD would be sufficent.
Diagnostics
Run the unified diagnostics script from the repository root:
./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
- 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
-
Set your env variables in
./core/.env,./drupal/.env,./forgejo/.env,./hedgedoc/.env,./onlyoffice/.env,./nextcloud/.env,./openproject/.env. -
Generate mailcow config
cd mailcow
./geneare_config.bash
- Copy config to .env
cp mailcow.conf .env
- Create infrastructure via script:
./create_infra.bash
Core environment
- Start traefik, mariadb, postgres and adminer with:
docker compose -f core/docker-compose.yml up -d
Drupal + Next.js
- Set your env variables in
drupal/.envandnextjs/.env.local. - Start the stack (NGINX, Drupal PHP-FPM, Redis and the Next.js frontend).
docker compose -f drupal/docker-compose.yml up -d
Additional steps
You may want to use Redis Caching.
- add to drupal/sites/default/settings.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';
- 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.
- Start Forgejo.
docker compose -f forgejo/docker-compose.yml up -d
- Create the first admin user (headless install is enabled, so skip the web installer).
docker exec -u 1000 forgejo forgejo admin user create \
--admin --username <you> --email <you@domain> --random-password
- Visit
https://git.${DOMAIN}and log in. Add your SSH key under Settings → SSH/GPG Keys. Clone URLs usegit@git.${DOMAIN}:<owner>/<repo>.giton SSH port 2424.
CI runner (Forgejo Actions)
- Generate a registration token and put it in
forgejo-runner/.env:
docker exec -u 1000 forgejo forgejo actions generate-runner-token
- Start the runner (registers automatically on first boot; CI jobs run in an isolated Docker-in-Docker engine).
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
- Start containers.
docker compose -f hedgedoc/docker-compose.yml up -d
- Add your user.
source hedgedoc/.env
docker exec hedgedoc bin/manage_users --pass ${HEDGEDOC_USER_PASSWORD} --add ${HEDGEDOC_USER_EMAIL}
Mailcow
- Start containers.
cd mailcow && docker compose up -d
-
Visit DOMAIN/admin and log in with admin:admin.
-
Consider the post installation steps, i. e.
watchdog dmarc dkim (You get your dkim key when you registered your email domain in mailcow ui)
OnylOffice
- Start containers.
docker compose -f onlyoffice/docker-compose.yml up -d
Nextcloud
- Start OnlyOffice first!
- Start containers.
docker compose -f nextcloud/docker-compose.yml up -d
- 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:
- Install Nextcloud Office app from Apps menu.
- Go to Settings → Administration → Office.
- Select "Use your own server" and enter:
https://office.yourdomain.com. - Configure WOPI allowlist with Collabora's IP:
# 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
- Start containers.
docker compose -f openproject/docker-compose.yml up -d
- 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
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
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):
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:
sudo bash scripts/secure-ssh-vpn.sh --mail-vpn-only
Local client setup
Linux
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
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, 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
# 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-knownURLs, failed on:/.well-known/webfingerFor more details see the documentation ↗.