Running Microsoft SQL Server in Containers , A Modern Approach to Database Infrastructure

Is there a a faster and more reliable way to deploy SQL environments, it opened the discussion around modern infrastructure design. This article explores how containers are transforming SQL Server deployments through faster provisioning, persistent storage, and production-ready networking.

For many years, SQL Server deployments followed a very traditional path.

Dedicated servers. Large virtual machines. Manual installations. Lengthy configuration processes.
Complex upgrade procedures.

And honestly … for a long time … that was the correct way to deploy databases.

SQL Server is one of the most critical components inside modern businesses.
When databases fail:

  • applications stop
  • operations freeze
  • customers feel it immediately

But infrastructure design has changed dramatically over the last few years. Containers introduced a completely different operational model:

  • rapid deployment
  • repeatable infrastructure
  • simplified recovery
  • consistent environments
  • infrastructure-as-code
  • portable workloads

At first, many engineers resisted the idea of databases inside containers.

Including me.

The concern was understandable: “How can something as critical as SQL run inside a disposable container?”

The answer is:
The container is disposable.
The data is not.

That is the mindset shift that changes everything.

SQL containers are not designed to replace every traditional SQL deployment.

But they are incredibly valuable for:

  • development environments
  • staging platforms
  • API-driven systems
  • modern applications
  • edge deployments
  • analytics platforms
  • rapid customer deployments
  • isolated workloads
  • container-native infrastructure

And in carefully designed environments: even production systems.

The biggest difference is not performance. It is operational speed.

Traditional deployments often involve:

  • VM provisioning
  • operating system preparation
  • SQL installation
  • patching
  • manual configuration
  • networking setup
  • backup configuration

A properly designed SQL container can be deployed in minutes.

Not days.

And more importantly: every deployment becomes consistent.

This is where many deployments fail. Never treat SQL containers like stateless application containers.

A database is stateful infrastructure.

That means:

  • persistence matters
  • storage matters
  • transaction logs matter
  • backup strategy matters
  • recovery matters

The container itself should be replaceable. The data should survive independently.

One of the worst mistakes engineers make is storing SQL data inside the container layer itself.

That creates massive risk.

If the container is removed:
the database disappears with it.

Production SQL containers should always use:

  • persistent volumes
  • mapped SSD storage
  • isolated log storage
  • backup destinations outside the container

I strongly recommend separating SQL workloads across dedicated SSD storage.

This dramatically improves:

  • performance
  • transaction consistency
  • recovery reliability
  • maintenance flexibility

SQL transaction logs are heavily write-intensive.

When logs share storage with database files:

  • latency increases
  • write queues grow
  • performance becomes inconsistent

Separating logs onto dedicated SSD storage improves:

  • write throughput
  • transactional consistency
  • recovery speed

This principle exists in both:

  • traditional SQL infrastructure
  • container deployments

Good architecture fundamentals never change.

One thing often ignored in container tutorials is networking. Many examples online simply deploy SQL onto:
“default bridge networks”

That might work for testing.

It is not good production practice. Production deployments should use:

  • dedicated container networks
  • predictable subnets
  • static addressing where appropriate
  • firewall visibility
  • monitoring integration
  • controlled routing

Below is a production-style deployment example.

version: '3.9'
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: prod_sql_01
hostname: prod-sql-01
environment:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: "StrongPasswordHere!"
MSSQL_PID: "Standard"
ports:
- "1433:1433"
restart: unless-stopped
deploy:
resources:
limits:
cpus: '4'
memory: 8G
volumes:
# Database Files
- /mnt/sql-data:/var/opt/mssql/data
# Transaction Logs
- /mnt/sql-logs:/var/opt/mssql/log
# SQL Backups
- /mnt/sql-backups:/var/opt/mssql/backups
healthcheck:
test: ["CMD", "/opt/mssql-tools/bin/sqlcmd", "-S", "localhost", "-U", "sa", "-P", "StrongPasswordHere!", "-Q", "SELECT 1"]
interval: 30s
timeout: 10s
retries: 5
networks:
production_net:
ipv4_address: 172.12.1.20
networks:
production_net:
driver: bridge
ipam:
config:
- subnet: 172.12.0/24

This is where many engineers stop too early.

Production-ready means more than:
“the container starts successfully.”

1. Persistent Storage

Critical for:

  • database survival
  • rebuild safety
  • backup consistency

Never store production databases inside ephemeral container layers.

2. Resource Limits

limits:
cpus: '4'
memory: 8G

Without limits:
SQL can consume the entire host.

Especially dangerous on shared Docker systems.

3. Automatic Recovery

restart: unless-stopped

Ensures SQL automatically returns after:

  • host reboot
  • Docker restart
  • daemon failure

4. Health Checks

A running container does not always mean:
SQL is healthy.

Health checks allow:

  • monitoring systems
  • orchestration platforms
  • administrators

to detect unhealthy SQL instances properly.

This distinction is extremely important.

Acceptable:

  • shared storage
  • dynamic IPs
  • simplified networking
  • smaller memory allocations
  • Developer Edition licensing

Usually optimised for:

  • speed
  • flexibility
  • experimentation

Require:

  • persistent SSD storage
  • dedicated backups
  • monitoring integration
  • controlled networking
  • resource allocation
  • security hardening
  • recovery planning
  • patch management
  • documented backup testing

Production environments should be engineered, not simply deployed.

Containers do not remove operational responsibilities.

SQL still requires:

  • performance monitoring
  • backup verification
  • storage monitoring
  • transaction log monitoring
  • alerting
  • security auditing

Recommended monitoring platforms include:

  • Zabbix
  • Grafana
  • Prometheus
  • Wazuh

depending on operational requirements.

Never expose SQL directly to the internet. Production deployments should include:

  • firewall restrictions
  • segmented networks
  • password rotation
  • encrypted backups
  • monitoring and alerting
  • least-privilege access

And ideally: applications should avoid direct SA account usage.

Containers are often misunderstood as:
“lightweight shortcuts.”

They are not.

Containers are an infrastructure standardisation tool.

When engineered properly:
they improve:

  • consistency
  • deployment speed
  • portability
  • operational repeatability

But only when combined with:

  • proper storage design
  • proper backup strategy
  • proper monitoring
  • proper networking
  • proper operational discipline

Running SQL Server inside containers is not about replacing database engineering principles. It is about modernising deployment methods while still respecting the foundations that make databases reliable.

The same fundamentals still apply:

  • storage matters
  • backups matter
  • recovery matters
  • monitoring matters
  • architecture matters

Containers simply provide a faster, cleaner, and more repeatable way to deliver those environments. And when implemented correctly: they become an incredibly powerful part of modern infrastructure design.

Leave a comment