672 lines
18 KiB
Markdown
672 lines
18 KiB
Markdown
|
|
# SQL Server 2017 Express - Low RAM Edition 🐳
|
||
|
|
|
||
|
|
[](https://hub.docker.com/r/andresgarcia0313/mssql-express-lowram)
|
||
|
|
[](https://hub.docker.com/r/andresgarcia0313/mssql-express-lowram)
|
||
|
|
|
||
|
|
Imagen de Docker optimizada para ejecutar **SQL Server 2017 Express** con **bajo consumo de RAM** (384MB - 512MB).
|
||
|
|
|
||
|
|
## ✨ Características
|
||
|
|
|
||
|
|
- 🎯 **RAM mínima:** 384MB (vs 2GB oficial de Microsoft)
|
||
|
|
- ⚡ **Optimizaciones automáticas** al iniciar el contenedor
|
||
|
|
- 🔧 **Trace flags** preconfigurados para estabilidad
|
||
|
|
- 🏥 **Health check** integrado
|
||
|
|
- 📝 **Logs informativos** del proceso de optimización
|
||
|
|
- 🔐 **Contraseña configurable** por variable de entorno
|
||
|
|
|
||
|
|
## 🚀 Uso Rápido
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker run -d \
|
||
|
|
--name mssql \
|
||
|
|
--memory=384m \
|
||
|
|
--memory-swap=2g \
|
||
|
|
-e MSSQL_SA_PASSWORD=MiPassword123! \
|
||
|
|
-p 1433:1433 \
|
||
|
|
andresgarcia0313/mssql-express-lowram
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📋 Variables de Entorno
|
||
|
|
|
||
|
|
### Variables Requeridas
|
||
|
|
|
||
|
|
| Variable | Descripción |
|
||
|
|
|----------|-------------|
|
||
|
|
| `MSSQL_SA_PASSWORD` | **REQUERIDO.** Password del usuario SA (administrador) |
|
||
|
|
|
||
|
|
### Variables Opcionales
|
||
|
|
|
||
|
|
| Variable | Default | Descripción |
|
||
|
|
|----------|---------|-------------|
|
||
|
|
| `MSSQL_PID` | `Express` | Edición de SQL Server |
|
||
|
|
| `MSSQL_MEMORY_LIMIT_MB` | `340` | Límite de memoria interna de SQL Server (MB) |
|
||
|
|
| `MSSQL_COLLATION` | `SQL_Latin1_General_CP1_CI_AS` | Collation de la instancia |
|
||
|
|
| `MSSQL_LCID` | `1033` | ID de idioma (1033=English, 3082=Spanish) |
|
||
|
|
| `MSSQL_TCP_PORT` | `1433` | Puerto TCP de SQL Server |
|
||
|
|
| `TZ` | `UTC` | Zona horaria del contenedor |
|
||
|
|
| `ACCEPT_EULA` | `Y` | Ya aceptada en la imagen |
|
||
|
|
|
||
|
|
### Valores de MSSQL_PID
|
||
|
|
|
||
|
|
| Valor | Descripción | Límites |
|
||
|
|
|-------|-------------|---------|
|
||
|
|
| `Express` | **Recomendado.** Gratuito para desarrollo y producción | 1GB RAM, 10GB DB |
|
||
|
|
| `Developer` | Todas las características, solo desarrollo | Sin límites |
|
||
|
|
| `Standard` | Requiere licencia | 128GB RAM |
|
||
|
|
| `Enterprise` | Requiere licencia | Sin límites |
|
||
|
|
|
||
|
|
### Requisitos del Password
|
||
|
|
|
||
|
|
El password de SA debe cumplir:
|
||
|
|
- Mínimo **8 caracteres**
|
||
|
|
- Al menos una letra **mayúscula** (A-Z)
|
||
|
|
- Al menos una letra **minúscula** (a-z)
|
||
|
|
- Al menos un **número** (0-9)
|
||
|
|
- Al menos un **caracter especial** (!@#$%^&*)
|
||
|
|
|
||
|
|
**Ejemplos válidos:** `MiPassword123!`, `Secure@Pass99`, `Dev#Server2024`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 💾 Configuración de Memoria y Swap
|
||
|
|
|
||
|
|
### Parámetros de Docker para Memoria
|
||
|
|
|
||
|
|
| Parámetro | Descripción |
|
||
|
|
|-----------|-------------|
|
||
|
|
| `--memory` | Límite de RAM física para el contenedor |
|
||
|
|
| `--memory-swap` | Límite total (RAM + Swap). Debe ser mayor que `--memory` |
|
||
|
|
| `--memory-reservation` | Reserva mínima de RAM (soft limit) |
|
||
|
|
| `--memory-swappiness` | Preferencia de uso de swap (0-100) |
|
||
|
|
| `--oom-kill-disable` | Deshabilita OOM killer (usar con cuidado) |
|
||
|
|
|
||
|
|
### Configuración Recomendada por Tipo de Disco
|
||
|
|
|
||
|
|
#### 💿 Para SSD/NVMe (Recomendado)
|
||
|
|
|
||
|
|
El swap en SSD es rápido, permite configuración más agresiva:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker run -d \
|
||
|
|
--name mssql \
|
||
|
|
--memory=384m \
|
||
|
|
--memory-swap=4g \
|
||
|
|
--memory-reservation=256m \
|
||
|
|
--memory-swappiness=70 \
|
||
|
|
-e MSSQL_SA_PASSWORD=MiPassword123! \
|
||
|
|
-e MSSQL_PID=Express \
|
||
|
|
-e MSSQL_MEMORY_LIMIT_MB=340 \
|
||
|
|
-p 1433:1433 \
|
||
|
|
-v mssql_data:/var/opt/mssql/data \
|
||
|
|
andresgarcia0313/mssql-express-lowram
|
||
|
|
```
|
||
|
|
|
||
|
|
| Parámetro | Valor | Razón |
|
||
|
|
|-----------|-------|-------|
|
||
|
|
| `--memory` | 384m | RAM mínima viable |
|
||
|
|
| `--memory-swap` | 4g | Swap generoso (SSD es rápido) |
|
||
|
|
| `--memory-swappiness` | 60 | Balance entre RAM y swap |
|
||
|
|
|
||
|
|
#### 🗄️ Para HDD (Disco Mecánico)
|
||
|
|
|
||
|
|
El swap en HDD es lento, minimizar su uso:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker run -d \
|
||
|
|
--name mssql \
|
||
|
|
--memory=512m \
|
||
|
|
--memory-swap=1g \
|
||
|
|
--memory-reservation=384m \
|
||
|
|
--memory-swappiness=10 \
|
||
|
|
-e MSSQL_SA_PASSWORD=MiPassword123! \
|
||
|
|
-e MSSQL_PID=Express \
|
||
|
|
-e MSSQL_MEMORY_LIMIT_MB=450 \
|
||
|
|
-p 1433:1433 \
|
||
|
|
-v mssql_data:/var/opt/mssql/data \
|
||
|
|
andresgarcia0313/mssql-express-lowram
|
||
|
|
```
|
||
|
|
|
||
|
|
| Parámetro | Valor | Razón |
|
||
|
|
|-----------|-------|-------|
|
||
|
|
| `--memory` | 512m | Más RAM para evitar swap |
|
||
|
|
| `--memory-swap` | 1g | Swap mínimo (HDD lento) |
|
||
|
|
| `--memory-swappiness` | 10 | Evitar swap excepto emergencia |
|
||
|
|
|
||
|
|
### Tabla de Configuraciones Recomendadas
|
||
|
|
|
||
|
|
| Escenario | RAM | Swap | Swappiness | MSSQL_MEMORY_LIMIT_MB |
|
||
|
|
|-----------|-----|------|------------|----------------------|
|
||
|
|
| **Mínimo SSD** | 384m | 4g | 60 | 340 |
|
||
|
|
| **Mínimo HDD** | 512m | 1g | 10 | 450 |
|
||
|
|
| **Desarrollo** | 512m | 2g | 30 | 450 |
|
||
|
|
| **CI/CD** | 512m | 2g | 30 | 450 |
|
||
|
|
| **Múltiples DBs** | 768m | 2g | 20 | 680 |
|
||
|
|
| **Carga moderada** | 1g | 2g | 10 | 900 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ⚡ Configuración para Máximo Rendimiento
|
||
|
|
|
||
|
|
### Desarrollo Local - Máximo Rendimiento
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker run -d \
|
||
|
|
--name mssql-performance \
|
||
|
|
--memory=1g \
|
||
|
|
--memory-swap=2g \
|
||
|
|
--memory-swappiness=10 \
|
||
|
|
--cpus=2 \
|
||
|
|
-e MSSQL_SA_PASSWORD=MiPassword123! \
|
||
|
|
-e MSSQL_PID=Developer \
|
||
|
|
-e MSSQL_MEMORY_LIMIT_MB=900 \
|
||
|
|
-e TZ=America/Bogota \
|
||
|
|
-p 1433:1433 \
|
||
|
|
-v mssql_data:/var/opt/mssql/data \
|
||
|
|
-v mssql_log:/var/opt/mssql/log \
|
||
|
|
andresgarcia0313/mssql-express-lowram
|
||
|
|
```
|
||
|
|
|
||
|
|
### Máxima Estabilidad (Producción-like)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker run -d \
|
||
|
|
--name mssql-stable \
|
||
|
|
--memory=768m \
|
||
|
|
--memory-swap=2g \
|
||
|
|
--memory-reservation=512m \
|
||
|
|
--memory-swappiness=20 \
|
||
|
|
--restart=unless-stopped \
|
||
|
|
--cpus=2 \
|
||
|
|
-e MSSQL_SA_PASSWORD=MiPassword123! \
|
||
|
|
-e MSSQL_PID=Express \
|
||
|
|
-e MSSQL_MEMORY_LIMIT_MB=680 \
|
||
|
|
-p 1433:1433 \
|
||
|
|
-v /path/to/data:/var/opt/mssql/data \
|
||
|
|
-v /path/to/log:/var/opt/mssql/log \
|
||
|
|
-v /path/to/backup:/var/opt/mssql/backup \
|
||
|
|
andresgarcia0313/mssql-express-lowram
|
||
|
|
```
|
||
|
|
|
||
|
|
### Recursos Mínimos Absolutos
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker run -d \
|
||
|
|
--name mssql-minimal \
|
||
|
|
--memory=384m \
|
||
|
|
--memory-swap=6g \
|
||
|
|
--memory-swappiness=80 \
|
||
|
|
-e MSSQL_SA_PASSWORD=MiPassword123! \
|
||
|
|
-e MSSQL_PID=Express \
|
||
|
|
-e MSSQL_MEMORY_LIMIT_MB=300 \
|
||
|
|
-p 1433:1433 \
|
||
|
|
andresgarcia0313/mssql-express-lowram
|
||
|
|
```
|
||
|
|
|
||
|
|
> ⚠️ Con recursos mínimos, el rendimiento dependerá mucho del swap (requiere SSD).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔧 Optimizaciones Incluidas en la Imagen
|
||
|
|
|
||
|
|
### Configuración de SQL Server (Automática)
|
||
|
|
|
||
|
|
| Setting | Valor | Propósito |
|
||
|
|
|---------|-------|-----------|
|
||
|
|
| `max server memory` | 320 MB | Límite del buffer pool |
|
||
|
|
| `min server memory` | 128 MB | Permite liberar RAM bajo presión |
|
||
|
|
| `max degree of parallelism` | 2 | Reduce consumo en queries paralelas |
|
||
|
|
| `cost threshold for parallelism` | 50 | Solo queries costosas usan paralelismo |
|
||
|
|
| `optimize for ad hoc workloads` | ON | Reduce caché de planes únicos |
|
||
|
|
| `recovery interval` | 1 min | Recuperación rápida tras crash |
|
||
|
|
|
||
|
|
### Trace Flags Activos (Automáticos)
|
||
|
|
|
||
|
|
| Flag | Propósito |
|
||
|
|
|------|-----------|
|
||
|
|
| **TF 1117** | Crecimiento uniforme de archivos de datos |
|
||
|
|
| **TF 1118** | Reduce contención en tempdb (extents uniformes) |
|
||
|
|
| **TF 3226** | Suprime logs de backup exitoso (menos I/O) |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📦 Docker Compose
|
||
|
|
|
||
|
|
### Configuración Básica
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
version: '3.8'
|
||
|
|
|
||
|
|
services:
|
||
|
|
sqlserver:
|
||
|
|
image: andresgarcia0313/mssql-express-lowram
|
||
|
|
container_name: mssql
|
||
|
|
mem_limit: 512m
|
||
|
|
memswap_limit: 2g
|
||
|
|
mem_reservation: 384m
|
||
|
|
restart: unless-stopped
|
||
|
|
environment:
|
||
|
|
- MSSQL_SA_PASSWORD=MiPassword123!
|
||
|
|
- MSSQL_PID=Express
|
||
|
|
- MSSQL_MEMORY_LIMIT_MB=450
|
||
|
|
- TZ=America/Bogota
|
||
|
|
ports:
|
||
|
|
- "1433:1433"
|
||
|
|
volumes:
|
||
|
|
- mssql_data:/var/opt/mssql/data
|
||
|
|
- mssql_log:/var/opt/mssql/log
|
||
|
|
healthcheck:
|
||
|
|
test: /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -Q "SELECT 1"
|
||
|
|
interval: 30s
|
||
|
|
timeout: 10s
|
||
|
|
retries: 3
|
||
|
|
|
||
|
|
volumes:
|
||
|
|
mssql_data:
|
||
|
|
mssql_log:
|
||
|
|
```
|
||
|
|
|
||
|
|
### Configuración Avanzada (SSD + Rendimiento)
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
version: '3.8'
|
||
|
|
|
||
|
|
services:
|
||
|
|
sqlserver:
|
||
|
|
image: andresgarcia0313/mssql-express-lowram
|
||
|
|
container_name: mssql
|
||
|
|
mem_limit: 768m
|
||
|
|
memswap_limit: 4g
|
||
|
|
mem_reservation: 512m
|
||
|
|
cpus: 2
|
||
|
|
restart: unless-stopped
|
||
|
|
environment:
|
||
|
|
MSSQL_SA_PASSWORD: ${MSSQL_PASSWORD:-MiPassword123!}
|
||
|
|
MSSQL_PID: Express
|
||
|
|
MSSQL_MEMORY_LIMIT_MB: 680
|
||
|
|
MSSQL_COLLATION: Modern_Spanish_CI_AS
|
||
|
|
TZ: America/Bogota
|
||
|
|
ports:
|
||
|
|
- "1433:1433"
|
||
|
|
volumes:
|
||
|
|
- mssql_data:/var/opt/mssql/data
|
||
|
|
- mssql_log:/var/opt/mssql/log
|
||
|
|
- mssql_backup:/var/opt/mssql/backup
|
||
|
|
healthcheck:
|
||
|
|
test: /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -Q "SELECT 1"
|
||
|
|
interval: 30s
|
||
|
|
timeout: 10s
|
||
|
|
start_period: 30s
|
||
|
|
retries: 3
|
||
|
|
logging:
|
||
|
|
driver: "json-file"
|
||
|
|
options:
|
||
|
|
max-size: "10m"
|
||
|
|
max-file: "3"
|
||
|
|
|
||
|
|
volumes:
|
||
|
|
mssql_data:
|
||
|
|
driver: local
|
||
|
|
mssql_log:
|
||
|
|
driver: local
|
||
|
|
mssql_backup:
|
||
|
|
driver: local
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔌 Conexión
|
||
|
|
|
||
|
|
### Desde línea de comandos
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Usando sqlcmd dentro del contenedor
|
||
|
|
docker exec -it mssql /opt/mssql-tools/bin/sqlcmd \
|
||
|
|
-S localhost -U sa -P 'MiPassword123!'
|
||
|
|
|
||
|
|
# Usando sqlcmd local
|
||
|
|
sqlcmd -S localhost,1433 -U sa -P 'MiPassword123!'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Connection Strings
|
||
|
|
|
||
|
|
**.NET / C#**
|
||
|
|
```csharp
|
||
|
|
Server=localhost,1433;Database=MiDB;User Id=sa;Password=MiPassword123!;TrustServerCertificate=True;
|
||
|
|
```
|
||
|
|
|
||
|
|
**Node.js (mssql)**
|
||
|
|
```javascript
|
||
|
|
const config = {
|
||
|
|
server: 'localhost',
|
||
|
|
port: 1433,
|
||
|
|
user: 'sa',
|
||
|
|
password: 'MiPassword123!',
|
||
|
|
database: 'MiDB',
|
||
|
|
options: { trustServerCertificate: true }
|
||
|
|
};
|
||
|
|
```
|
||
|
|
|
||
|
|
**Python (pyodbc)**
|
||
|
|
```python
|
||
|
|
conn_str = (
|
||
|
|
"DRIVER={ODBC Driver 17 for SQL Server};"
|
||
|
|
"SERVER=localhost,1433;"
|
||
|
|
"DATABASE=MiDB;"
|
||
|
|
"UID=sa;"
|
||
|
|
"PWD=MiPassword123!;"
|
||
|
|
"TrustServerCertificate=yes;"
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Java (JDBC)**
|
||
|
|
```java
|
||
|
|
String url = "jdbc:sqlserver://localhost:1433;database=MiDB;user=sa;password=MiPassword123!;trustServerCertificate=true;";
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🏗️ Ejemplos de Uso
|
||
|
|
|
||
|
|
### CI/CD (GitHub Actions)
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
services:
|
||
|
|
sqlserver:
|
||
|
|
image: andresgarcia0313/mssql-express-lowram
|
||
|
|
env:
|
||
|
|
MSSQL_SA_PASSWORD: TestPassword123!
|
||
|
|
MSSQL_PID: Express
|
||
|
|
MSSQL_MEMORY_LIMIT_MB: 450
|
||
|
|
ports:
|
||
|
|
- 1433:1433
|
||
|
|
options: >-
|
||
|
|
--memory=512m
|
||
|
|
--memory-swap=2g
|
||
|
|
--health-cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P TestPassword123! -Q 'SELECT 1'"
|
||
|
|
--health-interval=10s
|
||
|
|
--health-timeout=5s
|
||
|
|
--health-retries=5
|
||
|
|
```
|
||
|
|
|
||
|
|
### Kubernetes
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
apiVersion: v1
|
||
|
|
kind: Pod
|
||
|
|
metadata:
|
||
|
|
name: mssql-lowram
|
||
|
|
spec:
|
||
|
|
containers:
|
||
|
|
- name: mssql
|
||
|
|
image: andresgarcia0313/mssql-express-lowram
|
||
|
|
resources:
|
||
|
|
limits:
|
||
|
|
memory: "768Mi"
|
||
|
|
requests:
|
||
|
|
memory: "512Mi"
|
||
|
|
env:
|
||
|
|
- name: MSSQL_SA_PASSWORD
|
||
|
|
valueFrom:
|
||
|
|
secretKeyRef:
|
||
|
|
name: mssql-secret
|
||
|
|
key: sa-password
|
||
|
|
- name: MSSQL_PID
|
||
|
|
value: "Express"
|
||
|
|
- name: MSSQL_MEMORY_LIMIT_MB
|
||
|
|
value: "680"
|
||
|
|
ports:
|
||
|
|
- containerPort: 1433
|
||
|
|
livenessProbe:
|
||
|
|
exec:
|
||
|
|
command:
|
||
|
|
- /opt/mssql-tools/bin/sqlcmd
|
||
|
|
- -S
|
||
|
|
- localhost
|
||
|
|
- -U
|
||
|
|
- sa
|
||
|
|
- -P
|
||
|
|
- $(MSSQL_SA_PASSWORD)
|
||
|
|
- -Q
|
||
|
|
- SELECT 1
|
||
|
|
initialDelaySeconds: 30
|
||
|
|
periodSeconds: 30
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ⚠️ Advertencias
|
||
|
|
|
||
|
|
- **No recomendado para producción pesada** - La RAM es insuficiente para cargas grandes
|
||
|
|
- **Swap en HDD** - Experimentará lentitud significativa, usar SSD cuando sea posible
|
||
|
|
- **Realizar backups frecuentes** en entornos con recursos limitados
|
||
|
|
- Los **trace flags** se aplican en cada inicio (no persisten en la imagen)
|
||
|
|
- `MSSQL_MEMORY_LIMIT_MB` debe ser **menor** que `--memory` (dejar ~60MB para el OS)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔍 Troubleshooting
|
||
|
|
|
||
|
|
### Ver logs de optimización
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker logs mssql 2>&1 | grep LOWRAM
|
||
|
|
```
|
||
|
|
|
||
|
|
### Verificar configuración aplicada
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker exec mssql /opt/mssql-tools/bin/sqlcmd \
|
||
|
|
-S localhost -U sa -P 'MiPassword123!' \
|
||
|
|
-Q "SELECT name, value_in_use FROM sys.configurations WHERE name LIKE '%memory%' OR name LIKE '%parallel%'"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Ver uso de memoria real
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker stats mssql --no-stream
|
||
|
|
```
|
||
|
|
|
||
|
|
### El contenedor no inicia
|
||
|
|
|
||
|
|
1. Verificar que el password cumple los requisitos
|
||
|
|
2. Verificar que hay suficiente RAM: `docker stats`
|
||
|
|
3. Revisar logs: `docker logs mssql`
|
||
|
|
4. Verificar swap disponible: `free -h`
|
||
|
|
|
||
|
|
### Rendimiento lento
|
||
|
|
|
||
|
|
1. Verificar tipo de disco (SSD vs HDD)
|
||
|
|
2. Aumentar `--memory` si es posible
|
||
|
|
3. Reducir `--memory-swappiness` en HDD
|
||
|
|
4. Verificar que no hay otros contenedores compitiendo por recursos
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔬 Proceso de Optimización (Trazabilidad)
|
||
|
|
|
||
|
|
Esta imagen fue creada mediante un proceso de investigación y optimización documentado. A continuación se detalla el proceso completo para reproducibilidad y trazabilidad.
|
||
|
|
|
||
|
|
### Problema Original
|
||
|
|
|
||
|
|
Microsoft SQL Server 2017 tiene un **requisito mínimo oficial de 2GB de RAM**, lo cual es excesivo para:
|
||
|
|
- Desarrollo local en equipos con recursos limitados
|
||
|
|
- Pipelines de CI/CD
|
||
|
|
- Contenedores en entornos de pruebas
|
||
|
|
- Microservicios que solo necesitan una DB pequeña
|
||
|
|
|
||
|
|
### Investigación Realizada
|
||
|
|
|
||
|
|
1. **Documentación oficial consultada:**
|
||
|
|
- [Configure SQL Server Docker Containers](https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-configure)
|
||
|
|
- [SQL Server Linux Performance Best Practices](https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-performance-best-practices)
|
||
|
|
- [KB4347055 - Fix OOM in Docker containers](https://support.microsoft.com/en-us/topic/kb4347055)
|
||
|
|
- [mssql-conf Configuration Tool](https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-configure-mssql-conf)
|
||
|
|
|
||
|
|
2. **Hallazgos clave:**
|
||
|
|
- `MSSQL_MEMORY_LIMIT_MB` existe pero requiere versiones recientes
|
||
|
|
- SQL Server 2017 CU10+ incluye fix para respetar límites de contenedor
|
||
|
|
- El 80% de RAM por defecto es configurable vía `sp_configure`
|
||
|
|
- Trace flags pueden mejorar estabilidad en entornos con poca RAM
|
||
|
|
|
||
|
|
### Optimizaciones Aplicadas
|
||
|
|
|
||
|
|
#### 1. Configuración de SQL Server (`sp_configure`)
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- Ejecutado automáticamente al iniciar el contenedor
|
||
|
|
|
||
|
|
-- Limitar buffer pool (principal consumidor de RAM)
|
||
|
|
EXEC sp_configure 'max server memory', 320;
|
||
|
|
|
||
|
|
-- Permitir liberar memoria bajo presión del sistema
|
||
|
|
EXEC sp_configure 'min server memory', 128;
|
||
|
|
|
||
|
|
-- Reducir caché de planes para queries ad-hoc (ahorra RAM)
|
||
|
|
EXEC sp_configure 'optimize for ad hoc workloads', 1;
|
||
|
|
|
||
|
|
-- Limitar paralelismo (operaciones paralelas consumen más RAM)
|
||
|
|
EXEC sp_configure 'max degree of parallelism', 2;
|
||
|
|
|
||
|
|
-- Solo queries costosas usan paralelismo
|
||
|
|
EXEC sp_configure 'cost threshold for parallelism', 50;
|
||
|
|
|
||
|
|
-- Checkpoints frecuentes para recuperación rápida
|
||
|
|
EXEC sp_configure 'recovery interval (min)', 1;
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 2. Trace Flags para Estabilidad
|
||
|
|
|
||
|
|
```sql
|
||
|
|
-- Ejecutados automáticamente al iniciar
|
||
|
|
|
||
|
|
-- TF 1117: Crecimiento uniforme de archivos
|
||
|
|
-- Evita que un archivo crezca más que otros, reduciendo fragmentación
|
||
|
|
DBCC TRACEON(1117, -1);
|
||
|
|
|
||
|
|
-- TF 1118: Extents uniformes en tempdb
|
||
|
|
-- Reduce contención de páginas mixtas, mejora rendimiento
|
||
|
|
DBCC TRACEON(1118, -1);
|
||
|
|
|
||
|
|
-- TF 3226: Suprime logs de backup exitoso
|
||
|
|
-- Reduce I/O en el log de errores
|
||
|
|
DBCC TRACEON(3226, -1);
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 3. Entrypoint Personalizado
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# El entrypoint realiza:
|
||
|
|
# 1. Valida que MSSQL_SA_PASSWORD esté definido
|
||
|
|
# 2. Inicia SQL Server en foreground
|
||
|
|
# 3. En background, espera que SQL Server esté listo
|
||
|
|
# 4. Aplica todas las optimizaciones automáticamente
|
||
|
|
# 5. Muestra logs informativos del proceso
|
||
|
|
```
|
||
|
|
|
||
|
|
#### 4. Health Check Integrado
|
||
|
|
|
||
|
|
```dockerfile
|
||
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||
|
|
CMD /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$MSSQL_SA_PASSWORD" -Q "SELECT 1"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pruebas de Validación
|
||
|
|
|
||
|
|
La imagen fue probada durante **6+ minutos** de monitoreo continuo:
|
||
|
|
|
||
|
|
| Minuto | Estado | RAM | Operación |
|
||
|
|
|--------|--------|-----|-----------|
|
||
|
|
| 0 | ✅ OK | 380.9 MB | Query básica |
|
||
|
|
| 2 | ✅ OK | 381.9 MB | Count de databases |
|
||
|
|
| 4 | ✅ OK | 381.8 MB | CREATE TABLE + 1000 INSERTs |
|
||
|
|
| 6 | ✅ OK | 381.6 MB | Listado de databases |
|
||
|
|
|
||
|
|
**Resultado:** Sin errores, sin OOM, sin crashes, memoria estable.
|
||
|
|
|
||
|
|
### Archivos de la Imagen
|
||
|
|
|
||
|
|
```
|
||
|
|
deploy/docker-mssql/
|
||
|
|
├── Dockerfile # Imagen base + labels + health check
|
||
|
|
├── entrypoint.sh # Validación + inicio + optimización automática
|
||
|
|
├── optimize.sql # Queries de sp_configure y trace flags
|
||
|
|
├── build-push.sh # Script para build y push a Docker Hub
|
||
|
|
└── README.md # Esta documentación
|
||
|
|
```
|
||
|
|
|
||
|
|
### Limitaciones Conocidas
|
||
|
|
|
||
|
|
| Limitación | Causa | Mitigación |
|
||
|
|
|------------|-------|------------|
|
||
|
|
| RAM mínima ~380MB | Componentes fuera del buffer pool | Usar swap en SSD |
|
||
|
|
| No persisten trace flags | Se aplican en runtime, no en imagen | Se re-aplican en cada inicio |
|
||
|
|
| Rendimiento reducido | Menos RAM = menos caché | Usar SSD, aumentar swap |
|
||
|
|
|
||
|
|
### Diferencias vs Imagen Oficial
|
||
|
|
|
||
|
|
| Aspecto | Imagen Oficial | Esta Imagen |
|
||
|
|
|---------|----------------|-------------|
|
||
|
|
| RAM mínima | 2 GB | 384 MB |
|
||
|
|
| Optimizaciones | Ninguna | Automáticas |
|
||
|
|
| Trace flags | Ninguno | 3 preconfigurados |
|
||
|
|
| Health check | No | Sí |
|
||
|
|
| Validación password | No | Sí (con mensaje de error claro) |
|
||
|
|
| Documentación | Básica | Completa |
|
||
|
|
|
||
|
|
### Reproducir las Optimizaciones Manualmente
|
||
|
|
|
||
|
|
Si prefieres aplicar las optimizaciones a la imagen oficial:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Iniciar contenedor oficial
|
||
|
|
docker run -d --name mssql --memory=512m \
|
||
|
|
-e ACCEPT_EULA=Y \
|
||
|
|
-e MSSQL_SA_PASSWORD=TuPassword123! \
|
||
|
|
-p 1433:1433 \
|
||
|
|
mcr.microsoft.com/mssql/server:2017-latest
|
||
|
|
|
||
|
|
# 2. Esperar que inicie
|
||
|
|
sleep 30
|
||
|
|
|
||
|
|
# 3. Aplicar optimizaciones
|
||
|
|
docker exec mssql /opt/mssql-tools/bin/sqlcmd \
|
||
|
|
-S localhost -U sa -P 'TuPassword123!' -Q "
|
||
|
|
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
|
||
|
|
EXEC sp_configure 'max server memory', 384; RECONFIGURE;
|
||
|
|
EXEC sp_configure 'min server memory', 128; RECONFIGURE;
|
||
|
|
EXEC sp_configure 'optimize for ad hoc workloads', 1; RECONFIGURE;
|
||
|
|
EXEC sp_configure 'max degree of parallelism', 2; RECONFIGURE;
|
||
|
|
EXEC sp_configure 'cost threshold for parallelism', 50; RECONFIGURE;
|
||
|
|
EXEC sp_configure 'recovery interval (min)', 1; RECONFIGURE;
|
||
|
|
DBCC TRACEON(1117, -1);
|
||
|
|
DBCC TRACEON(1118, -1);
|
||
|
|
DBCC TRACEON(3226, -1);
|
||
|
|
"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📊 Basado en
|
||
|
|
|
||
|
|
- **Microsoft SQL Server 2017 Express** (CU31 - versión 14.0.3515.1)
|
||
|
|
- Imagen base: `mcr.microsoft.com/mssql/server:2017-latest`
|
||
|
|
- Documentación oficial de Microsoft para SQL Server en Linux
|
||
|
|
|
||
|
|
## 📄 Licencia
|
||
|
|
|
||
|
|
- **SQL Server Express**: Gratuito para desarrollo y producción (con límites)
|
||
|
|
- **Scripts de optimización**: MIT License
|
||
|
|
|
||
|
|
## 👤 Autor
|
||
|
|
|
||
|
|
**andresgarcia0313**
|
||
|
|
|
||
|
|
- GitHub: [@andresgarcia0313](https://github.com/andresgarcia0313)
|
||
|
|
- Docker Hub: [andresgarcia0313](https://hub.docker.com/u/andresgarcia0313)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
⭐ Si esta imagen te fue útil, considera dejar una estrella en el repositorio.
|