---
title: "Deploy OpenLivery | (Just Updated) White-Label WhatsApp AI Agent Platform With Postgres, Owner Login Generated"
description: "OpenLivery WhatsApp AI agent platform for agencies with Postgres and API"
category: "Other"
url: https://railway.com/deploy/openlivery-or-just-updated-white-label-w
---

# Deploy OpenLivery | (Just Updated) White-Label WhatsApp AI Agent Platform With Postgres, Owner Login Generated

OpenLivery WhatsApp AI agent platform for agencies with Postgres and API

**[Deploy OpenLivery | (Just Updated) White-Label WhatsApp AI Agent Platform With Postgres, Owner Login Generated on Railway](https://railway.com/template/openlivery-or-just-updated-white-label-w)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/openlivery-or-just-updated-white-label-w/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** Other

## Template content

### proxy

- **Image:** caddy:2-alpine@sha256:003a97808e781aa9f7e75cc2f43d34d461099031faf5e20faefb9f61126836f0
- **Start command:** `/bin/sh -c 'echo UD0iJHtQT1JUOi04MDgwfSIKY2F0ID4gL3RtcC9DYWRkeWZpbGUgPDxFT0YKewoJYWRtaW4gb2ZmCglzZXJ2ZXJzIHsKCQl0cnVzdGVkX3Byb3hpZXMgc3RhdGljIHByaXZhdGVfcmFuZ2VzIDEwMC42NC4wLjAvMTAKCX0KfQo6JFAgewoJaGFuZGxlIC9hcGkvKiB7CgkJcmV2ZXJzZV9wcm94eSBhcGkucmFpbHdheS5pbnRlcm5hbDo4MDAwCgl9CgloYW5kbGUgewoJCXJldmVyc2VfcHJveHkgd2ViLnJhaWx3YXkuaW50ZXJuYWw6MzAwMAoJfQp9CkVPRgplY2hvICJwcm94eTogbGlzdGVuPTokUCIKZXhlYyBjYWRkeSBydW4gLS1jb25maWcgL3RtcC9DYWRkeWZpbGUgLS1hZGFwdGVyIGNhZGR5ZmlsZQ== | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`
- **Public domain:** Yes

### whatsapp

- **Image:** ghcr.io/sarrazola/openlivery-whatsapp:v0.4.0@sha256:a14e02d8405d3e4b97206dd283880003d3f3dcb9fc1b0070e8d1c301c8bb3c55
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFdIQVRTQVBQX0JSSURHRV9IT1NUPSc6OicgV0hBVFNBUFBfQlJJREdFX1BPUlQ9MzEwMSBXSEFUU0FQUF9MT0dfTEVWRUw9c2lsZW50CmV4cG9ydCBCQUNLRU5EX1VSTD1odHRwOi8vYXBpLnJhaWx3YXkuaW50ZXJuYWw6ODAwMAppPTAKdW50aWwgKGVjaG8gPiAvZGV2L3RjcC9wb3N0Z3Jlcy5yYWlsd2F5LmludGVybmFsLzU0MzIpIDI+L2Rldi9udWxsOyBkbwogIGk9JCgoaSsxKSk7IFsgIiRpIiAtZ3QgOTAgXSAmJiB7IGVjaG8gIndoYXRzYXBwOiBwb3N0Z3JlcyBuZXZlciBhbnN3ZXJlZCI7IGJyZWFrOyB9CiAgc2xlZXAgMgpkb25lCmVjaG8gIndoYXRzYXBwOiBwb3N0Z3JlcyByZWFjaGFibGUgYWZ0ZXIgJGkgdHJpZXMiCmV4ZWMgL2FwcC9icmlkZ2U= | base64 -d > /tmp/boot.sh; exec bash /tmp/boot.sh'`

### api

- **Image:** ghcr.io/sarrazola/openlivery-api:v0.4.0@sha256:cf59813ec201a1fc4fddb507c13e5ac3b7737604a9ff67a4477567233fd72643
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFNUT1JBR0VfRElSPS9hcHAvYmFja2VuZC9zdG9yYWdlCmV4cG9ydCBCQUNLRU5EX1VSTD1odHRwOi8vYXBpLnJhaWx3YXkuaW50ZXJuYWw6ODAwMApleHBvcnQgV0hBVFNBUFBfQlJJREdFX1VSTD1odHRwOi8vd2hhdHNhcHAucmFpbHdheS5pbnRlcm5hbDozMTAxCmV4cG9ydCBDT09LSUVfU0VDVVJFPXRydWUgQ09PS0lFX1NBTUVTSVRFPWxheCBBQ0NFU1NfVE9LRU5fTUlOVVRFUz0xMDA4MApleHBvcnQgQUxMT1dfTVVMVElfQUdFTkNZPWZhbHNlIFJBVEVfTElNSVRfRU5BQkxFRD10cnVlCm1rZGlyIC1wICIkU1RPUkFHRV9ESVIiCmNob3duIC1SIDEwMDAxOjEwMDAxICIkU1RPUkFHRV9ESVIiCmVjaG8gImFwaTogc3RvcmFnZSBvd25lcj0kKHN0YXQgLWMgJXU6JWcgIiRTVE9SQUdFX0RJUiIpIHdyaXRhYmxlLWJ5LWFwcD0kKHNldHByaXYgLS1yZXVpZD0xMDAwMSAtLXJlZ2lkPTEwMDAxIC0tY2xlYXItZ3JvdXBzIHRlc3QgLXcgIiRTVE9SQUdFX0RJUiIgJiYgZWNobyB5ZXMgfHwgZWNobyBubykiCnB5dGhvbiAtIDw8J1BZJwppbXBvcnQgc29ja2V0LCB0aW1lCmZvciBpIGluIHJhbmdlKDkwKToKICAgIHRyeToKICAgICAgICBzb2NrZXQuY3JlYXRlX2Nvbm5lY3Rpb24oKCJwb3N0Z3Jlcy5yYWlsd2F5LmludGVybmFsIiwgNTQzMiksIDIpLmNsb3NlKCkKICAgICAgICBwcmludCgiYXBpOiBwb3N0Z3JlcyByZWFjaGFibGUgYWZ0ZXIgJWQgdHJpZXMiICUgaSwgZmx1c2g9VHJ1ZSkKICAgICAgICBicmVhawogICAgZXhjZXB0IE9TRXJyb3I6CiAgICAgICAgdGltZS5zbGVlcCgyKQplbHNlOgogICAgcHJpbnQoImFwaTogcG9zdGdyZXMgbmV2ZXIgYW5zd2VyZWQiLCBmbHVzaD1UcnVlKQpQWQpjYXQgPiAvdG1wL2Jvb3RzdHJhcC5weSA8PCdQWScKaW1wb3J0IGpzb24sIG9zLCB0aW1lLCB1cmxsaWIucmVxdWVzdCwgdXJsbGliLmVycm9yCmJvZHkgPSBqc29uLmR1bXBzKHsiYWdlbmN5X25hbWUiOiAiT3BlbkxpdmVyeSIsICJuYW1lIjogIkFkbWluIiwgImVtYWlsIjogb3MuZW52aXJvblsiQURNSU5fRU1BSUwiXSwKICAgICAgICAgICAgICAgICAgICJwYXNzd29yZCI6IG9zLmVudmlyb25bIkFETUlOX1BBU1NXT1JEIl19KS5lbmNvZGUoKQpmb3IgaSBpbiByYW5nZSgyNDApOgogICAgdHJ5OgogICAgICAgIHVybGxpYi5yZXF1ZXN0LnVybG9wZW4oImh0dHA6Ly9bOjoxXTo4MDAwL2hlYWx0aCIsIHRpbWVvdXQ9MykucmVhZCgpCiAgICAgICAgYnJlYWsKICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgdGltZS5zbGVlcCgyKQplbHNlOgogICAgcHJpbnQoImJvb3RzdHJhcDogYXBpIG5ldmVyIGFuc3dlcmVkIiwgZmx1c2g9VHJ1ZSk7IHJhaXNlIFN5c3RlbUV4aXQoMSkKcmVxID0gdXJsbGliLnJlcXVlc3QuUmVxdWVzdCgiaHR0cDovL1s6OjFdOjgwMDAvYXBpL2F1dGgvcmVnaXN0ZXIiLCBkYXRhPWJvZHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVycz17IkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIn0sIG1ldGhvZD0iUE9TVCIpCnRyeToKICAgIHVybGxpYi5yZXF1ZXN0LnVybG9wZW4ocmVxLCB0aW1lb3V0PTE1KS5yZWFkKCkKICAgIHByaW50KCJib290c3RyYXA6IG93bmVyIGFjY291bnQgY3JlYXRlZCIsIGZsdXNoPVRydWUpCmV4Y2VwdCB1cmxsaWIuZXJyb3IuSFRUUEVycm9yIGFzIGU6CiAgICBwcmludCgiYm9vdHN0cmFwOiByZWdpc3RlciBhbnN3ZXJlZCAlZCAob3duZXIgYWxyZWFkeSBleGlzdHMpIiAlIGUuY29kZSwgZmx1c2g9VHJ1ZSkKUFkKc2V0cHJpdiAtLXJldWlkPTEwMDAxIC0tcmVnaWQ9MTAwMDEgLS1jbGVhci1ncm91cHMgcHl0aG9uIC90bXAvYm9vdHN0cmFwLnB5ICYKZXhlYyBzZXRwcml2IC0tcmV1aWQ9MTAwMDEgLS1yZWdpZD0xMDAwMSAtLWNsZWFyLWdyb3VwcyBzaCAtYyAnYWxlbWJpYyB1cGdyYWRlIGhlYWQgJiYgZXhlYyB1dmljb3JuIGFwcC5tYWluOmFwcCAtLWhvc3QgOjogLS1wb3J0IDgwMDAn | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`

### web

- **Image:** ghcr.io/sarrazola/openlivery-web:v0.4.0@sha256:0ca77db6853619d8e47eb7b2e513357413a948df2cff0c7d880436f939cfb414
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IEhPU1ROQU1FPSc6OicgUE9SVD0zMDAwCmV4cG9ydCBCQUNLRU5EX0lOVEVSTkFMX1VSTD1odHRwOi8vYXBpLnJhaWx3YXkuaW50ZXJuYWw6ODAwMAplY2hvICJ3ZWI6IGxpc3Rlbj1bOjpdOiRQT1JUIGJhY2tlbmQ9JEJBQ0tFTkRfSU5URVJOQUxfVVJMIHVpZD0kKGlkIC11KSIKZXhlYyBub2RlIHNlcnZlci5qcw== | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`

### postgres

- **Image:** postgres:17-alpine@sha256:a77aa70e641402a21411b92b721c58d10f23b50ae5fdd2333efd22d166e1e5f7
- **Start command:** `/bin/sh -c 'echo ZXhwb3J0IFBPU1RHUkVTX1VTRVI9b3BlbmxpdmVyeSBQT1NUR1JFU19EQj1vcGVubGl2ZXJ5CmV4ZWMgZG9ja2VyLWVudHJ5cG9pbnQuc2ggcG9zdGdyZXM= | base64 -d > /tmp/boot.sh; exec sh /tmp/boot.sh'`

## Documentation

# Deploy and Host OpenLivery on Railway

**Built for an LLM agent to deploy and use.** The deploy form has nothing to fill in: the owner password, the database password and every signing key are generated, the owner account is created at first boot, public signup is closed, and data survives redeploys. OpenLivery is an open-source white-label platform for agencies to build AI agents that answer customers on WhatsApp, with a shared inbox, per-client portals, a web chat widget, knowledge bases and custom tools.

## About Hosting OpenLivery

This template runs five services from the upstream OpenLivery images (version 0.4.0) plus Caddy and Postgres, each pinned by digest. **proxy** is the public front door on one domain and routes `/api` to the backend and everything else to the web app. **web** is the Next.js interface. **api** is the FastAPI backend: agencies, clients, agents, conversations, the REST API and the owner account. **postgres** holds every record and the WhatsApp session on a volume. **whatsapp** is the WhatsApp bridge, private, which pairs a phone by QR code from the OpenLivery interface.

**No default login.** The owner is the email `ADMIN_EMAIL` (admin at the proxy domain) with the generated `ADMIN_PASSWORD`, created at first boot. This is a single-agency instance, so registration is closed and nobody else can create an account.

**What the template fixes for Railway.** Services reach each other over Railway's private network, which is IPv6, so every service listens on `::`. The proxy listens on Railway's injected `PORT` and trusts Railway's edge so the real client address is kept. The api container fixes ownership of its storage volume, waits for Postgres, runs the database migrations, then starts. Cookies are marked secure for the HTTPS domain.

**Using it.** Open the proxy domain, sign in with `ADMIN_EMAIL` and `ADMIN_PASSWORD` (read them from the api service variables), add an AI provider key under settings, create a client and an agent, then connect WhatsApp by scanning the QR code.

### Agent contract

- Public URL: `https://RAILWAY_SERVICE_PROXY_URL` (the generated domain of the `proxy` service, also the part of `ADMIN_EMAIL` after the at sign)
- Private URL: `http://proxy.railway.internal:8080` (the backend itself is `http://api.railway.internal:8000`)
- Credentials: the variable `ADMIN_PASSWORD` on the `api` service
- Login name: the variable `ADMIN_EMAIL` on the `api` service (a public identifier, not a secret)
- Auth: `POST /api/auth/login` with JSON `email` and `password` sets the session cookie `access_token` (HttpOnly, secure); every other `/api` call sends that cookie. A request with no cookie or a wrong one answers `401`.
- Health: `GET /api/auth/status` returns 200

```bash
#!/bin/sh
# needs: ADMIN_EMAIL, ADMIN_PASSWORD (variables of the api service); also curl. ADMIN_EMAIL is admin@ plus the proxy's public domain.
D="${ADMIN_EMAIL#admin@}"; R="https://$D"; J="Content-Type: application/json"; B=$(mktemp); C=$(mktemp)
n=0; until [ "$(curl -s -o /dev/null -w '%{http_code}' "$R/api/auth/status")" = 200 ]; do n=$((n+1)); [ "$n" -le 90 ] || break; sleep 5; done
# sign in as the owner created at first boot; the session is the access_token cookie
n=0; while :; do c=$(curl -s -c "$C" -o "$B" -w '%{http_code}' -H "$J" -d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}" "$R/api/auth/login"); if [ "$c" = 200 ]; then break; fi; n=$((n+1)); [ "$n" -le 12 ] || break; sleep 10; done
echo "login: $c"
curl -s -b "$C" -o /dev/null -w "read with session: %{http_code}\n" "$R/api/clients"
curl -s -b "$C" -o "$B" -w "write with session: %{http_code}\n" -H "$J" -d '{"name":"Railway Check","industry":"test"}' "$R/api/clients"
ID=$(sed -n 's/.*"id":"\([0-9a-f-]*\)".*/\1/p' "$B" | head -1)
curl -s -b "$C" "$R/api/clients" | grep -c '"name":"Railway Check"' | sed 's/^/client found after write: /'
curl -s -b "$C" -o /dev/null -w "delete with session: %{http_code}\n" -X DELETE "$R/api/clients/$ID"
curl -s -o /dev/null -w "read without key: %{http_code}\n" "$R/api/clients"
curl -s -o /dev/null -w "write without key: %{http_code}\n" -X POST -H "$J" -d '{"name":"Anonymous"}' "$R/api/clients"
curl -s -o /dev/null -w "write wrong key: %{http_code}\n" -X POST -H "$J" -b "access_token=wrong" -d '{"name":"Anonymous"}' "$R/api/clients"
curl -s -o /dev/null -w "public signup: %{http_code}\n" -X POST -H "$J" -d '{"agency_name":"Intruder","name":"Intruder","email":"x@example.com","password":"Intruder-pass-123"}' "$R/api/auth/register"
curl -s -o /dev/null -w "web app: %{http_code}\n" "$R/"
```

A fresh deploy prints `login: 200`, `read with session: 200`, `write with session: 201`, `client found after write: 1` and `delete with session: 204`. The refusals print `read without key: 401`, `write without key: 401`, `write wrong key: 401` and `public signup: 403`: a request with no session or a wrong one creates nothing, and nobody can register an account from outside. `web app: 200` is the interface itself.

## Why Deploy OpenLivery on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying OpenLivery on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

- **Agent-ready** - a generated owner password, a contract block and one script that proves sign-in, an authenticated write, read-back and delete, and the refusal of a read and a write with no session or a wrong one.
- **No setup form and no default login** - the owner is created at boot and registration is closed.
- **Data survives redeploys** - records and the WhatsApp session sit in Postgres on a volume, uploads on a second volume.
- **Pinned** - every upstream image is pinned by digest.

## Common Use Cases

- **WhatsApp AI agents for clients** - an agency builds and runs one agent per customer business.
- **Shared support inbox** - operators and agents answer WhatsApp conversations in one place.
- **White-label client portals** - each client gets a branded portal and a web chat widget.
- **Self-hosted alternative to hosted chatbot platforms** - own the conversations and the keys.

## Dependencies for OpenLivery Hosting

- The five services above, created by the template. An OpenAI or Anthropic API key is added inside OpenLivery afterwards to power the agents.

### Deployment Dependencies

- [OpenLivery repository](https://github.com/sarrazola/openlivery)
- [OpenLivery documentation](https://github.com/sarrazola/openlivery#readme)


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — Self-hosted virtual tabletop for role-playing games (license required)
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/openlivery-or-just-updated-white-label-w
