---
title: "Deploy Odoo"
description: "Self-host Odoo: open-source ERP, CRM, invoicing and inventory"
category: "Other"
url: https://railway.com/deploy/odoo-railway
---

# Deploy Odoo

Self-host Odoo: open-source ERP, CRM, invoicing and inventory

**[Deploy Odoo on Railway](https://railway.com/template/odoo-railway)**

- **Creator:** A3A
- **Category:** Other
- **Total deploys:** 2

## Template content

### Postgres https://devicons.railway.app/i/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### odoo https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/odoo.svg

- **Source:** https://github.com/gridalpha/odoo-railway
- **Health check:** /web/health

### odoo-proxy https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/odoo.svg

- **Source:** https://github.com/gridalpha/odoo-railway
- **Health check:** /web/health
- **Public domain:** Yes

## Documentation

![Odoo logo](https://res.cloudinary.com/rroe4rtk/image/upload/v1786650623/6df24420-183f-451c-b404-6e92e6a8f07e.png)

# Deploy and Host Odoo on Railway

Odoo is the open-source business suite behind CRM, Sales, Invoicing, Inventory, Project, HR and Point of Sale — dozens of apps sharing one PostgreSQL database and one login, so a quotation becomes a sales order, a delivery and a journal entry with no glue code. Teams that outgrow spreadsheets but do not want a per-seat SaaS bill self-host Odoo Community Edition: LGPL-3.0, no license fee. Deploy Odoo on Railway to get the production configuration on first boot.

Self-host Odoo on Railway as three services. **`odoo`** builds on the official `odoo:19.0` image and runs it in multi-processing mode, with a volume at `/var/lib/odoo` for the filestore. **`Postgres`** is Railway's managed PostgreSQL on the private network. **`odoo-proxy`** runs `nginx:1.30-alpine`, owns the public domain, and sends `/websocket` to Odoo's gevent port `8072` and everything else to the HTTP workers on `8069` — Odoo puts its real-time bus on that second port, and a Railway domain maps to only one port, so without the proxy live updates fail silently.

![Odoo Railway architecture](https://res.cloudinary.com/rroe4rtk/image/upload/v1786650591/722d9bc3-fddf-4a97-8c8f-7eb43690b500.png)

## Getting Started with Odoo on Railway

**Create the database role first.** Odoo 19 refuses to start when its PostgreSQL user is named `postgres`, so this template ships `PGUSER=odoo` with a generated `PGPASSWORD`. Create that role on the Postgres service:

```
CREATE ROLE odoo WITH LOGIN CREATEDB NOSUPERUSER NOCREATEROLE NOREPLICATION PASSWORD '';
```

`CREATEDB` is required: Odoo uses it to create, duplicate and restore databases, and to bootstrap `db_name` on first boot. If the service exits at boot, this role is why.

Then open the public domain on `odoo-proxy`. Odoo initialises the database itself with no first-run wizard: you land on `/web/login`, and an administrator already exists with the default credentials **`admin` / `admin`**. Change it immediately under *My Profile → Account Security* — nothing forces it, and the instance is public as soon as the domain resolves. Next open **Apps** and install a module, then confirm *Customer Account* is **On invitation** under **Settings → General Settings → Permissions**: some apps pull in Odoo's sign-up module, whose default opens public registration at `/web/signup`.

![Odoo dashboard screenshot 1](https://res.cloudinary.com/rroe4rtk/image/upload/v1786648837/02-discuss_yy5czj.png)
![Odoo dashboard screenshot 2](https://res.cloudinary.com/rroe4rtk/image/upload/v1786648835/03-contacts_nyer40.png)
![Odoo dashboard screenshot 3](https://res.cloudinary.com/rroe4rtk/image/upload/v1786648839/01-apps_pcs8r3.png)

## About Hosting Odoo

Odoo replaces the usual small-business stack — a CRM, an invoicing tool, a stock spreadsheet, an accounting package — with one relational model, so there is no sync job between systems to fail. Self-host it to keep your ledger and customer data on infrastructure you control.

- **Modular apps** — CRM, Sales, Purchase, Inventory, Invoicing, Project, HR, Point of Sale, Website and eCommerce, installed individually.
- **Open APIs** — XML-RPC and JSON-RPC expose every model; most Shopify and Stripe integrations build on them.
- **Extensible** — custom addons drop into the addons path; the OCA publishes thousands of free ones.

The volume is Odoo's *filestore*: attachments live on disk, not in the database, so it must persist or files 404 after a redeploy. The proxy rewrites `X-Forwarded-For` to its leftmost entry, so Odoo logs real user IPs.

## Why Deploy Odoo on Railway

Railway removes the server administration an ERP normally drags along.

- Managed PostgreSQL, provisioned and wired up
- Persistent volume for the Odoo filestore
- Private networking, so the app server is never exposed
- Free HTTPS domain and certificate on the proxy
- Health checks, logs and metrics, no extra tooling

## Common Use Cases for Self-Hosted Odoo

- **Full back office for an SMB** — quotes, orders, invoices and stock for a 10–100 person team.
- **CRM and sales pipeline management** — a free alternative to per-seat CRM SaaS, with email logging.
- **Inventory and light manufacturing** — multi-warehouse stock, reordering rules, bills of materials.
- **Custom internal apps** — Odoo's ORM and access rules make a fast internal-tool framework.

## Dependencies for Odoo

- **`odoo`** — `odoo:19.0`, the [Docker Official Image](https://hub.docker.com/_/odoo) from [github.com/odoo/odoo](https://github.com/odoo/odoo): HTTP workers on `8069`, gevent worker on `8072`, one cron worker.
- **`Postgres`** — Railway managed PostgreSQL: business data, module state, settings.
- **`odoo-proxy`** — `nginx:1.30-alpine`: public entrypoint, websocket routing, 128 MB uploads.

### Environment Variables Reference

| Variable | Service | What it does |
|---|---|---|
| `PGHOST` / `PGPORT` | odoo | Private address of Postgres |
| `PGUSER` / `PGPASSWORD` | odoo | Odoo's own role — never `postgres` |
| `PORT` | odoo | `8069`, the port Railway health-checks |
| `ODOO_ADMIN_PASSWD` | odoo | Master password guarding database create, backup and restore |
| `PORT` | odoo-proxy | `8080`, the port the public domain targets |
| `ODOO_UPSTREAM_HOST` | odoo-proxy | Private hostname of the Odoo service |

The libpq names matter: the image's entrypoint reads `PORT` as the *PostgreSQL* port, so `PG*` is used instead, freeing `PORT` for Railway.

Everything else is a file, not a variable: `odoo.conf` and the proxy's `nginx.conf` ship in the images, so tuning them is an edit and a redeploy. `list_db = False` and `dbfilter = ^odoo$` hide the database selector, `workers` selects the production multi-processing server, and `db_maxconn` caps connections *per process*.

### Deployment Dependencies

- Runtime: Python 3 (bundled), PostgreSQL 12+
- Source: [github.com/odoo/odoo](https://github.com/odoo/odoo), LGPL-3.0; add-ons: [OCA](https://github.com/OCA)
- Docs: [odoo.com/documentation](https://www.odoo.com/documentation/19.0/)

## Hardware Requirements for Self-Hosting Odoo

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2–4 vCPU |
| RAM | 1 GB | 4–8 GB |
| Storage | 5 GB volume | 20 GB+ volume |
| Database | PostgreSQL 12+ | Managed PostgreSQL 15+ |

Odoo's sizing rule is `(cores × 2) + 1` workers at 4–6 concurrent users each, and scaling is vertical — the filestore volume binds the service to a single replica. `limit_memory_soft` / `limit_memory_hard` are absolute numbers, not container-aware: four processes at the 2 GiB / 2.5 GiB defaults budget ~10 GiB inside an 8 GiB container. `db_maxconn` is per process too — four at the default 64 ask for 256 connections against `max_connections = 100`.

## Self-Hosting Odoo with Docker

The minimum stack is Odoo plus PostgreSQL, on a shared Docker network:

```
docker run -d --name odoo-db --network odoo-net \
  -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=change-me \
  -v odoo-db-data:/var/lib/postgresql/data postgres:16

docker run -d --name odoo --network odoo-net -p 8069:8069 -p 8072:8072 \
  -e PGHOST=odoo-db -e PGUSER=odoo -e PGPASSWORD=change-me \
  -v odoo-filestore:/var/lib/odoo \
  -v "$PWD/odoo.conf:/etc/odoo/odoo.conf" odoo:19.0
```

The mounted `odoo.conf` holds the production settings:

```
[options]
admin_passwd = 
data_dir = /var/lib/odoo
gevent_port = 8072
proxy_mode = True
workers = 2
db_maxconn = 8
dbfilter = ^odoo$
db_name = odoo
list_db = False
without_demo = True
```

Note `without_demo = True`: the `all` value is rejected in a 19.0 config file.

## How Much Does Odoo Cost to Self-Host?

Odoo Community Edition is free and open source under LGPL-3.0 — no per-user fee, no seat count. Odoo's hosted Enterprise plans run roughly $25–$76 per user per month by region and tier, which is what self-hosting avoids. On Railway you pay only for the compute, memory, volume and database the stack uses, so cost tracks workers and filestore size, not headcount.

## FAQ

**What is Odoo?**
An open-source suite of business apps — CRM, sales, invoicing, inventory, accounting, project and HR — built on Python and PostgreSQL. Community Edition is LGPL-3.0 and free to self-host.

**What does this Railway template deploy?**
The official `odoo:19.0` image with a filestore volume, Railway-managed PostgreSQL, and an `nginx:1.30-alpine` proxy that owns the public domain.

**Why does the template include a separate nginx service?**
Odoo serves its real-time bus on `8072` while HTTP stays on `8069`, and a Railway domain maps to one port — so nginx does the path split. Without it, live updates fail on a healthy-looking deployment.

**Which PostgreSQL user should self-hosted Odoo connect as?**
Not `postgres` — Odoo aborts on that name. Use a dedicated role with `CREATEDB` and no superuser rights. PostgreSQL is Odoo's only supported database; any reachable 12+ works.

**What is the default Odoo login, and what is the master password?**
First boot creates an administrator with the credentials `admin` / `admin` — change it immediately. `admin_passwd` is a separate master password guarding database create, backup and restore.

**How do I send email from self-hosted Odoo?**
Nothing outbound is configured, so invitations and password resets queue and fail. Add an outgoing mail server under *Settings → Technical*.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — [Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [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/odoo-railway
