Railway

Deploy mssql2019

Microsoft SQL Server 2019 with persistent storage and TCP access

Deploy mssql2019

Just deployed

mssql2019 — SQL Server 2019 on Railway

Deploy on Railway

A reusable Railway template that runs Microsoft SQL Server 2019 (Linux, mcr.microsoft.com/mssql/server:2019-latest) as a normal Railway service, working out of the box on a one-click deploy — no password juggling, no crash loops.

Verified running Microsoft SQL Server 2019 (RTM-CU32-GDR) - 15.0.4480.2 (X64) on Railway (EU West), queried successfully over TCP with sqlcmd.

> A SQL Server 2022 variant of this template lives at mssql2022.

What you get

  • SQL Server 2019 (Developer edition by default) listening on TCP 1433
  • Zero-config first boot: if no SA password is provided, a strong one is generated and printed to the deploy logs
  • Handles Railway's runtime quirks that crash-loop a vanilla SQL Server deployment (see Storage on Railway — important and How it works)
  • Connect from any MSSQL client: SSMS, Azure Data Studio, sqlcmd, or any driver (ODBC, JDBC, pyodbc, mssql npm package, Entity Framework, Prisma, etc.)

What this means in practice:

  • Great for: development databases, staging/preview instances, CI databases, learning and prototyping — anywhere a disposable, fully-managed SQL Server is useful.
  • Not for: primary production data. If you need persistence, run SQL Server somewhere with real block storage, or use a managed offering.

Do not attach a Railway volume at /var/opt/mssql — it is the one configuration that always crash-loops. The entrypoint detects this and prints a warning to the deploy logs.

Deploying

  1. Click the deploy button above (or go to ).
  2. Add a TCP Proxy under Service → Settings → Networking to reach SQL Server from your machine (public endpoint like .proxy.rlwy.net:).
  3. Deploy. Optionally set the variables below before the first deploy.

Environment variables

VariableRequiredDefaultDescription
MSSQL_SA_PASSWORDNoauto-generatedSA password. Only applies on first initialization. Must satisfy SQL Server complexity rules (8–128 chars, 3 of: uppercase, lowercase, digit, symbol).
ACCEPT_EULANoYSQL Server EULA acceptance. Baked in as a default; override if you need to.
MSSQL_PIDNoDeveloperEdition: Developer, Express, Standard, Enterprise, or a product key.
MSSQL_COLLATIONNoserver defaultCollation, applied on first initialization (e.g. SQL_Latin1_General_CP1_CI_AS).
MSSQL_DEBUGNounsetSet to 1 to print data-directory layout and disk diagnostics to the deploy logs before startup.

SA password behavior

