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
- Create an Ubuntu 24.04 droplet (minimum 2 vCPU, 4 GB RAM recommended)
- SSH in:
ssh root@<droplet-ip>
- 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 (recommended)
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:
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
Recommended Server Specs
| Users | vCPU | RAM | Disk |
|---|
| 1–50 | 1 | 2 GB | 25 GB |
| 50–500 | 2 | 4 GB | 50 GB |
| 500+ | 4 | 8 GB | 100 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.