Deploy a Docker Compose App to Production
Railway does not run docker-compose.yml files directly. Instead, each service defined in your Compose file maps to a separate Railway service within a project. The sections below walk through that translation so you can take an existing Compose setup and deploy it to production without managing servers.
How Compose maps to Railway
| Compose concept | Railway equivalent |
|---|---|
services: entry | Railway service |
build: | Deploy from GitHub repo with a Dockerfile |
image: | Deploy from a Docker image |
ports: | Public networking (external) or automatic private networking (internal) |
volumes: | Railway Volumes |
networks: | Automatic private networking (no config needed) |
environment: / env_file: | Railway Variables |
depends_on: | No direct equivalent. Applications should handle connection retries at startup. |
Prerequisites
- A working
docker-compose.yml - A Railway account
- The Railway CLI installed (optional, but useful for setting variables)
1. Create a Railway project
Open the Railway dashboard and click + New Project. Choose Empty project. This project will hold all of the services that correspond to your Compose file.
2. Add services
Work through each entry under services: in your Compose file and create a matching Railway service.
Services with a Dockerfile or build context
If a Compose service uses build:, it has source code and a Dockerfile. To deploy it on Railway:
- Push the code to a GitHub repository.
- In your Railway project, click + New and select GitHub Repo.
- Choose the repository and branch.
- If the Dockerfile is not in the repository root, set the Root Directory or add a Dockerfile Path in the service settings under Build Configuration.
Railway will build the image from the Dockerfile on every push to the selected branch.
Services using a Docker image
If a Compose service uses image: (for example, image: redis:7-alpine), deploy it as follows:
- In your Railway project, click + New and select Docker Image.
- Enter the image name and tag, such as
redis:7-alpine.
Database services
For common databases like Postgres, MySQL, Redis, and MongoDB, use Railway's managed database services instead of raw Docker images. Managed databases include automatic backups, connection pooling, and a dashboard.
- In your Railway project, click + New and select Database.
- Choose the database type (Postgres, MySQL, Redis, or MongoDB).
Railway provisions the database and exposes connection variables automatically. This replaces Compose services like:
See the databases documentation for more detail.
3. Configure environment variables
Compose files define environment variables in environment: blocks or reference external files with env_file:. On Railway:
- Open a service's Variables tab.
- Add each variable individually, or click Raw Editor to paste multiple variables at once (one
KEY=VALUEper line).
For variables that reference another service (for example, a DATABASE_URL that points to Postgres), use Railway reference variables. Reference variables stay in sync when connection details change.
Example: instead of hardcoding DATABASE_URL=postgres://user:pass@db:5432/myapp, create a reference variable that pulls the value from the Postgres service's DATABASE_URL variable.
4. Set up networking
Private networking
In a Compose file, services communicate over a shared Docker network using the service name as the hostname. Railway works similarly. Every service in a project can reach other services over the private network at:
No manual network configuration is needed. Private networking is automatic. See Private Networking for details.
Note: Use the port your application actually listens on when connecting over the private network. There is no port mapping layer.
Public networking
For services that need to be reachable from the internet (for example, a web server):
- Open the service's Settings tab.
- Under Networking, click Generate Domain to get a Railway-provided domain.
This replaces the ports: mapping in your Compose file. See Domains for custom domains and other options.
5. Attach volumes
If your Compose file uses named volumes for persistent data, create a Railway Volume for each one:
- Open the service's Settings tab.
- Under Volumes, click Add Volume.
- Set the Mount Path to match the path in your Compose file (for example,
/var/lib/postgresql/data).
Railway Volumes persist across deploys and restarts. Note that volumes are not available during the build step, only at runtime.
If you replaced a database image with a Railway managed database, you do not need to attach a volume. Railway handles storage for managed databases.
See Volumes for more detail.
6. Verify the deployment
After all services are configured:
- Check the Deploy Logs for each service to confirm it started without errors.
- If you generated a public domain, open it in a browser or send a request with
curlto verify the service responds. - For services that depend on a database, confirm the connection by checking logs for successful queries or running a health check endpoint.
Example: translating a Compose file
Consider this docker-compose.yml:
This translates to three Railway services:
1. Postgres database (managed)
Add a Postgres database from the Railway dashboard. Railway creates the database, provisions credentials, and exposes a DATABASE_URL variable. No volume configuration is needed.
2. Redis database (managed)
Add a Redis database from the Railway dashboard. Railway exposes a REDIS_URL variable automatically.
3. Web service (from GitHub)
Deploy from your GitHub repository. Railway detects the Dockerfile and builds the image. In the service's Variables tab, set:
DATABASE_URLas a reference variable pointing to the Postgres service'sDATABASE_URL.REDIS_URLas a reference variable pointing to the Redis service'sREDIS_URL.
Generate a public domain under Networking so the web service is accessible externally.
The depends_on directive has no Railway equivalent. If the web service starts before the database is ready, it should retry the connection. Most database client libraries and ORMs support this through connection retry configuration.
Next steps
- Private Networking - Learn how services communicate within a project.
- Manage Volumes - Attach persistent storage to services.
- Add a Database Service - Provision managed databases.
- Monitor your app - View logs, metrics, and traces.