---
title: "Deploy OpenProject"
description: "Open source project management with Gantt charts and agile boards"
category: "Other"
url: https://railway.com/deploy/openproject-server
---

# Deploy OpenProject

Open source project management with Gantt charts and agile boards

**[Deploy OpenProject on Railway](https://railway.com/template/openproject-server)**

- **Creator:** A3A
- **Category:** Other

## Template content

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

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

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

- **Image:** openproject/openproject:17-slim
- **Start command:** `/bin/bash -c "exec ./docker/prod/cron"`

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

- **Image:** redis:8.2
- **Start command:** `/bin/sh -c "rm -rf $RAILWAY_VOLUME_MOUNT_PATH/lost+found/ && exec docker-entrypoint.sh redis-server --requirepass $REDIS_PASSWORD --save 60 1 --dir $RAILWAY_VOLUME_MOUNT_PATH"`

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

- **Image:** openproject/openproject:17-slim
- **Start command:** `/bin/bash -c "until ./docker/prod/seeder; do echo '[boot] seeder failed; retrying in 10s'; sleep 10; done; exec ./docker/prod/web"`
- **Health check:** /health_checks/all

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

- **Source:** https://github.com/gridalpha/openproject-railway
- **Health check:** /healthz
- **Public domain:** Yes

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

- **Image:** openproject/openproject:17-slim
- **Start command:** `/bin/bash -c "exec bundle exec good_job start"`
- **Health check:** /status/connected

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

- **Image:** openproject/hocuspocus:17.7
- **Health check:** /

## Buckets

- **openproject-attachments**

## Documentation

![OpenProject logo](https://www.openproject.org/assets/images/cover/openproject-home-5ab8cc23.jpg)

# Deploy and Host OpenProject on Railway

OpenProject is open source project management software for teams that plan real work: work packages with hierarchies and custom fields, Gantt charts, Scrum and Kanban boards, a team planner, meetings with agendas, wikis, and time and cost tracking. It shares Redmine's Ruby on Rails lineage but has moved well past it, with an Angular front end and a documented REST API. Teams self-host OpenProject for data residency, for classic scheduling beside agile boards, or because per-seat pricing stops adding up. Deploy OpenProject on Railway and you get the Community edition in full — GPL-licensed, no seat limit, no trial clock.

It runs the multi-process topology OpenProject documents for production, not a single all-in-one container. A Caddy service is the public entry point and the only thing exposed to the internet. Behind it sit a Puma web service, a GoodJob worker, a scheduler for inbound email, and a Hocuspocus websocket server for collaborative editing. PostgreSQL holds every record, Redis is the shared Rails cache, and an object storage bucket holds attachments — which is what lets web and worker read each other's uploads without a shared disk.

![Diagram of the OpenProject services deployed on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1788056912/openproject-architecture.png)

## Getting Started with OpenProject on Railway

Open the public URL and you land on the sign-in page. Log in as `admin` with the password from `OPENPROJECT_SEED_ADMIN_USER_PASSWORD`; if you left the generated default, copy it from that variable in the Railway dashboard. OpenProject forces a password change on that first sign-in, and the replacement needs ten characters with upper and lower case, a digit and a symbol. Pick a language and the home screen appears with a seeded demo project.

Open **Demo project → Work packages**, create one of your own, give it a description and attach a file. That attachment is the best end-to-end check: the browser uploads straight to object storage and the app signs the download link, so a file that comes back proves the database, the bucket and the front end are all wired. Switch to **Gantt charts** to confirm scheduling renders, then use **Administration → Users & permissions** to invite your team.

![OpenProject work package table showing a conference project plan](https://res.cloudinary.com/rroe4rtk/image/upload/v1788056915/openproject-work-packages.png)

![Work package detail with a description and an attached CSV file](https://res.cloudinary.com/rroe4rtk/image/upload/v1788056916/openproject-work-package-attachment.png)

![OpenProject Gantt chart with conference tasks and milestones](https://res.cloudinary.com/rroe4rtk/image/upload/v1788056920/openproject-gantt-chart.png)

## About Hosting OpenProject

OpenProject is a full project management suite, not an issue tracker with extras bolted on. One instance carries a portfolio of projects, each with its own modules, roles and workflows, and rolls them into shared views.

- Work packages with hierarchies, custom fields and type-specific workflows
- Gantt charts with dependencies, baselines and automatic scheduling
- Scrum backlogs, sprints, action boards and a drag-and-drop team planner
- Meetings with recurring series and linked work packages
- Wikis, documents, attachments, budgets and time tracking
- REST API v3, OAuth 2 applications and webhooks

The deployment splits OpenProject the way its own production compose file does. The web service answers browser and API traffic. The worker runs GoodJob, which executes exports, notification digests and scheduled cleanups — without it the app looks fine while long-running actions never finish. The scheduler polls an IMAP mailbox so email replies become work packages, and stays idle until configured. Caddy routes `/hocuspocus` to the websocket server and everything else to the app, because the browser must reach both on one origin.

## Why Deploy OpenProject on Railway

Railway removes the infrastructure work that self-hosting OpenProject normally involves.

- Managed PostgreSQL, Redis and object storage, provisioned with the app
- Private networking between services; only the Caddy entry point is public
- HTTPS and a domain on first deploy, custom domains a few clicks away
- Migrations run on every deploy, so upgrades are just a redeploy
- Per-service logs, metrics and health checks, no monitoring stack to run

## Common Use Cases

- Replacing a per-seat Jira or Asana subscription with an instance your team owns
- Agency and client projects where scope, budget and logged time live in one place
- Coordinating a roadmap in Gantt view while squads work day to day on Kanban boards
- Public-sector, healthcare and research work whose data residency rules out SaaS

## Dependencies for OpenProject

- `openproject/openproject:17-slim` — the Rails application, shared by the web, worker and scheduler services ([opf/openproject](https://github.com/opf/openproject))
- `openproject/hocuspocus:17.7` — collaborative editing websocket server
- `caddy:2-alpine` — the public entry point, built from [gridalpha/openproject-railway](https://github.com/gridalpha/openproject-railway)
- PostgreSQL 13+ — every project, work package and comment record
- Redis — the shared Rails cache
- S3-compatible object storage — attachments, shared by every application process

### Environment Variables Reference

| Variable | Purpose |
|---|---|
| `SECRET_KEY_BASE` | Signs sessions and cookies. Identical on all three application services, and never changed. |
| `OPENPROJECT_HOST__NAME` | Public hostname. Also arms host-header checking, so add a custom domain to `OPENPROJECT_ADDITIONAL__HOST__NAMES` too. |
| `OPENPROJECT_SEED_ADMIN_USER_PASSWORD` | Password for the first `admin` account, read once while the user table is empty. |
| `OPENPROJECT_SELF__REGISTRATION` | `0` off, `1` admin approval, `2` email activation, `3` open. Defaults to `0`. |
| `OPENPROJECT_ATTACHMENTS__STORAGE` | `fog` sends attachments to object storage instead of local disk. |
| `OPENPROJECT_SMTP__ADDRESS` | Outgoing mail relay. Unset by default, which disables email. |

### Deployment Dependencies

- Source: [github.com/opf/openproject](https://github.com/opf/openproject)
- Images: [openproject/openproject](https://hub.docker.com/r/openproject/openproject), [openproject/hocuspocus](https://hub.docker.com/r/openproject/hocuspocus)
- Docs: [openproject.org/docs](https://www.openproject.org/docs/), [configuration reference](https://www.openproject.org/docs/installation-and-operations/configuration/)

## Hardware Requirements for Self-Hosting OpenProject

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU total | 4 vCPU |
| RAM | 4 GB total | 8 GB, 4 GB of it for the worker |
| Storage | 10 GB Postgres | 20 GB plus object storage |
| Runtime | Ruby 4 (in the image) | PostgreSQL 13+, Redis 7+ |

The worker is the memory-hungry process, because PDF and Excel exports are built in RAM. If exports fail on large projects, raise its memory first.

## Self-Hosting OpenProject with Docker

Upstream publishes a production compose file:

```
git clone https://github.com/opf/openproject-docker-compose
cd openproject-docker-compose
cp .env.example .env
docker compose up -d
```

The all-in-one image takes one command, but bundles its own PostgreSQL and is not a production shape:

```
docker run -d -p 8080:80 --name openproject \
  -e OPENPROJECT_HOST__NAME=localhost:8080 \
  -e OPENPROJECT_SECRET_KEY_BASE=$(openssl rand -hex 64) \
  -v /var/lib/openproject/pgdata:/var/openproject/pgdata \
  -v /var/lib/openproject/assets:/var/openproject/assets \
  openproject/openproject:17
```

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

The Community edition is free and GPLv3-licensed, with no user cap and no time limit, and it is what this template deploys. The Enterprise on-premises add-on unlocks extras such as custom themes, baseline comparison and enforced 2FA, at roughly €5.95 per member per month with a 25-user floor. Self-hosting on Railway costs only the compute, database and storage you use.

## FAQ

**What is OpenProject?**
Open source project management software covering work packages, Gantt scheduling, agile boards, meetings, wikis, and time and cost tracking. GPLv3-licensed and self-hostable in full.

**What does this Railway template deploy?**
A Caddy entry point, the OpenProject web application, a GoodJob worker, an inbound-mail scheduler, a Hocuspocus collaborative editing server, PostgreSQL, Redis, and an object storage bucket.

**Why does the template include a separate worker service?**
OpenProject runs exports, notification digests and scheduled cleanups as background jobs. Without a worker the interface loads but those jobs never run.

**Why is object storage used instead of a disk volume?**
The web, worker and scheduler processes all read and write attachments, and a Railway volume attaches to exactly one service. Object storage gives all three the same files.

**How do I add users to self-hosted OpenProject?**
Self-registration ships disabled. Use Administration → Users & permissions to invite people, or set `OPENPROJECT_SELF__REGISTRATION` to `1` for admin-approved signups or `2` for email activation, which needs SMTP first.

**How do I enable email notifications in self-hosted OpenProject?**
Set `OPENPROJECT_EMAIL__DELIVERY__METHOD=smtp` plus `OPENPROJECT_SMTP__ADDRESS`, `OPENPROJECT_SMTP__PORT`, `OPENPROJECT_SMTP__USER__NAME` and `OPENPROJECT_SMTP__PASSWORD` on all three application services, then send a test mail from Administration → Emails and notifications.

**Do I need the Enterprise edition?**
No. Everything above is Community edition, and the instance keeps working as it is without a licence key.


## 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) — 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/openproject-server
