WIKI Setup Complete Hetzner VPS Deployment Guide Gollum Lumo

Complete Hetzner VPS Deployment Guide

Step-by-Step Instructions for Hybrid Wiki Platform

Phase 1: VPS Provisioning & Initial Setup (15 minutes)

1.1 Purchase & Configure Hetzner VPS

  1. Visit https://www.hetzner.com/cloud

  2. Create account or log in

  3. Click “Create Project” or select existing project

  4. Click “Create Server”

  5. Configuration:

    • Location: Choose closest to your users (Frankfurt, Nuremberg, etc.)

    • OS Image: Ubuntu 22.04 LTS (x64)

    • Server Type: CPX21 recommended minimum

      • 2 vCPU

      • 4 GB RAM

      • 40 GB SSD

    • Volume: Optional (add if you need extra storage)

    • Network: Default is fine

    • SSH Keys: Select or upload your public SSH key

    • Firewalls: Create new: Allow 22/TCP, 80/TCP, 443/TCP, 10000/UDP

    • Backups: Enable automatic backups (recommended)

  6. Click “Create & Buy now”

  7. Wait 1-2 minutes for server to boot

1.2 Initial SSH Access

# On your local machine
# Find your VPS IP in Hetzner console and SSH in
ssh root@YOUR_VPS_IP
 
# Accept the host key when prompted

1.3 System Updates & Security Hardening

# Update system
apt update && apt upgrade -y
 
# Set timezone to UTC
timedatectl set-timezone UTC
 
# Install essential tools
apt install -y wget curl git unzip build-essential
 
# Create non-root user for application
adduser collab
# Press Enter for all prompts except password - set a strong password
 
# Add user to sudo group (for passwordless sudo if using SSH keys)
usermod -aG sudo collab
 
# Enable sudo without password (optional, for automation)
echo "collab ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/collab
 
# Set hostname
hostnamectl set-hostname hybrid-platform
# Add to /etc/hosts
echo "127.0.0.1 hybrid-platform" >> /etc/hosts

1.4 Configure SSH for Increased Security

# As root, configure SSH
nano /etc/ssh/sshd_config
 
# Make these changes:
# - Change port (optional, e.g., Port 2222)
# - PermitRootLogin no
# - PasswordAuthentication no
# - PubkeyAuthentication yes
 
# Restart SSH
systemctl restart ssh
 
# Exit as root and log in as collab user
exit
ssh collab@YOUR_VPS_IP

1.5 Configure Firewall

# Install UFW (firewall)
sudo apt install -y ufw
 
# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
 
# Allow necessary ports
sudo ufw allow 22/tcp      # SSH
sudo ufw allow 80/tcp      # HTTP
sudo ufw allow 443/tcp     # HTTPS
sudo ufw allow 10000/udp   # Jitsi media
 
# Enable firewall
sudo ufw enable
 
# Verify configuration
sudo ufw status

Phase 2: Docker Installation (10 minutes)

2.1 Install Docker Engine

# Download Docker install script
curl -fsSL https://get.docker.com -o get-docker.sh
 
# Run installation
sudo sh get-docker.sh
 
# Verify installation
docker --version

2.2 Install Docker Compose V2

# Download Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
 
# Make executable
sudo chmod +x /usr/local/bin/docker-compose
 
# Verify installation
docker-compose --version
 
# Verify Docker works
sudo docker run hello-world

2.3 Configure Docker User Permissions

# Add user to docker group (allows running docker without sudo)
sudo usermod -aG docker $USER
 
# Apply group membership
newgrp docker
 
# Test without sudo
docker run hello-world
 
# If error, log out and log back in
logout
ssh collab@YOUR_VPS_IP

Phase 3: Domain & SSL Configuration (10 minutes)

3.1 Point Domain to VPS

  1. Access your domain registrar (GoDaddy, Namecheap, etc.)

  2. Find DNS settings

  3. Create or update A record:

    • Host: @ (or subdomain if you prefer: wiki, platform, etc.)

    • Type: A

    • Value: YOUR_VPS_IP

    • TTL: 3600 (1 hour)

  4. Wait 5-15 minutes for DNS propagation

  5. Test DNS resolution:

# From your local machine
nslookup your_domain.com
# Should return YOUR_VPS_IP