SQL Server only reads the SA password when it initializes an empty data directory — this is official image behavior, not a template limitation. The entrypoint handles it as follows:

  1. If MSSQL_SA_PASSWORD (or legacy SA_PASSWORD) is set, it is used for initialization and saved to /var/opt/mssql/.sa_password.
  2. If no password is provided, a strong one is generated, saved, and printed to the deploy logs (visible under the deployment's Deployments → View Logs).
  3. On container restarts the stored password is reused. On a redeploy the filesystem starts fresh, the server re-initializes, and — if no password variable is set — a new password is generated and printed; you can't get locked out.
  4. Weak passwords are rejected at boot with a clear error message instead of an opaque crash loop.

The generated password is stored in plaintext at /var/opt/mssql/.sa_password inside the container.

Resource sizing

SQL Server 2019 wants a minimum of ~2 GB of memory. On Railway, give the service at least 2 GB RAM (Service → Settings → Resources) for reliable operation.

Connecting

After adding a TCP proxy, connect with any client using the public hostname and port Railway assigns (e.g. mono-packed-macaque.proxy.rlwy.net:31234):

# sqlcmd
sqlcmd -S .proxy.rlwy.net, -U sa -P '' -C -Q "SELECT @@VERSION"

# connection string
Server=.proxy.rlwy.net,;Database=master;User Id=sa;Password=;Encrypt=True;TrustServerCertificate=True;

Modern drivers (Microsoft.Data.SqlClient, ODBC Driver 18+, pyodbc 18+) default to encryption and will complain about the server's self-signed certificate — set TrustServerCertificate=True (or Encrypt=False / sqlcmd -No) unless you bring your own certificate.

From inside the container you can always reach the server at localhost:1433.

How it works

  • Dockerfile — based on mcr.microsoft.com/mssql/server:2019-latest, bakes in EULA acceptance and Developer edition defaults, installs entrypoint.sh, exposes 1433.
  • entrypoint.sh — resolves and validates the SA password, persists it for container restarts, prints the previous boot's crash reason and cleans up stale crash dumps (they are multi-gigabyte and will fill the disk), warns if a volume is mounted at the data path, then execs sqlservr as PID 1 so it shuts down cleanly on SIGTERM. It runs sqlservr as root — the configuration verified under Railway's gVisor runtime.

Local testing

docker build -t mssql2019 .
docker run -d --name mssql2019-test -p 1433:1433 mssql2019
docker logs -f mssql2019-test   # shows the generated SA password

Then connect with sqlcmd -S localhost,1433 -U sa -P '' -C.

License

MIT

Deploy and Host

SQL Server 2019 on Railway — a one-click template that runs Microsoft SQL Server 2019 (Linux, the official mcr.microsoft.com/mssql/server:2019-latest image) as a Railway service listening on TCP 1433, hardened for Railway's runtime so it actually starts and stays up instead of crash-looping like a vanilla deployment. Verified end-to-end on Railway: the server initializes cleanly, accepts queries from sqlcmd over TCP, and reports Microsoft SQL Server 2019 (RTM-CU32-GDR) - 15.0.4480.2 (X64).

Deploy on Railway

About Hosting

You are hosting one service:

  • mssql — SQL Server 2019 (Developer edition by default) from the official Microsoft Docker image, listening on TCP 1433, with its data on the container filesystem.

Configured environment variables: ACCEPT_EULA=Y (EULA acceptance), MSSQL_PID=Developer (free for development/testing; switch to Express, Standard, Enterprise, or a product key), and optionally MSSQL_SA_PASSWORD (SA password, applied on first initialization) and MSSQL_COLLATION (server collation).

After deploying: copy the SA password from the deploy logs (or set MSSQL_SA_PASSWORD yourself before the first deploy), add a TCP Proxy under Settings → Networking to get a public endpoint like .proxy.rlwy.net:, and connect with any MSSQL client — SSMS, Azure Data Studio, sqlcmd, ODBC/JDBC, pyodbc, Entity Framework, Prisma, or the mssql npm package. Give the service at least 2 GB of RAM; SQL Server will not run comfortably below that.

Storage note: SQL Server on Railway uses the container filesystem, which is ephemeral — databases live until the service is redeployed. Railway runs containers under gVisor, and SQL Server crashes mid-initialization when its state is placed on a Railway volume, so persistent storage is not possible for SQL Server on this platform today. Ideal for development, staging/preview, CI, and learning workloads; not for primary production data.

Why Deploy

Deploying the official SQL Server image manually on Railway fails in boring ways, and this template fixes all of them:

  1. Volumes crash-loop under gVisor — Railway executes containers under gVisor, and SQL Server's process abstraction layer stack-overflows mid-initialization when its data or registry hives sit on a Railway volume (see gVisor issue #11112). The template keeps SQL Server state on the container filesystem, the configuration verified to work, and warns loudly in the logs if a volume is mounted at the data path.
  2. SA password requirements — SQL Server refuses to initialize with a weak or missing SA password. The template validates passwords before boot (a clear error instead of an opaque crash loop) and auto-generates a compliant one when none is set.
  3. Crash dump hygiene — a fatal error makes sqlservr write multi-gigabyte dumps into its log directory, which fills the disk and keeps the server from ever starting again. Oversized dumps are cleaned up at boot, and a previous boot's crash reason is printed to the deploy logs.
  4. Clean shutdown — sqlservr runs as PID 1, so redeploys shut the server down cleanly instead of killing it hard.

Common Use Cases

  • Backends that require MSSQL — .NET/Entity Framework, legacy ASP.NET, or any stack whose ORM speaks TDS and needs real SQL Server (not a Postgres shim).
  • SQL Server–specific features — T-SQL, stored procedures, temporal tables, and MSSQL-only query behavior for development and testing.
  • Staging and preview databases — spin up disposable SQL Server instances per project or per pull request, without standing up a Windows VM.
  • Learning and prototyping — a full SQL Server 2019 Developer edition in the cloud for practicing T-SQL, SSMS connections, or BI tooling against a real instance.

Dependencies for

Applications

Deployment Dependencies

  • A Railway account with a plan that provides at least 2 GB of RAM for the service.
  • No external services, APIs, or accounts are required — SQL Server is fully self-contained.
  • The image mcr.microsoft.com/mssql/server:2019-latest is pulled from Microsoft's public registry at build time.

Template Content

More templates in this category

View Template
Garage S3 Storage
Ultra-light S3 server: fast, open-source, plug-and-play.

PROJETOS
8
View Template
Redis
Self Host Latest Redis with Railway

4
View Template
EasyImg
Simple self-hostable Nuxt.js personal image hosting system.

Muhammad Bilal
0