Skip to main content
MeepaChat runs as a single binary with Docker-managed infrastructure (Postgres, Redis, MinIO). Deploy it to any Linux server with Docker installed.

Quick Start (any VPS)

On a fresh Ubuntu 24.04 server:
# 1. Install Docker
curl -fsSL https://get.docker.com | sh

# 2. Install MeepaChat
curl -fsSL https://meepachat.bogpad.io/install.sh | sh

# 3. Set up infrastructure
meepachat init --yes

# 4. Start the server
meepachat start
meepachat init --yes pulls Docker images, starts Postgres, Redis, and MinIO, and writes config to ~/.meepachat/config.yaml. Access MeepaChat at http://<server-ip>:8091. The first user to register becomes admin.

DigitalOcean

One-click cloud-init

Create a droplet with MeepaChat pre-installed:
doctl compute droplet create meepachat \
  --region nyc1 \
  --size s-2vcpu-4gb \
  --image ubuntu-24-04-x64 \
  --ssh-keys <YOUR_KEY_ID> \
  --user-data "$(curl -sfL https://meepachat.bogpad.io/cloud-init.sh)" \
  --wait
This installs Docker, MeepaChat, runs meepachat init --yes, and creates a systemd service automatically. MeepaChat is running by the time the droplet is ready (~2–3 minutes).
Replace <YOUR_KEY_ID> with your SSH key ID. List keys with doctl compute ssh-key list.To add an SSH key:
ssh-keygen -t ed25519 -C "your-email@example.com"
doctl compute ssh-key import meepachat --public-key-file ~/.ssh/id_ed25519.pub

Manual setup

  1. Create an Ubuntu 24.04 droplet (minimum 2 vCPU, 4 GB RAM recommended)
  2. SSH in: ssh root@<droplet-ip>
  3. Follow the Quick Start instructions above

Hetzner / Any Provider

Use cloud-init — paste as “User data” when creating a server:
curl -sfL https://meepachat.bogpad.io/cloud-init.sh
After boot (~5 minutes), open http://<server-ip>:8091.

Run as a systemd Service

Keep MeepaChat running across reboots and SSH disconnects:
cat > /etc/systemd/system/meepachat.service << EOF
[Unit]
Description=MeepaChat Server
After=network.target docker.service
Requires=docker.service

[Service]
Type=simple
ExecStart=/usr/local/bin/meepachat start --foreground
Environment=MEEPA_CONFIG_PATH=/root/.meepachat/config.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now meepachat

Reverse Proxy

MeepaChat serves HTTP on port 8091. For production, put it behind a reverse proxy for TLS termination and a clean domain name. Caddy handles TLS automatically via Let’s Encrypt:
chat.example.com {
    reverse_proxy localhost:8091
}
Set BASE_URL=https://chat.example.com in your config so cookies and links use the correct domain.

Nginx

server {
    listen 443 ssl;
    server_name chat.example.com;

    ssl_certificate /etc/letsencrypt/live/chat.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/chat.example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8091;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
The Upgrade and Connection headers are required for WebSocket support. Without them, real-time messaging will not work.

Firewall

If UFW is enabled, open the MeepaChat port:
ufw allow 8091/tcp
In production behind a reverse proxy, you can restrict direct access to the port:
ufw allow 80/tcp
ufw allow 443/tcp
ufw deny 8091/tcp

UsersvCPURAMDisk
1–5012 GB25 GB
50–50024 GB50 GB
500+48 GB100 GB
Storage needs depend on file upload volume. MeepaChat stores uploads in S3-compatible storage (MinIO by default). For heavy file sharing, use Cloudflare R2 or AWS S3 instead.