How to Deploy Multiple Services from Same Directory with Different Dockerfiles?
rubenszinho
PROOP

2 months ago

Problem

I have a monorepo structure where two Railway servicesvizionari-api and celery-worker) are located in the same directorypython_backend/) but need to use different Dockerfiles.

Current Directory Structure

python_backend/

├── docker/

│   ├── Dockerfile.api       # For vizionari-api service

│   └── Dockerfile.celery     # For celery-worker service

├── app/

├── railway.api.toml          # Config for API

├── railway.celery.toml       # Config for Celery

└── deploy.sh                 # Workaround script

Current Configuration Files

railway.api.toml:

[build]

builder = "dockerfile"

dockerfilePath = "docker/Dockerfile.api"

[deploy]

numReplicas = 1

restartPolicyType = "always"

railway.celery.toml:

[build]

builder = "dockerfile"

dockerfilePath = "docker/Dockerfile.celery"

[deploy]

numReplicas = 1

restartPolicyType = "always"

Current Workaround (Works but Not Ideal)

I created a deploy.sh script that temporarily copies the correct config:

#!/bin/bash

# For API service

cp railway.api.toml railway.toml

railway up --service vizionari-api --environment production

# For Celery service  

cp railway.celery.toml railway.toml

railway up --service celery-worker --environment production

rm railway.toml  # Cleanup

This works for manual/CI deployments, but prevents using Railway's native GitHub integration and automatic PR environments.

What I Want to Achieve

I want to:

1. Keep both services in the same directory python_backend/)

2. Use different Dockerfiles for each service

3. Use Railway's native GitHub integration

4. Support automatic PR environments

5. Avoid temporary file manipulation

Questions

1. Can I specify different railway.toml configs per service?

Is there a way to tell Railway: "For service A, use railway.api.toml, for service B, use railway.celery.toml"?

Something like:

railway up --service vizionari-api --config railway.api.toml

railway up --service celery-worker --config railway.celery.toml

2. Can services reference configs from parent directory?

Could I structure it like this?

python_backend/

├── docker/

├── app/

├── railway.toml              # Shared config

└── services/

    ├── api/

    │   └── railway.toml      # API-specific overrides

    └── celery/

        └── railway.toml      # Celery-specific overrides

3. Alternative approaches?

Are there any recommended patterns for:

- Multiple services in the same directory

- Different build configurations per service

- Maintaining GitHub integration

Why This Matters

This setup prevents me from:

- Using Railway's automatic GitHub deployments

- Creating dynamic PR environments via GitHub Actions

- Having a clean, maintainable deployment workflow

Any guidance would be greatly appreciated!

Environment:

- Railway CLI: latest

- Project: Monorepo with FastAPI + Celery

- Deployment: GitHub Actions + Manual via CLI

Solved$10 Bounty

6 Replies

Railway
BOT

2 months ago

Hey there! We've found the following might help you get unblocked faster:

If you find the answer from one of these, please let us know by solving the thread!


I think what you're looking for is RAILWAY_DOCKERFILE_PATH

You can set this environmental variable differently in each service and remove it entirely from railway.toml.


rubenszinho
PROOP

2 months ago

That's perfect, but whenever I try to create environments for PRs through actions, Dockerfiles arent being detected for some reason do you know what could be?

on:

  pull_request:

    types: [opened, synchronize, closed]

    paths:

      - 'python_backend/**'

env:

  RAILWAY_API_TOKEN: ${{ secrets.RAILWAY_API_TOKEN }}

  RAILWAY_PROJECT_ID: ${{ secrets.RAILWAY_PROJECT_ID }}

jobs:

  deploy-pr:

    if: github.event.action == 'opened' || github.event.action == 'synchronize'

    runs-on: ubuntu-latest

    container: ghcr.io/railwayapp/cli:latest

    steps:

      - uses: actions/checkout@v4

      - name: Create or Update PR Environment

        run: |

          PR_ENV="pr-${{ github.event.pull_request.number }}"

          railway link --project ${{ env.RAILWAY_PROJECT_ID }} --environment uat

          if railway environment list | grep -q "$PR_ENV"; then

            echo "Environment $PR_ENV already exists, updating..."

          else

            echo "Creating new environment $PR_ENV..."

            railway environment new "$PR_ENV" --copy uat

          fi

      - name: Deploy API Service

        working-directory: ./python_backend

        run: |

          PR_ENV="pr-${{ github.event.pull_request.number }}"

          railway up --service vizionari-api --environment "$PR_ENV" --detach

      - name: Deploy Celery Worker Service

        working-directory: ./python_backend

        run: |

          PR_ENV="pr-${{ github.event.pull_request.number }}"

          railway up --service celery-worker --environment "$PR_ENV" --detach

  cleanup-pr:

    if: github.event.action == 'closed'

    runs-on: ubuntu-latest

    container: ghcr.io/railwayapp/cli:latest

    steps:

      - name: Delete PR Environment

        run: |

          PR_ENV="pr-${{ github.event.pull_request.number }}"

          railway link --project ${{ env.RAILWAY_PROJECT_ID }} --environment uat

          railway environment delete "$PR_ENV" -y || true

I get this error

Attachments


Have you tried setting it to /docker/Dockerfile.celery?

I believe because your working directory is ./python_backend it's looking at ./python_backend/docker/Dockerfile.celery


samgordon

Have you tried setting it to /docker/Dockerfile.celery?I believe because your working directory is ./python_backend it's looking at ./python_backend/docker/Dockerfile.celery

rubenszinho
PROOP

2 months ago

yep, but I've solved now somehow by adding a railway link step before railway up. But that's weird nway, check the final working version:
name: Railway PR Environments

...

      - name: Create or Update PR Environment

        run: |

          railway link --project ${{ env.RAILWAY_PROJECT_ID }} --environment uat

          railway environment new "${{ steps.env.outputs.name }}" --copy uat || echo "Environment already exists"

      - name: Deploy API Service

        working-directory: ./python_backend

        run: |

          railway link --project ${{ env.RAILWAY_PROJECT_ID }} --environment "${{ steps.env.outputs.name }}"

          railway up --service vizionari-api --ci

      - name: Deploy Celery Worker Service

        working-directory: ./python_backend

        run: |

          railway link --project ${{ env.RAILWAY_PROJECT_ID }} --environment "${{ steps.env.outputs.name }}"

          railway up --service celery-worker --ci

...


Glad to hear it's solved!


Status changed to Solved sarahkb125 about 2 months ago


Loading...