Prerequisites
- A Railway account
- Your project pushed to a public or private GitHub repository
- Your project built with
pipes init(which generates aDockerfileanddocker-compose.yaml)
Option A — Drag & Drop via the Railway Dashboard
The quickest way to get started is to drop yourdocker-compose.yaml directly onto the Railway project canvas.
Step 1 — Create a new project on Railway
- Go to railway.app/new and click Empty Project.
Step 2 — Drag and drop your docker-compose.yaml
- Open your project canvas.
- Drag the
docker-compose.yamlfile from your project root and drop it anywhere on the canvas.
| Service | Image / Source |
|---|---|
| Your indexer | Built from your local Dockerfile |
postgres or clickhouse | Official Docker images |
Step 3 — Link the indexer service to your GitHub repository
- Click the indexer service card on the canvas.
- Go to Settings → Source and choose GitHub Repo.
- Select your repository and branch.
Step 4 — Add the Pipe UI service
- Click + New Service on the canvas.
- Choose Docker Image and enter
iankguimaraes/pipe-ui:latest. - Go to the service’s Variables tab and add:
Replace
Pipeswith the actual name Railway assigned to your indexer service.
Step 5 — Generate public domains
For each service that needs a public URL:- Click the service card.
- Go to Settings → Networking → Public Networking.
- Click Generate Domain and set the correct port (
3000for Pipe UI,5432for PostgreSQL,8123for ClickHouse).
Option B — Railway CLI
If you prefer the terminal, the Railway CLI gives you full control over every service and environment variable.Step 1 — Install the Railway CLI
Step 2 — Log in to Railway
Step 3 — Initialize the Railway project
Run this from the root of your indexer project:name field in your package.json. This creates a new project on Railway and links the current directory to it.
Step 4 — Add the database service
If your project uses PostgreSQL (projects withdrizzle.config.ts):
DATABASE_URL variable automatically.
If your project uses ClickHouse:
Step 5 — Add the indexer service
Replaceyour-org/your-repo with your actual GitHub repository slug.
PostgreSQL project:
Note on variable syntax:The${{ServiceName.VARIABLE}}is Railway’s cross-service reference syntax. The shell requires escaping the$as\$when passing it through the CLI; Railway resolves it at runtime.
--repo flag links this service to your GitHub repository and enables automatic deployments on every push to the default branch.
Step 6 — Add the Pipe UI dashboard
Step 7 — Generate public domains
Give each service a publicly accessible URL: PostgreSQL project:Step 8 — Open the Railway dashboard
Service Architecture
${{ServiceName.RAILWAY_PRIVATE_DOMAIN}} references. Only the UI (and optionally the database) need public domains.
Environment Variables Reference
Indexer (PostgreSQL)
| Variable | Value |
|---|---|
DB_CONNECTION_STR | ${{Postgres.DATABASE_URL}} |
Indexer (ClickHouse)
| Variable | Value |
|---|---|
CLICKHOUSE_URL | http://${{Clickhouse.RAILWAY_PRIVATE_DOMAIN}}:8123 |
CLICKHOUSE_DB | pipes |
CLICKHOUSE_USER | default |
CLICKHOUSE_PASSWORD | password |
ClickHouse service
| Variable | Value |
|---|---|
CLICKHOUSE_DB | pipes |
CLICKHOUSE_USER | default |
CLICKHOUSE_PASSWORD | password |
Pipe UI
| Variable | Value |
|---|---|
METRICS_SERVER_URL | ${{Pipes.RAILWAY_PRIVATE_DOMAIN}}:9090 |
Dockerfile Overview
Your project’sDockerfile (generated by pipes init) uses a two-stage build:
- Builder stage — installs dependencies with
pnpm, compiles TypeScript todist/. - Runner stage — copies only the production build, runs migrations (PostgreSQL only), then starts the indexer.
Troubleshooting
Indexer fails to start — cannot connect to database The database service may not be healthy yet. Railway starts services in parallel; the indexer’s health-check retry logic should handle this, but you can also set a startup delay under Settings → Deploy → Start Command.${{...}} variables show as literal strings
Cross-service references are resolved at deploy time. Make sure both services are in the same Railway project and the referenced service name matches exactly (case-sensitive).
ClickHouse connection refused
Confirm CLICKHOUSE_URL uses the private domain (RAILWAY_PRIVATE_DOMAIN), not a public URL, and that port 8123 is correct.
Pipe UI shows no data
Check that METRICS_SERVER_URL points to the private domain of the indexer service and that port 9090 is included.