Files
homelab-optimized/hosts/vms/matrix-ubuntu-vm/README.md
Gitea Mirror Bot 2be8f1fe17
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m1s
Documentation / Deploy to GitHub Pages (push) Has been skipped
Sanitized mirror from private repository - 2026-04-05 08:31:50 UTC
2026-04-05 08:31:50 +00:00

10 KiB

Ubuntu VM Homelab

Self-hosted communication platform with Mastodon, Mattermost, and Matrix/Element on a single Ubuntu VM sharing PostgreSQL.

Current Deployment Status

Service Status Domain Internal Port Nginx Port
Mastodon Running mastodon.vish.gg 3000, 4000 8082
Mattermost Running mm.crista.love 8065 8081
Matrix (mx.vish.gg) Running mx.vish.gg 8018 8082
Matrix (vish - legacy) Running matrix.thevish.io 8008 8081
PostgreSQL Running - 5432 -
Redis Running - 6379 -
TURN (coturn) Running mx.vish.gg:3479 3479 -

VM Specifications

  • OS: Ubuntu 24.04.4 LTS (x86_64)
  • Hostname: matrix-ubuntu
  • LAN IP: 192.168.0.154 (static) — ssh ubuntu-matrix
  • Tailscale IP: 100.85.21.51
  • SSH user: test
  • RAM: 7.7 GB
  • CPU: 4 cores
  • Storage: 96 GB
  • Network: Static IP set via netplan (/etc/netplan/99-static.yaml), cloud-init network management disabled

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    Cloudflare Proxy                          │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                         Nginx                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │ :8080       │  │ :8081       │  │ :8082       │          │
│  │ Matrix      │  │ Mattermost  │  │ Mastodon    │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
└─────────────────────────────────────────────────────────────┘
         │                   │                  │
         ▼                   ▼                  ▼
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Synapse    │     │ Mattermost  │     │  Mastodon   │
│  :8008      │     │   Docker    │     │   Docker    │
│  + Element  │     │   :8065     │     │   :3000     │
└─────────────┘     └─────────────┘     │   :4000     │
         │                   │          └─────────────┘
         │                   │                  │
         └───────────────────┴──────────────────┘
                              │
                              ▼
                    ┌─────────────────┐
                    │   PostgreSQL    │
                    │     :5432       │
                    │                 │
                    │  - synapse      │
                    │  - mattermost   │
                    │  - mastodon     │
                    └─────────────────┘

Databases

All services share the same PostgreSQL 16 server:

Database User Purpose
synapse synapse Matrix homeserver (vish - legacy)
synapse_mx synapse_mx Matrix homeserver (mx.vish.gg - federated)
mattermost mmuser Mattermost
mastodon_production mastodon Mastodon

Docker Containers

NAMES                  IMAGE                                        STATUS
mastodon-streaming-1   ghcr.io/mastodon/mastodon-streaming:v4.5.7   Up
mastodon-web-1         ghcr.io/mastodon/mastodon:v4.5.7             Up
mastodon-sidekiq-1     ghcr.io/mastodon/mastodon:v4.5.7             Up
mastodon-redis-1       redis:7-alpine                               Up
mattermost             mattermost/mattermost-team-edition:11.4      Up (healthy)

Systemd Services (bare-metal)

UNIT                SERVICE            VERSION
synapse.service     Synapse (legacy)   1.148.0  — /opt/synapse, port 8008
synapse-mx.service  Synapse (primary)  1.148.0  — /opt/synapse-mx, port 8018

Both Synapse instances share the venv at /opt/synapse/venv/.

Quick Start

  1. Clone this repo to your VM
  2. Copy environment templates and edit with your values
  3. Run the setup script
git clone https://git.vish.gg/Vish/Ubuntu-vm-homelab.git
cd Ubuntu-vm-homelab
./scripts/setup.sh

Directory Structure

Ubuntu-vm-homelab/
├── mastodon/
│   ├── docker-compose.yml
│   └── .env.production.template
├── mattermost/
│   ├── docker-compose.yml
│   └── config.json.template
├── matrix-element/
│   ├── homeserver.yaml.template
│   └── element-config.json.template
├── nginx/
│   ├── mastodon.conf
│   ├── mattermost.conf
│   └── matrix.conf
├── scripts/
│   ├── setup.sh
│   ├── backup.sh
│   └── update.sh
└── README.md

Credentials

Stored securely on the server:

  • /opt/mastodon/.env.production - Mastodon secrets
  • /opt/mattermost/config/config.json - Mattermost config
  • /opt/synapse/homeserver.yaml - Matrix config

Cloudflare Setup

Each service requires a DNS record pointing to the VM's public IP with Cloudflare proxy enabled. Configure origin rules to route to the correct nginx port.

Maintenance

