Skip to content

How to Deploy Dockerized MCP Servers to Railway

You have built a powerful MCP server (likely for SAP, Oracle, or another legacy system), and it runs perfectly in Docker on your machine. Now you need it running 24/7 so your Agents can access it from anywhere.

We recommend Railway for this. Unlike other cloud providers, Railway has excellent support for raw Dockerfiles and handles the complex networking automatically.


🛑 Prerequisite: Make your Code “Cloud Aware”

Section titled “🛑 Prerequisite: Make your Code “Cloud Aware””

Before you deploy, you must ensure your Python script listens on the port Railway assigns to it. Railway injects a PORT environment variable (e.g., 5678) that you cannot predict.

Change your server startup logic to look like this:

if __name__ == "__main__":
import os
# 1. Get the PORT from Railway (Default to 8000 for local testing)
port = int(os.environ.get("PORT", 8000))
# 2. Bind to 0.0.0.0 (CRITICAL: 'localhost' will not work in the cloud)
mcp.run(transport='sse', host='0.0.0.0', port=port)

Ensure you expose the default port so Railway’s health checks pass.

EXPOSE 8000

Since we are using the CLI to upload your files (see below), we must prevent “heavy” local folders from being sent to the cloud.

Create a .dockerignore file in your root folder:

.dockerignore
.git
.env
venv/
node_modules/
__pycache__/
*.pyc
.DS_Store

Section titled “🚀 Deployment Strategy: The “Copyright Safe” Method”

If you are deploying an SAP or Oracle integration, you likely have a folder named nwrfcsdk or instantclient in your project.

⚠️ DANGER: You cannot commit these folders to a public GitHub repository. They are proprietary, licensed binaries.

Instead of using GitHub, we will use the Railway CLI. This uploads your local folder (including the SDK) directly to Railway’s secure build server without ever exposing it on public source control.

Open your terminal and install the tool.

Terminal window
# macOS / Linux
npm i -g @railway/cli
# Windows (via Scoop)
scoop install railway

Navigate to your project folder (where your Dockerfile is).

Terminal window
# Login to your account
railway login
# Create a new project space
railway init
# > Select "Empty Project"
# > Name it "sap-mcp-server"

This command zips up your current folder (respecting .dockerignore) and sends it to the cloud.

Terminal window
railway up

You will see a build log stream in your terminal. Railway is now building your Docker container using your local files (including the SAP SDK).


⚙️ Configuration (Environment Variables)

Section titled “⚙️ Configuration (Environment Variables)”

Your code likely needs credentials (like SAP_USER, SAP_PASSWORD). Never hardcode these.

  1. Go to your Railway Dashboard.
  2. Click on your project card.
  3. Navigate to the Variables tab.
  4. Click Raw Editor and paste your .env file content:
SAP_ASHOST=192.168.1.50
SAP_SYSNR=00
SAP_CLIENT=100
SAP_USER=MY_BOT_USER
SAP_PASS=Secret123

Note regarding VPNs: If your SAP system is on-premise, you cannot reach 192.168.x.x from the cloud directly. You must add the NordLayer or Tailscale service to your Railway project to bridge the network.


Before connecting your agent, check the logs to ensure the server started correctly.

  1. Click on your service in the Railway canvas.
  2. Click the Deployments tab and select the active deployment.
  3. Click View Logs.
  4. You should see a message similar to: INFO: Uvicorn running on http://0.0.0.0:PORT

If you see this, your “Bridge” is live!


Once the deployment finishes (green checkmark), you need the public URL.

  1. Go to the Settings tab in Railway.
  2. Under Networking, click Generate Domain.
  3. You will get a URL like: https://sap-mcp-server-production.up.railway.app.

Update your Agent code (CrewAI / LangGraph) to point to this new secure endpoint:

# In your local agent.py
remote_mcp = "[https://sap-mcp-server-production.up.railway.app/sse](https://sap-mcp-server-production.up.railway.app/sse)"
sap_agent = Agent(
role="SAP Specialist",
# ...
mcps=[remote_mcp]
)

  • Error: Standard_C_Plus_Plus or glibc not found:

    • Cause: You are likely using an Alpine Linux image (FROM python:alpine).
    • Fix: SAP requires standard libraries found in Debian. Always use FROM python:3.10-slim or FROM python:3.10-bookworm.
  • Build Failed (Missing Files):

    • Cause: You might be deploying via GitHub instead of the CLI. GitHub ignores files listed in .gitignore (usually including proprietary SDKs).
    • Fix: Ensure you use railway up to upload the files directly from your disk.
  • App Crashing (Error R10):

    • Cause: This usually means you didn’t bind to 0.0.0.0 or didn’t use the os.environ.get("PORT") variable. Check the code snippet in Prerequisite #1.

  • Status: ✅ Verified
  • Method: Docker / Railway CLI
  • Auditor: AgentRetrofit CI/CD

Transparency: This page contains affiliate links.