The Complete Self-Hosting Stack: 15 Tools for a Full SaaS Replacement
The Complete Self-Hosting Stack: 15 Tools for a Full SaaS Replacement
What if you could replace Slack, Notion, Jira, Google Analytics, Mailchimp, Auth0, Calendly, Zendesk, and more — all self-hosted on a single server for under $50/month?
Here's the complete stack, what it replaces, and what you'll save.
The Stack
| # | Tool | Replaces | Saved/month |
|---|---|---|---|
| 1 | Mattermost | Slack | $8.75/user |
| 2 | Outline | Notion / Confluence | $10/user |
| 3 | Plane | Jira / Linear | $8/user |
| 4 | Plausible | Google Analytics 360 | $150+ |
| 5 | Listmonk | Mailchimp | $20-300 |
| 6 | Keycloak | Auth0 / Okta | $23+/1K MAU |
| 7 | Cal.com | Calendly | $12/user |
| 8 | Chatwoot | Intercom / Zendesk | $39/agent |
| 9 | Nextcloud | Google Workspace / Dropbox | $12/user |
| 10 | n8n | Zapier | $20-100 |
| 11 | Uptime Kuma | Better Stack / Pingdom | $25+ |
| 12 | Vaultwarden | 1Password Teams | $4/user |
| 13 | Gitea | GitHub (private repos) | $4/user |
| 14 | Metabase | Looker / Power BI | $30/user |
| 15 | Coolify | Vercel / Heroku | $20/user |
For a 20-person team: SaaS costs ~$6,000/month. Self-hosted costs ~$30-80/month in server costs.
Server Architecture
Option A: Single Server (1-25 users)
One powerful VPS runs everything:
Hetzner CX41: 8 vCPU, 16 GB RAM, 160 GB disk — €16/month
Option B: Two Servers (25-100 users)
Split by resource needs:
Server 1 (Apps): 8 vCPU, 16 GB RAM — €16/month
Mattermost, Outline, Plane, Cal.com, Chatwoot, n8n
Server 2 (Data): 4 vCPU, 8 GB RAM — €8/month
PostgreSQL, Keycloak, Metabase, Plausible, Listmonk
Option C: Three Servers (100+ users)
Server 1 (Frontend): 8 vCPU, 16 GB — €16/month
Mattermost, Outline, Plane, Nextcloud
Server 2 (Backend): 8 vCPU, 16 GB — €16/month
Keycloak, Chatwoot, n8n, Metabase
Server 3 (Database): 4 vCPU, 16 GB — €16/month
PostgreSQL, Redis, MinIO
Deployment Order
Install tools in this order for the smoothest setup:
Phase 1: Foundation (Day 1)
1. Coolify — Deploy Coolify first. Then use it to deploy everything else.
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
2. Keycloak — Set up authentication before other apps. All tools will use Keycloak for SSO.
3. Uptime Kuma — Monitor everything you deploy from this point forward.
Phase 2: Communication (Day 2)
4. Mattermost — Team chat. Connect to Keycloak for SSO.
5. Cal.com — Scheduling. Connect calendars.
6. Chatwoot — Customer support. Add live chat widget to your site.
Phase 3: Productivity (Day 3)
7. Outline — Knowledge base. Import from Notion/Confluence. Connect to Keycloak.
8. Plane — Project management. Import from Jira if applicable.
9. Nextcloud — File storage, calendar, contacts. Replace Google Workspace.
Phase 4: Data & Marketing (Day 4)
10. Plausible — Analytics. Add tracking script to all sites.
11. Listmonk — Email newsletter. Set up SMTP, import subscribers.
12. Metabase — Business intelligence. Connect to your databases.
Phase 5: Infrastructure (Day 5)
13. n8n — Workflow automation. Connect your tools together.
14. Vaultwarden — Password management. Import from 1Password/LastPass.
15. Gitea — Git hosting. Mirror from GitHub or start fresh.
Shared Infrastructure
Single PostgreSQL for All Tools
Instead of each tool running its own PostgreSQL, use one shared instance:
# Shared PostgreSQL
services:
postgres:
image: postgres:16-alpine
container_name: shared-postgres
restart: unless-stopped
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=your-root-password
Create databases for each tool:
CREATE DATABASE mattermost;
CREATE DATABASE outline;
CREATE DATABASE plane;
CREATE DATABASE keycloak;
CREATE DATABASE chatwoot;
CREATE DATABASE calcom;
CREATE DATABASE plausible;
CREATE DATABASE listmonk;
CREATE DATABASE metabase;
CREATE DATABASE n8n;
CREATE DATABASE gitea;
-- Create dedicated users for each
CREATE USER mm_user WITH PASSWORD 'password1';
GRANT ALL ON DATABASE mattermost TO mm_user;
-- Repeat for each tool...
Shared Redis
redis:
image: redis:7-alpine
container_name: shared-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
Shared SMTP Configuration
Use one SMTP provider for all tools:
| Provider | Cost for 50K emails/month |
|---|---|
| Amazon SES | $5 |
| Resend | $20 |
| Brevo | Free (300/day limit) |
Single Reverse Proxy (Caddy)
# /etc/caddy/Caddyfile
# Infrastructure
auth.company.com { reverse_proxy localhost:8080 } # Keycloak
status.company.com { reverse_proxy localhost:3001 } # Uptime Kuma
deploy.company.com { reverse_proxy localhost:8000 } # Coolify
# Communication
chat.company.com { reverse_proxy localhost:8065 } # Mattermost
cal.company.com { reverse_proxy localhost:3000 } # Cal.com
support.company.com { reverse_proxy localhost:3000 } # Chatwoot (different port)
# Productivity
wiki.company.com { reverse_proxy localhost:3000 } # Outline
pm.company.com { reverse_proxy localhost:3000 } # Plane
cloud.company.com { reverse_proxy localhost:8080 } # Nextcloud
# Data
analytics.company.com { reverse_proxy localhost:8000 } # Plausible
mail.company.com { reverse_proxy localhost:9000 } # Listmonk
bi.company.com { reverse_proxy localhost:3000 } # Metabase
# Infrastructure
auto.company.com { reverse_proxy localhost:5678 } # n8n
vault.company.com { reverse_proxy localhost:8080 } # Vaultwarden
git.company.com { reverse_proxy localhost:3000 } # Gitea
Note: When multiple tools use the same internal port (e.g., 3000), remap them in Docker to unique host ports.
SSO with Keycloak
Connect all tools to Keycloak for single sign-on:
| Tool | Auth Method |
|---|---|
| Mattermost | OIDC (built-in) |
| Outline | OIDC (required) |
| Plane | OIDC (built-in) |
| Nextcloud | OIDC (app) |
| Chatwoot | OIDC (built-in) |
| n8n | OIDC (built-in) |
| Gitea | OIDC (built-in) |
| Metabase | SAML (built-in) |
| Grafana | OIDC (built-in) |
One login, all tools. Users sign in once through Keycloak.
Backup Strategy
Daily automated backups:
#!/bin/bash
# backup-all.sh — run via cron daily
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backups/$DATE"
mkdir -p $BACKUP_DIR
# PostgreSQL (all databases)
docker exec shared-postgres pg_dumpall -U postgres > $BACKUP_DIR/all-databases.sql
# File storage
tar czf $BACKUP_DIR/nextcloud.tar.gz /data/nextcloud
tar czf $BACKUP_DIR/mattermost.tar.gz /data/mattermost
tar czf $BACKUP_DIR/vaultwarden.tar.gz /data/vaultwarden
# Upload to S3
rclone copy $BACKUP_DIR s3:backups/$DATE/
# Retain 30 days
find /backups -maxdepth 1 -mtime +30 -exec rm -rf {} +
Cost Breakdown
Self-Hosted (20-person team)
| Item | Monthly Cost |
|---|---|
| Hetzner CX41 (main server) | €16 |
| Hetzner CX21 (backup server) | €4.50 |
| Domain | ~$1 |
| Amazon SES (email) | ~$5 |
| S3 backups (50 GB) | ~$1 |
| Total | ~$30/month |
SaaS Equivalent (20-person team)
| Service | Monthly Cost |
|---|---|
| Slack Pro | $175 |
| Notion Team | $200 |
| Jira Standard | $160 |
| Google Analytics 360 | $150 |
| Mailchimp Standard | $59 |
| Auth0 | $228 |
| Calendly Teams | $240 |
| Intercom | $780 |
| Google Workspace | $240 |
| Zapier Team | $200 |
| Better Stack | $100 |
| 1Password Teams | $80 |
| GitHub Team | $80 |
| Metabase Pro | $500 |
| Vercel Pro | $400 |
| Total | ~$3,592/month |
Annual savings: ~$42,744/year for a 20-person team.
Trade-Offs
What you gain:
- Full data ownership and privacy
- No vendor lock-in
- No per-user pricing that scales linearly
- Customizable and extensible
- Works offline / on private networks
What you trade:
- Initial setup time (~1 week for full stack)
- Ongoing maintenance (~2-4 hours/month)
- You're responsible for security updates
- No SaaS vendor support (community support instead)
- Need someone comfortable with Docker/Linux
The break-even point: Most teams break even within 1-3 months of switching.
Find open source alternatives for every SaaS tool on OSSAlt — features, self-hosting guides, and community health side by side.