3.2 Generate SSL Certificates with Let’s Encrypt

# Install Certbot (BEFORE starting Docker services)
sudo apt install -y certbot python3-certbot-nginx
 
# Generate certificate (replace your_domain.com)
sudo certbot certonly --standalone -d your_domain.com
 
# You'll be asked for email (for renewal notifications) - enter valid email
 
# Verify certificate created
sudo ls -la /etc/letsencrypt/live/your_domain.com/
 
# You should see:
# - fullchain.pem (certificate chain)
# - privkey.pem (private key)
# - cert.pem
# - chain.pem
 
# Set correct permissions for Docker access
sudo chmod 755 /etc/letsencrypt/live/
sudo chmod 755 /etc/letsencrypt/archive/
sudo chmod 644 /etc/letsencrypt/live/your_domain.com/fullchain.pem
sudo chmod 644 /etc/letsencrypt/live/your_domain.com/privkey.pem

3.3 Configure SSL Auto-Renewal

# Test renewal process
sudo certbot renew --dry-run
 
# Check renewal cron job was created
sudo ls -la /etc/cron.d/certbot
 
# Certbot automatically renews 30 days before expiration
# Verify by checking renewal daemon status
sudo systemctl status certbot.timer
 
# Start timer if not running
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

Phase 4: Repository Setup (5 minutes)

4.1 Clone Repository

# Navigate to home directory
cd ~
 
# Clone the repository
git clone https://github.com/YOUR_USERNAME/hybrid-wiki-collab-platform.git
cd hybrid-wiki-collab-platform
 
# Verify structure
ls -la
# Should see: docker/, src/, configs/, docs/, .env.example, docker-compose.yml, etc.

4.2 Configure Environment Variables

# Copy template
cp .env.example .env
 
# Edit configuration
nano .env
 
# Key variables to customize:
# DOMAIN=your_domain.com
# SMTP_USER=your-email@gmail.com
# SMTP_PASSWORD=your_app_password (for Gmail)
# And all password fields
 
# Generate strong random values for passwords/secrets
# Run this multiple times to create values:
openssl rand -base64 32
 
# Edit and save: Ctrl+O, Enter, Ctrl+X

4.3 Verify File Permissions

# Change ownership of project to collab user (if you're not already collab)
sudo chown -R collab:collab /home/collab/hybrid-wiki-collab-platform
 
# Verify
ls -la
 
# Test docker-compose syntax
docker-compose config > /dev/null && echo "docker-compose.yml is valid" || echo "Error in docker-compose.yml"

Phase 5: Directory Structure & Database Setup (5 minutes)

5.1 Create Required Directories

# From project root
mkdir -p wiki-repo
mkdir -p rocket-chat-data
mkdir -p mongodb-data
mkdir -p postgres-data
mkdir -p jitsi-config
mkdir -p logs
 
# Initialize bare git repository for wiki
cd wiki-repo
git init --bare
cd ..
 
# Set permissions
chmod -R 755 wiki-repo
chmod -R 700 rocket-chat-data mongodb-data postgres-data
 
# Verify
ls -la | grep -E "wiki-repo|rocket-chat|mongodb|postgres|jitsi|logs"

Phase 6: Build & Deploy Services (20-30 minutes)

6.1 Build Docker Images

# Verify all services are defined
docker-compose config | grep "service:"
 
# Build custom images (gollum, auth, nginx)
docker-compose build
 
# This will take 10-15 minutes as it downloads and compiles
# You'll see progress for each service
 
# Verify images were created
docker images | grep collab

6.2 Start Services

# Start all services in background
docker-compose up -d
 
# Monitor startup (takes 2-3 minutes)
watch docker-compose ps
# Press Ctrl+C to exit watch
 
# Or check individual service status
docker-compose ps
 
# Should show all services as "Up" after 2-3 minutes

6.3 Initialize Databases

# PostgreSQL schema for auth service
docker-compose exec -T postgres psql -U collab_admin -d collab_auth << EOF
CREATE TABLE IF NOT EXISTS users (
    id SERIAL PRIMARY KEY,
    account_name VARCHAR(255) UNIQUE NOT NULL,
    email_hash VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_login TIMESTAMP,
    is_active BOOLEAN DEFAULT true
);
 
