# Deploy Moltis on a VPS Run your own AI agent on a $5/month VPS. This guide covers provisioning, installation, and connecting channels (Telegram, Discord, etc.) so you can talk to your agent from anywhere. ## Prerequisites - A VPS with at least 1 GB RAM and 10 GB disk (any provider: Hetzner, DigitalOcean, Linode, Vultr, etc.) - SSH access to the server - An API key from at least one LLM provider (Anthropic, OpenAI, etc.) ## Option A: Docker (recommended) Docker is the fastest path. It handles sandbox isolation and upgrades via image pulls. For browser-trusted TLS on a VPS, put Moltis behind a reverse proxy such as Caddy, nginx, or Traefik and let the proxy manage public certificates. ### 1. Install Docker ```bash curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # Log out and back in for group membership to take effect ``` ### 2. Deploy Moltis ```bash mkdir -p ~/moltis && cd ~/moltis curl -fsSL https://raw.githubusercontent.com/moltis-org/moltis/main/deploy/docker-compose.yml -o docker-compose.yml # Set your password export MOLTIS_PASSWORD="your-secure-password" # Start docker compose up -d ``` ### 3. Access the web UI For a production VPS, use a domain name and terminate TLS at a reverse proxy: ```yaml services: moltis: image: ghcr.io/moltis-org/moltis:latest command: ["--bind", "0.0.0.0", "--port", "13131", "--no-tls"] environment: - MOLTIS_BEHIND_PROXY=true - MOLTIS_EXTERNAL_URL=https://chat.example.com ``` Point your proxy at `http://:13131`, then open your public URL, for example `https://chat.example.com`. Moltis can also auto-generate a local CA and server certificate, but that mode is meant for local development or private networks. Trusting the generated CA only makes the issuer trusted; the browser still requires the certificate's Subject Alternative Name (SAN) to match the exact hostname or IP you open. An IP-address URL such as `https://:13131` only works if the certificate contains that IP address as an IP SAN, and normal public TLS setups are domain-name based. Inside Docker, Moltis usually cannot know your VPS public IP or provider domain, so direct IP access may fail with a certificate name mismatch even after importing the CA. To use direct IP access with the auto-generated certificate, set the public IP explicitly: ```toml [tls] public_ip = "203.0.113.10" ``` Then restart Moltis so it regenerates the server certificate and import the generated CA from `http://:13132/certs/ca.pem`. If you want Moltis to serve HTTPS directly on a public domain, configure `tls.cert_path` and `tls.key_path` with a certificate issued for that domain. Log in with the password you set, then configure your LLM provider in Settings. ## Option B: Binary + systemd For servers without Docker, install the binary directly. ### 1. Download the binary ```bash # Replace VERSION with the latest release (e.g. 20260420.01) VERSION=$(curl -s https://api.github.com/repos/moltis-org/moltis/releases/latest | grep tag_name | cut -d '"' -f 4) ARCH=$(uname -m | sed 's/x86_64/x86_64/;s/aarch64/aarch64/') curl -fsSL "https://github.com/moltis-org/moltis/releases/download/${VERSION}/moltis-${VERSION}-linux-${ARCH}.tar.gz" | sudo tar xz -C /usr/local/bin ``` ### 2. Create user and directories ```bash sudo useradd -r -m -d /var/lib/moltis -s /usr/sbin/nologin moltis sudo mkdir -p /etc/moltis sudo chown moltis:moltis /var/lib/moltis /etc/moltis ``` ### 3. Install the systemd service ```bash sudo curl -fsSL https://raw.githubusercontent.com/moltis-org/moltis/main/deploy/moltis.service -o /etc/systemd/system/moltis.service ``` The bundled unit keeps `NoNewPrivileges=true` and `ProtectHome=true` as secure defaults. If Moltis uses rootless Podman, install the Podman-specific override: ```bash sudo mkdir -p /etc/systemd/system/moltis.service.d sudo curl -fsSL https://raw.githubusercontent.com/moltis-org/moltis/main/deploy/moltis-podman.conf -o /etc/systemd/system/moltis.service.d/podman.conf ``` The override relaxes only the directives that block Podman's user namespace re-exec path and places its writable home and runtime directories under paths allowed by the unit. Rootless Podman also requires an unused subordinate UID and GID range. Check `/etc/subuid` and `/etc/subgid`; if the `moltis` user has none, assign a non-overlapping range before starting the service, for example: ```bash sudo usermod --add-subuids 200000-265535 --add-subgids 200000-265535 moltis ``` If `allow_host_podman = true`, install the companion API service before Moltis. It runs as `moltis` and creates `/run/moltis/podman/podman.sock`, matching the drop-in's `XDG_RUNTIME_DIR`: ```bash sudo curl -fsSL https://raw.githubusercontent.com/moltis-org/moltis/main/deploy/moltis-podman-api.service -o /etc/systemd/system/moltis-podman-api.service sudo systemctl daemon-reload sudo systemctl enable --now moltis-podman-api.service ``` Then enable and start Moltis: ```bash sudo systemctl daemon-reload sudo systemctl enable --now moltis ``` ### 4. Set your password ```bash sudo -u moltis MOLTIS_DATA_DIR=/var/lib/moltis MOLTIS_CONFIG_DIR=/etc/moltis moltis auth reset-password ``` ### 5. Check status ```bash sudo systemctl status moltis sudo journalctl -u moltis -f ``` ## Connecting channels Once Moltis is running, add messaging channels from Settings > Channels in the web UI. Each channel has its own setup flow: | Channel | What you need | |---------|--------------| | Telegram | Bot token from [@BotFather](https://t.me/BotFather) | | Discord | Bot token from the [Developer Portal](https://discord.com/developers) | | Slack | Bot + App tokens from [api.slack.com](https://api.slack.com/apps) | | Matrix | Homeserver URL + credentials | | Nostr | Secret key (nsec) + relay URLs | See the individual [channel docs](channels.md) for detailed setup instructions. ## Firewall If you use the recommended reverse proxy setup, expose only the proxy ports (`80` and `443`) publicly and keep Moltis' `13131` port private to the host or container network. Only expose `13131` directly if you intentionally serve Moltis without a proxy. Only expose `13132` if you intentionally use Moltis' local CA download endpoint. ```bash # UFW example for the recommended reverse proxy setup sudo ufw allow 80/tcp sudo ufw allow 443/tcp ``` ## Upgrades **Docker:** `docker compose pull && docker compose up -d` **Binary:** Download the new release binary and restart the service: ```bash sudo systemctl stop moltis # Download new binary (same curl as step 1) sudo systemctl start moltis ``` ## Resource requirements | Workload | RAM | CPU | Disk | |----------|-----|-----|------| | Chat only (no sandbox) | 512 MB | 1 vCPU | 5 GB | | Chat + sandbox | 1 GB | 1 vCPU | 10 GB | | Chat + sandbox + local LLM | 4+ GB | 2+ vCPU | 20+ GB | LLM inference happens on the provider's API servers, so even a $5 VPS handles chat workloads with external providers.