Below is a clean, end-to-end Markdown documentation covering everything you’ve done from start to finish, written so that:
- You (or anyone else) can reproduce the setup
- It can live in a README.md
- It reflects the final working state
- It clearly notes where SSL was intentionally skipped for admin
Domain: snap.co.ke
Homeserver: matrix.snap.co.ke
Web Client: chat.snap.co.ke
Admin UI: admin.chat.snap.co.ke (HTTP only)
This document describes the complete setup of a self-hosted Matrix stack, consisting of:
- Synapse (Matrix homeserver)
- Element Web (end-user web client)
- Synapse Admin UI (server administration dashboard)
- Google SSO (OIDC) for authentication
- Email verification for registrations
- Nginx as the reverse proxy and static file server
⚠️ Note: The Admin UI is intentionally served over HTTP only for now due to SSL/TLS configuration issues. This is acceptable for temporary/internal access, but HTTPS is recommended for production.
-
Ubuntu / Debian server
-
Root or sudo access
-
DNS records pointing to server IP:
matrix.snap.co.ke chat.snap.co.ke admin.chat.snap.co.ke -
Installed packages:
sudo apt update sudo apt install -y nginx git curl nodejs npm sudo npm install -g yarn
sudo apt install -y matrix-synapse-py3During installation:
- Set server name to:
matrix.snap.co.ke
File:
/etc/matrix-synapse/homeserver.yaml
Key settings enabled:
- Open registration with email verification
- SMTP email sending
- Google SSO (OIDC)
- Reverse-proxy support
enable_registration: true
enable_registration_without_verification: false
registrations_require_3pid:
- emailemail:
enable_notifs: true
smtp_host: smtp.gmail.com
smtp_port: 587
smtp_user: your-email@gmail.com
smtp_pass: APP_PASSWORD
require_transport_security: true
enable_tls: true
notif_from: "Matrix <your-email@gmail.com>"public_baseurl: "https://matrix.snap.co.ke/"oidc_providers:
- idp_id: google
idp_name: "Google"
issuer: "https://accounts.google.com"
client_id: GOOGLE_CLIENT_ID
client_secret: GOOGLE_CLIENT_SECRET
scopes: ["openid", "profile", "email"]
user_mapping_provider:
config:
localpart_template: "{{ user.email.split('@')[0] }}"
display_name_template: "{{ user.name }}"
allow_existing_users: truesudo register_new_matrix_user \
-c /etc/matrix-synapse/homeserver.yaml \
http://localhost:8008- Choose username (e.g.
superadmin) - Set Make admin: yes
File:
/etc/nginx/sites-available/matrix.snap.co.ke
server {
listen 80;
server_name matrix.snap.co.ke;
location /_matrix {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /_synapse/admin {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Enable and reload:
sudo ln -s /etc/nginx/sites-available/matrix.snap.co.ke /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxcd /opt
git clone https://github.com/element-hq/element-web.git
cd element-web
yarn install
yarn distDeploy:
sudo mkdir -p /var/www/element
sudo rsync -a dist/ /var/www/element/
sudo chown -R www-data:www-data /var/www/elementFile:
/var/www/element/config.json
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.snap.co.ke",
"server_name": "matrix.snap.co.ke"
}
},
"disable_custom_urls": true,
"disable_guests": true,
"brand": "Snap Chat"
}server {
listen 80;
server_name chat.snap.co.ke;
root /var/www/element;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}cd /opt
git clone https://github.com/Awesome-Technologies/synapse-admin.git
cd synapse-admin
yarn install
yarn buildOutput directory: dist/
Deploy:
sudo mkdir -p /var/www/synapse-admin
sudo rsync -a dist/ /var/www/synapse-admin/
sudo chown -R www-data:www-data /var/www/synapse-adminFile:
/var/www/synapse-admin/config.json
{
"restrictBaseUrl": "https://matrix.snap.co.ke"
}File:
/etc/nginx/sites-available/admin.chat
server {
listen 80;
server_name admin.chat.snap.co.ke;
root /var/www/synapse-admin;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location = /config.json {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;
try_files $uri =404;
}
}Enable:
sudo ln -s /etc/nginx/sites-available/admin.chat /etc/nginx/sites-enabled/admin.chat
sudo nginx -t
sudo systemctl reload nginxAccess:
http://admin.chat.snap.co.ke
| Service | URL |
|---|---|
| Matrix Homeserver | https://matrix.snap.co.ke |
| Element Web | https://chat.snap.co.ke |
| Admin UI | http://admin.chat.snap.co.ke |
- Admin UI is HTTP only
- Google SSO will not work on Admin UI without HTTPS
- Fix SSL properly for
admin.chat.snap.co.ke - Restrict admin access by IP or VPN
- Set up TURN server for calls
- Add backups for
/var/lib/matrix-synapse
If you want, I can:
- Export this as a README.md
- Add architecture diagrams
- Add troubleshooting section
- Or write a production hardening checklist
Just say the word.