Backup

./scripts/backup.sh

View Logs

# Mastodon
cd /opt/mastodon && docker compose logs -f

# Mattermost
docker logs -f mattermost

# Matrix (mx.vish.gg)
tail -f /opt/synapse-mx/homeserver.log

# Matrix (legacy vish)
tail -f /opt/synapse/homeserver.log

Updating Services

Update Mastodon

cd /opt/mastodon

# Pull latest images
docker compose pull

# Stop services
docker compose down

# Run database migrations
docker compose run --rm web bundle exec rails db:migrate

# Precompile assets (if needed)
docker compose run --rm web bundle exec rails assets:precompile

# Start services
docker compose up -d

# Verify
docker compose ps

Check for release notes: https://github.com/mastodon/mastodon/releases

Update Mattermost

cd /opt/mattermost

# Check current version
docker exec mattermost mattermost version

# Pull latest image
docker compose pull

# Stop and restart
docker compose down
docker compose up -d

# Verify
docker logs mattermost | head -20

Check for release notes: https://docs.mattermost.com/about/mattermost-server-releases.html

Update Matrix Synapse (both instances share the same venv)

Both instances use /opt/synapse/venv/ — upgrade once, restart both.

# Check current version
curl -s http://localhost:8018/_synapse/admin/v1/server_version

# Upgrade (pin to a specific version, e.g. 1.148.0)
sudo /opt/synapse/venv/bin/pip install 'matrix-synapse==1.148.0'

# Restart both services
sudo systemctl restart synapse synapse-mx

# Verify
curl -s http://localhost:8008/_synapse/admin/v1/server_version  # legacy
curl -s http://localhost:8018/_synapse/admin/v1/server_version  # mx

Check for release notes: https://github.com/element-hq/synapse/releases

Note: If startup fails with InsufficientPrivilege: must be owner of table, see the DB ownership fix in docs/MATRIX.md#db-ownership-fix.

Update Element Web

# Check latest version at https://github.com/element-hq/element-web/releases
ELEMENT_VERSION="v1.12.11"  # Change to latest version

# Download and extract
cd /tmp
wget https://github.com/element-hq/element-web/releases/download/${ELEMENT_VERSION}/element-${ELEMENT_VERSION}.tar.gz
tar -xzf element-${ELEMENT_VERSION}.tar.gz

# Backup current config
cp /opt/element/web/config.json /tmp/element-config-backup.json

# Back up configs
cp /opt/element/web/config.json /tmp/element-config-web.json
cp /opt/element/web-thevish/config.json /tmp/element-config-thevish.json

# Replace files (both installs share the same release)
sudo rm -rf /opt/element/web/* /opt/element/web-thevish/*
sudo cp -r element-${ELEMENT_VERSION}/* /opt/element/web/
sudo cp -r element-${ELEMENT_VERSION}/* /opt/element/web-thevish/

# Restore configs
sudo cp /tmp/element-config-web.json /opt/element/web/config.json
sudo cp /tmp/element-config-thevish.json /opt/element/web-thevish/config.json

# Verify (nginx serves static files, no restart needed)
cat /opt/element/web/version
cat /opt/element/web-thevish/version

# Cleanup
rm -rf /tmp/element-${ELEMENT_VERSION}* /tmp/element-config-*.json

Update TURN Server (coturn)

# Update via apt
sudo apt update
sudo apt upgrade coturn

# Restart
sudo systemctl restart coturn

# Verify
sudo systemctl status coturn

Update All Services (Quick Script)

#!/bin/bash
# Save as /opt/scripts/update-all.sh

echo "=== Updating Mastodon ==="
cd /opt/mastodon
docker compose pull
docker compose down
docker compose run --rm web bundle exec rails db:migrate
docker compose up -d

echo "=== Updating Mattermost ==="
cd /opt/mattermost
docker compose pull
docker compose down
docker compose up -d

echo "=== Updating Synapse ==="
cd /opt/synapse
source venv/bin/activate
pip install --upgrade matrix-synapse
pkill -f 'synapse.app.homeserver'
sleep 2
sudo -u synapse /opt/synapse/venv/bin/python -m synapse.app.homeserver \
  --config-path=/opt/synapse-mx/homeserver.yaml --daemonize
sudo -u synapse /opt/synapse/venv/bin/python -m synapse.app.homeserver \
  --config-path=/opt/synapse/homeserver.yaml --daemonize

echo "=== Updating System Packages ==="
sudo apt update && sudo apt upgrade -y

echo "=== Done! ==="

Federation Status

Service Protocol Federation
Matrix (mx.vish.gg) Matrix Enabled
Matrix (vish) Matrix Disabled (invalid server_name)
Mastodon ActivityPub Enabled
Mattermost Shared Channels Enterprise only

License

MIT