Docker Compose启动SQL Server容器后自动退出,如何保持运行?
How to Keep Your SQL Server Docker Container Running After Initialization
Got it—your container exits immediately after finishing the database setup, and using tail -F to keep it alive feels like a messy workaround. The core problem here is that your load_db.sh script is running as the container's PID 1 process. Once the script finishes executing all its steps, Docker has no foreground process to keep the container running, so it shuts down. Let’s fix this with a cleaner, more robust approach:
Fix the load_db.sh Script
The key is to make sure SQL Server runs as the foreground process after your initialization tasks are done. Here’s the revised script:
#!/usr/bin/env bash SERVER_OUT=/var/log/sqlserver.out TIMEOUT=90 # Start SQL Server in the background so we can run our setup steps /opt/mssql/bin/sqlservr &>${SERVER_OUT} & SQLPID=$! # Function to check if SQL Server is ready function server_ready() { grep -q -F 'Recovery is complete.' ${SERVER_OUT} } echo 'Waiting for Microsoft SQL Server to start up...' for (( i=0; i<${TIMEOUT}; i++ )); do sleep 1 if server_ready; then break fi done # Exit early if SQL Server didn't start in time if ! server_ready; then echo "Error: SQL Server failed to start within ${TIMEOUT} seconds" exit 1 fi echo 'Microsoft SQL Server is up and ready' # Run your database initialization commands /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P ${SA_PASSWORD} -Q "CREATE DATABASE MarketDataService;" /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P ${SA_PASSWORD} -d MarketDataService -i sql/2018.0100.000000001.Add_Layout_table.sql # Gracefully stop the background SQL Server instance to avoid port conflicts kill $SQLPID wait $SQLPID 2>/dev/null # Replace this script process with SQL Server running in the foreground # This makes SQL Server the container's PID 1, keeping the container alive and handling shutdown signals properly exec /opt/mssql/bin/sqlservr
Why This Works
- Background Startup: We launch SQL Server in the background first, which lets us run our database setup tasks while it initializes.
- Clean Handoff: After setup is done, we shut down the background SQL Server instance to avoid port conflicts when we restart it.
- Foreground Execution: Using
execreplaces the shell script with the SQL Server process running in the foreground. This makes SQL Server the container's PID 1 process—so Docker will keep the container running as long as SQL Server is active. It also ensures SQL Server receives shutdown signals (like when you rundocker stop) correctly, allowing for graceful termination instead of a forced kill.
Bonus Improvements
- Secure Your Password: Instead of hardcoding
SA_PASSWORDin your Dockerfile, use a.envfile with Docker Compose to keep secrets out of version control. Just add a line likeSA_PASSWORD=yourStrong(!)Passwordto.envand update your Docker Compose to reference it. - Add a Health Check: Make sure your Docker Compose file includes a health check to verify SQL Server is actually ready to accept connections:
services: db: build: context: . dockerfile: Dockerfile-db ports: - 1433:1433 healthcheck: test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P ${SA_PASSWORD} -Q 'SELECT 1' || exit 1"] interval: 10s timeout: 5s retries: 5
内容的提问来源于stack exchange,提问作者Serg046
相关产品推荐
相关产品推荐

