
Deploy mssql2019
Microsoft SQL Server 2019 with persistent storage and TCP access
mssql-2019
Just deployed
mssql2019 — SQL Server 2019 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,mssqlnpm 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
- Click the deploy button above (or go to ).
- Add a TCP Proxy under Service → Settings → Networking to reach SQL Server from your machine (public endpoint like
.proxy.rlwy.net:). - Deploy. Optionally set the variables below before the first deploy.
Environment variables
| Variable | Required | Default | Description |
|---|---|---|---|
MSSQL_SA_PASSWORD | No | auto-generated | SA password. Only applies on first initialization. Must satisfy SQL Server complexity rules (8–128 chars, 3 of: uppercase, lowercase, digit, symbol). |
ACCEPT_EULA | No | Y | SQL Server EULA acceptance. Baked in as a default; override if you need to. |
MSSQL_PID | No | Developer | Edition: Developer, Express, Standard, Enterprise, or a product key. |
MSSQL_COLLATION | No | server default | Collation, applied on first initialization (e.g. SQL_Latin1_General_CP1_CI_AS). |
MSSQL_DEBUG | No | unset | Set 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:
- If
MSSQL_SA_PASSWORD(or legacySA_PASSWORD) is set, it is used for initialization and saved to/var/opt/mssql/.sa_password. - 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).
- 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.
- 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 onmcr.microsoft.com/mssql/server:2019-latest, bakes in EULA acceptance and Developer edition defaults, installsentrypoint.sh, exposes1433.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, thenexecssqlservras PID 1 so it shuts down cleanly onSIGTERM. 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
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).
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:
- 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.
- 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.
- 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.
- 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-latestis pulled from Microsoft's public registry at build time.
Template Content
mssql-2019
lNamelessl/mssql2019