Overview
SS-IMS includes a multi-stage Dockerfile for containerized deployments. This approach provides consistent environments across development, staging, and production.
Dockerfile Analysis
The application uses a multi-stage Docker build to optimize image size and security:
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS builder
WORKDIR /app
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/runtime:9.0 AS runtime
WORKDIR /app
COPY --from=builder /app/out .
ENTRYPOINT [ "dotnet" , "ss.Integrated.Management.Server.dll" ]
Build Stages Explained
Builder Stage
Uses the full .NET 9.0 SDK to:
Restore NuGet dependencies (dotnet restore)
Build and publish the application in Release mode
Output compiled binaries to /app/out
Runtime Stage
Uses the smaller .NET 9.0 runtime image to:
Copy only the published output (not source code)
Reduce final image size by ~70%
Minimize attack surface for production deployments
Building the Docker Image
Prerequisites
Docker 20.10+ installed
Docker Compose 2.0+ (for multi-container setup)
Build Commands
Navigate to project directory
cd ss.Integrated.Management.Server
Build the image
docker build -t ss-ims:latest .
With a specific tag: docker build -t ss-ims:v1.0.0 .
Verify the image
docker images | grep ss-ims
Running with Docker
Standalone Container
You must have a PostgreSQL database accessible from the container. The database cannot be localhost unless using host networking.
docker run -d \
--name ss-ims \
--env-file .env \
--restart unless-stopped \
ss-ims:latest
With Environment Variables
Inject environment variables directly:
docker run -d \
--name ss-ims \
-e DISCORD_BOT_TOKEN="your_token_here" \
-e DISCORD_MATCHES_CHANNEL_ID="123456789" \
-e DISCORD_REFEREE_ROLE_ID="123456789" \
-e DISCORD_ADMIN_ROLE_ID="123456789" \
-e DISCORD_GUILD_ID="123456789" \
-e POSTGRESQL_CONNECTION_STRING="Host=postgres;Database=ss26db;Username=ss;Password=ss" \
-e LANGUAGE="en" \
--restart unless-stopped \
ss-ims:latest
View Logs
Stop and Remove
docker stop ss-ims
docker rm ss-ims
Docker Compose Setup
For a complete deployment including PostgreSQL and Adminer:
Create docker-compose.yml
version : '3.8'
services :
postgres :
image : postgres:15-alpine
container_name : ss-postgres
environment :
POSTGRES_USER : ss
POSTGRES_PASSWORD : ss
POSTGRES_DB : ss26db
volumes :
- postgres_data:/var/lib/postgresql/data
- ./schema.sql:/docker-entrypoint-initdb.d/schema.sql
ports :
- "5432:5432"
healthcheck :
test : [ "CMD-SHELL" , "pg_isready -U ss -d ss26db" ]
interval : 10s
timeout : 5s
retries : 5
restart : unless-stopped
adminer :
image : adminer:latest
container_name : ss-adminer
ports :
- "8080:8080"
depends_on :
- postgres
restart : unless-stopped
ss-ims :
build :
context : ./ss.Integrated.Management.Server
dockerfile : Dockerfile
container_name : ss-ims
env_file :
- .env
depends_on :
postgres :
condition : service_healthy
restart : unless-stopped
volumes :
postgres_data :
Create .env file
DISCORD_BOT_TOKEN = your_token_here
DISCORD_MATCHES_CHANNEL_ID = 123456789
DISCORD_REFEREE_ROLE_ID = 123456789
DISCORD_ADMIN_ROLE_ID = 123456789
DISCORD_GUILD_ID = 123456789
POSTGRESQL_CONNECTION_STRING = Host = postgres ; Database = ss26db ; Username = ss ; Password = ss ; Port = 5432
LANGUAGE = en
Download database schema
curl -o schema.sql https://gist.githubusercontent.com/Angarn/ddd9cf693aaeeb9407cc46b750fce3e5/raw/
View logs
docker compose logs -f ss-ims
Service Access
Adminer: http://localhost:8080
PostgreSQL: localhost:5432
SS-IMS: Running in background, check logs for Discord connection status
Managing the Stack
Start Services
Stop Services
Restart Specific Service
View Logs
Rebuild After Code Changes
Production Deployment Considerations
Security
Critical security practices for production:
Use Docker secrets or external secret management (e.g., HashiCorp Vault)
Never commit .env files to version control
Run containers as non-root user
Enable Docker Content Trust (DCT)
Scan images for vulnerabilities with docker scan
Non-Root User
Modify the Dockerfile to run as non-root:
FROM mcr.microsoft.com/dotnet/runtime:9.0 AS runtime
WORKDIR /app
# Create non-root user
RUN useradd -m -u 1000 ssims
COPY --from=builder /app/out .
# Change ownership
RUN chown -R ssims:ssims /app
USER ssims
ENTRYPOINT [ "dotnet" , "ss.Integrated.Management.Server.dll" ]
Resource Limits
Prevent resource exhaustion by setting limits:
services :
ss-ims :
# ... other config
deploy :
resources :
limits :
cpus : '1.0'
memory : 512M
reservations :
cpus : '0.5'
memory : 256M
Health Checks
Implement application health checks:
services :
ss-ims :
# ... other config
healthcheck :
test : [ "CMD" , "dotnet" , "--list-runtimes" ]
interval : 30s
timeout : 10s
retries : 3
start_period : 40s
Logging Configuration
Configure logging drivers for production:
services :
ss-ims :
# ... other config
logging :
driver : "json-file"
options :
max-size : "10m"
max-file : "3"
Or use a centralized logging solution:
services :
ss-ims :
# ... other config
logging :
driver : "syslog"
options :
syslog-address : "tcp://logs.example.com:514"
Persistent Data
Always use named volumes for database data to prevent data loss during container updates.
volumes :
postgres_data :
driver : local
driver_opts :
type : none
o : bind
device : /var/lib/ss-ims/postgres
Environment-Specific Configurations
Use multiple compose files:
docker-compose.yml (Base)
docker-compose.prod.yml (Production)
version : '3.8'
services :
ss-ims :
build : ./ss.Integrated.Management.Server
env_file :
- .env
Deploy with:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Automatic Updates
For automated deployments with minimal downtime:
#!/bin/bash
# deploy.sh
set -e
git pull origin main
docker compose build ss-ims
docker compose up -d --no-deps ss-ims
docker image prune -f
Monitoring
Integrate with monitoring tools:
services :
prometheus :
image : prom/prometheus:latest
volumes :
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports :
- "9090:9090"
grafana :
image : grafana/grafana:latest
ports :
- "3000:3000"
volumes :
- grafana_data:/var/lib/grafana
volumes :
prometheus_data :
grafana_data :
Troubleshooting
Container Fails to Start
# Check logs
docker compose logs ss-ims
# Inspect container
docker inspect ss-ims
# Check environment variables
docker exec ss-ims env
Database Connection Issues
# Test PostgreSQL connectivity from SS-IMS container
docker exec ss-ims ping postgres
# Check if PostgreSQL is accepting connections
docker exec ss-postgres psql -U ss -d ss26db -c "SELECT 1;"
Discord Bot Not Connecting
Verify token
docker exec ss-ims env | grep DISCORD_BOT_TOKEN
Check network connectivity
docker exec ss-ims ping discord.com
Review application logs
docker logs ss-ims 2>&1 | grep -i discord
Image Build Failures
# Build with verbose output
docker build --progress=plain -t ss-ims:latest .
# Build without cache
docker build --no-cache -t ss-ims:latest .