CREATE TABLE IF NOT EXISTS auth_tokens (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
    token VARCHAR(500) UNIQUE NOT NULL,
    expires_at TIMESTAMP NOT NULL,
    used BOOLEAN DEFAULT false,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
 
CREATE INDEX idx_auth_tokens_token ON auth_tokens(token);
CREATE INDEX idx_auth_tokens_expires ON auth_tokens(expires_at);
CREATE INDEX idx_users_email_hash ON users(email_hash);
EOF
 
echo "Database initialized successfully"

Phase 7: Service Verification (10 minutes)

7.1 Check Service Health

# View all container logs (last 50 lines)
docker-compose logs --tail=50
 
# Check specific service
docker-compose logs -f auth-service
 
# Wait for services to fully initialize (2-3 minutes)
sleep 180
 
# Check if containers are still running
docker-compose ps
 
# Any container showing "Exit" or "Restarting" has an issue

7.2 Test Endpoints from VPS

# Test wiki endpoint
curl -sk https://your_domain.com/wiki | head -20
 
# Test auth health endpoint
curl -s https://your_domain.com/api/auth/health | jq .
 
# Test chat endpoint (might show redirect or login page)
curl -sk https://your_domain.com/chat | head -20
 
# If you see errors, check logs
docker-compose logs nginx
docker-compose logs gollum
docker-compose logs auth-service

7.3 Test from Local Machine

# From your local computer (not VPS)
 
# Test wiki in browser
# Visit: https://your_domain.com/wiki
 
# Test chat endpoint
# Visit: https://your_domain.com/chat
 
# Test API endpoint
curl -s https://your_domain.com/api/auth/health | jq .
 
# Expected responses:
# - Wiki: Gollum wiki interface
# - Chat: Login page or chat interface
# - API Health: {"status": "ok", "timestamp": "..."}

Phase 8: Post-Deployment Configuration (15 minutes)

8.1 Create Rocket.Chat Admin Account

# Enter Rocket.Chat container
docker-compose exec rocket-chat bash
 
# Create admin user (inside container)
rocketchat-cli user create admin admin@your_domain.com $(openssl rand -base64 12)
 
# Exit container
exit
 
# Or use web interface:
# 1. Visit https://your_domain.com/chat
# 2. Click "Create account"
# 3. Create admin user

8.2 Configure Jitsi Users (Optional)

# Create Jitsi users for system accounts
docker-compose exec jitsi prosodyctl register jicofo your_domain.com $(openssl rand -base64 12)
docker-compose exec jitsi prosodyctl register jvb your_domain.com $(openssl rand -base64 12)

8.3 Initialize Wiki Home Page

# Access wiki container
docker-compose exec gollum bash
 
# Create initial home page
cd /wiki && git config user.name 'Wiki Admin' && git config user.email 'admin@your_domain.com'
 
# Create home page
echo "# Welcome to Hybrid Platform Wiki" > Home.md
git add Home.md
git commit -m "Initial wiki setup"
 
# Exit
exit
# Request magic link
curl -X POST https://your_domain.com/api/auth/request \\
  -H "Content-Type: application/json" \\
  -d '{"email": "your-test-email@example.com"}'
 
# Response will include generated account_name like "HappyNarwhal"
 
# Check email inbox for magic link
# Click link and verify you get JWT token back

Phase 9: Backup & Monitoring Setup (10 minutes)

9.1 Automated Backup Schedule

# Create backup script if not present
chmod +x src/scripts/backup.sh
 
# Edit crontab for automated backups
crontab -e
 
# Add these lines (backups daily at 2 AM):
0 2 * * * cd /home/collab/hybrid-wiki-collab-platform && ./src/scripts/backup.sh >> logs/backup.log 2>&1
 
# Save and exit (Ctrl+O, Enter, Ctrl+X)
 
# Verify crontab entry
crontab -l

9.2 Monitor Disk Space

# Check current usage
df -h
 
# Check Docker volume usage
docker system df
 
# Monitor in real-time (useful for initial startup)
watch -n 5 'docker system df && echo "" && df -h'

9.3 Set Up Log Rotation

# Create logrotate config
sudo nano /etc/logrotate.d/hybrid-platform
 
# Add this content:
/home/collab/hybrid-wiki-collab-platform/logs/*.log {
    daily
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
}
 
# Save and exit (Ctrl+O, Enter, Ctrl+X)
 
# Test configuration
sudo logrotate -d /etc/logrotate.d/hybrid-platform

Phase 10: Security Hardening (10 minutes)

10.1 Additional Firewall Rules

# Allow backup connections (if needed)
sudo ufw allow 22/tcp
sudo ufw allow 22/udp
 
# Limit SSH connections
sudo ufw limit 22/tcp
 
# View final firewall status
sudo ufw status verbose

10.2 Update System Packages Regularly

# Enable automatic security updates
sudo apt install -y unattended-upgrades
 
# Configure
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
 
# Ensure this line is present:
# Unattended-Upgrade::Automatic-Reboot "true";
 
# Enable the service
sudo systemctl enable unattended-upgrades
sudo systemctl start unattended-upgrades

10.3 Monitor System Health

# Install htop for system monitoring
sudo apt install -y htop
 
# Check system status
htop
# Press 'q' to exit
 
# Check open ports
sudo netstat -tulpn | grep LISTEN
 
# Check disk usage
du -sh ~/hybrid-wiki-collab-platform/*

Quick Troubleshooting Reference

Services Won’t Start

# 1. Check logs
docker-compose logs
 
# 2. Verify .env file
cat .env | grep DOMAIN
 
# 3. Ensure directories exist
ls -la | grep -E "wiki-repo|mongodb|postgres"
 
# 4. Restart Docker daemon
sudo systemctl restart docker
 
# 5. Rebuild from scratch
docker-compose down -v
docker-compose build --no-cache
docker-compose up -d

SSL Certificate Issues

# Check certificate status
sudo certbot certificates
 
# Manually renew if needed
sudo certbot renew --force-renewal
 
# Check certificate validity
openssl x509 -in /etc/letsencrypt/live/your_domain.com/fullchain.pem -text -noout

Database Connection Errors

# Check PostgreSQL
docker-compose exec postgres psql -U collab_admin -d collab_auth -c "SELECT 1"
 
# Check MongoDB
docker-compose exec mongodb mongosh --eval "db.adminCommand('ping')"
 
# Restart databases
docker-compose restart postgres mongodb
# Verify SMTP settings in .env
grep SMTP .env
 
# Test SMTP connection
telnet smtp.gmail.com 587
 
# Check auth service logs
docker-compose logs auth-service | grep -i email

Performance Optimization Tips

# 1. Monitor resource usage
docker stats
 
# 2. Limit resource consumption (edit docker-compose.yml)
# Add to services:
# resources:
#   limits:
#     cpus: '1'
#     memory: 1G
 
# 3. Enable Docker log rotation (prevent disk fill)
# Edit /etc/docker/daemon.json:
# {
#   "log-driver": "json-file",
#   "log-opts": {
#     "max-size": "100m",
#     "max-file": "10"
#   }
# }
 
# 4. Increase open file limits
ulimit -n 65536
 
# 5. Use Nginx caching for static assets
# Already configured in docker/nginx/conf.d/default.conf

Access Your Platform

After successful deployment:

ServiceURLAccess
Wikihttps://your_domain.com/wikiPublic, no login
Chathttps://your_domain.com/chatPrivate, requires login
Videohttps://your_domain.com/videoPrivate, requires login
API Authhttps://your_domain.com/api/authFor requesting magic links

Next Steps

  1. Create Initial Users - Use magic link authentication

  2. Configure Chat Channels - Set up team channels in Rocket.Chat

  3. Write Wiki Pages - Start documenting in Gollum

  4. Set Up Backups - Verify backup scripts are running

  5. Monitor Logs - Regularly check system and application logs

  6. Test Recovery - Periodically restore from backups to verify they work


Support & Resources


Deployment Complete! 🎉

Your hybrid platform is now live and ready to use. Remember to:

  • Keep backups current

  • Monitor resource usage

  • Update containers regularly

  • Review logs periodically

For issues or questions, check the troubleshooting section or review service logs.

Notesnook Github Vercel project private wiki

WIKI Setup Complete Hetzner VPS Deployment Guide lumo

phone recommendations