Railway

Deploy Operately

Deploy Operately, open-source goal and project tracking

Deploy Operately

/var/lib/postgresql/data

/media

Operately for railway.app

Template Header

Deploy Operately on Railway with one click.

Deploy on Railway

Deploy and Host Operately on Railway

Operately is an open-source goal, project, and OKR tracking tool that replaces status-update meetings with structured check-ins. This template runs the official operately/operately Docker image on Railway, backed by a separate Postgres service for data storage.

About Hosting Operately

Hosting Operately on Railway means running its Elixir/Phoenix release container next to a managed Postgres instance, with Railway generating the domain, terminating TLS, and running the database migration automatically before every deploy — no server to patch, no reverse proxy to configure by hand.

Why Deploy Operately on Railway

  • No server provisioning — Railway builds and runs the container from the pinned upstream image
  • Postgres attaches as a managed service instead of a self-hosted database to babysit
  • TLS and the domain are handled at Railway's edge, so OPERATELY_HOST only needs a hostname
  • Migrations run automatically on every deploy via preDeployCommand, no manual SSH step
  • Renovate keeps the pinned image tag current without floating on latest

Common Use Cases

  • Replacing weekly status-update meetings with asynchronous written check-ins
  • Tracking OKRs and project goals with automatic progress roll-ups across a company
  • Giving leadership a single, always-current view of who owns what and how it is progressing

Dependencies for Operately

  • Image: operately/operately:1.8.0 (official upstream image, pinned tag)
  • Database: PostgreSQL, provisioned as a separate Railway service and wired in via the DATABASE_URL reference variable — there is no SQLite fallback
  • Volume: a Railway volume mounted at /media for uploaded files
  • License note: Operately's core is Apache-2.0; a separate proprietary license covers its ee/ (Enterprise Edition) subtree. This template only references the published Docker image, it does not build or redistribute the source.

🚀 Quick Start

  1. Click "Deploy on Railway"
  2. Add a Postgres service to the project and reference it as DATABASE_URL (see below)
  3. Set the remaining environment variables listed below
  4. Attach a volume at /media before sending production traffic
  5. Wait for the build — preDeployCommand creates the database and runs migrations automatically — then open the generated URL

⚙️ Configuration

Environment variables

DATABASE_URL=${{Postgres.DATABASE_URL}}     # reference to a separate Postgres service
SECRET_KEY_BASE=generate-a-secret           # Railway "generate" button; signs/encrypts cookies
OPERATELY_BLOB_TOKEN_SECRET_KEY=generate-a-secret   # signs file/blob URLs
SYSTEM_SETTINGS_ENCRYPTION_KEYS=generate-a-secret   # encrypts stored settings
OPERATELY_HOST=${{RAILWAY_PUBLIC_DOMAIN}}   # bare hostname, no scheme or port
OPERATELY_URL_SCHEME=https
ALLOW_LOGIN_WITH_EMAIL=yes    # without this + no Google OAuth, nobody can log in
ALLOW_SIGNUP_WITH_EMAIL=yes
CERT_DOMAIN=""                # must be set (empty string, not unset) — see below
CERT_EMAILS=""
CERT_DB_DIR=/opt/operately/certs

Set real values as Railway variables, never in a file in this repo. PORT defaults to 4000 and Railway sets it for you. requiredMountPath = "/media" in railway.toml — attach a volume there before production traffic, or uploads are lost on every redeploy.

🐳 Local Development

git clone https://github.com/vergissberlin/railwayapp-operately.git
cd railwayapp-operately
cp .env.example .env
docker compose up -d
docker compose exec operately /opt/operately/bin/create_db
docker compose exec operately /opt/operately/bin/migrate

preDeployCommand only runs on Railway, so run the two commands above by hand locally. Then open http://localhost:4000.

🤝 Contributing

Found a bug? Open an issue or a pull request. See CONTRIBUTING.md.

📝 License

MIT — see LICENSE.

Railway runtime defaults

  • Healthcheck /health · Restart ON_FAILURE (10 retries) · Dockerfile build · TLS at Railway's edge, credentials only ever set as variables, never committed
  • preDeployCommand runs predeploy.sh (create_db then migrate) — Railway only accepts one command, so chaining needed a real script, not a &&-joined string
  • Operately reads $PORT directly, no start command or entrypoint wrapper needed
  • CERT_DOMAIN/CERT_EMAILS/CERT_DB_DIR are set even though no real TLS cert is used here: Operately's cert-management child validates and chmods these at every boot regardless of CERT_AUTO_RENEW, and unset values crash the app. Empty strings for the first two match the official installer's own "skip TLS" path; CERT_DB_DIR=/opt/operately/certs is a nobody-owned folder baked into the image, kept outside /media (a volume's contents replace whatever the Dockerfile put at its mount path, so it isn't there by boot time).

📚 Resources


Airbyte Apache Airflow CloudBeaver CodiMD Django Email Service FastAPI Flask Flowise GitLab CE Grafana Home Assistant InfluxDB MJML MongoDB Mosquitto MQTT MySQL n8n Node.js Node-RED OpenSearch Open WebUI Operately Outerbase Studio PostgreSQL Redis TYPO3 CMS


Template Content

More templates in this category

View Template
Rocky Linux
[Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
40
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51