Docker Deployment Guide¶
Home → Documentation → Setup → Docker Deployment
Deploy Cesivi Server using Docker for production, development, and CI/CD environments.
Table of Contents¶
- Quick Start
- Docker Compose Setup
- Docker CLI Setup
- Volume Mapping
- Environment Configuration
- Health Checks
- Production Best Practices
- Troubleshooting
Quick Start¶
Fastest way to get running with Docker:
# Start container with Docker Compose
docker-compose up -d
# Verify container is running
docker-compose ps
# Check health
curl http://localhost:8080/_vti_bin/health
# View logs
docker-compose logs -f
Stop and cleanup:
docker-compose down
Docker Compose Setup¶
Default docker-compose.yml¶
The repository includes a production-ready docker-compose.yml:
version: '3.8'
services:
cesivi:
build:
context: .
dockerfile: Dockerfile
image: Cesivi:latest
container_name: cesivi-server
hostname: mocksharepoint.local
ports:
- "8080:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:8080
- Cesivi__DataRootPath=/app/MockData
- Cesivi__HostName=mocksharepoint.local
volumes:
- ./MockData:/app/MockData
- ./logs:/app/logs
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/_vti_bin/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
Start Container¶
# Build and start
docker-compose up -d
# Build without cache (after code changes)
docker-compose build --no-cache
docker-compose up -d
# View logs
docker-compose logs -f cesivi
# Check status
docker-compose ps
Stop Container¶
# Stop (keeps containers)
docker-compose stop
# Stop and remove containers
docker-compose down
# Stop and remove volumes (DELETES DATA!)
docker-compose down -v
Rebuild After Code Changes¶
# Stop existing container
docker-compose down
# Rebuild image (no cache)
docker-compose build --no-cache
# Start new container
docker-compose up -d
# Verify
curl http://localhost:8080/_vti_bin/health
Docker CLI Setup¶
Build Docker Image¶
# Build image
docker build -t Cesivi:latest .
# Build with specific tag
docker build -t Cesivi:1.0.0 .
# Build without cache
docker build --no-cache -t Cesivi:latest .
Run Container¶
Basic run:
docker run -d \
--name cesivi-server \
-p 8080:8080 \
Cesivi:latest
Production run with volumes:
docker run -d \
--name cesivi-server \
--hostname mocksharepoint.local \
-p 8080:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e Cesivi__DataRootPath=/app/MockData \
-e Cesivi__HostName=mocksharepoint.local \
-v ./MockData:/app/MockData \
-v ./logs:/app/logs \
--restart unless-stopped \
Cesivi:latest
Manage Container¶
# List running containers
docker ps
# View logs
docker logs -f cesivi-server
# Execute command in container
docker exec -it cesivi-server bash
# Stop container
docker stop cesivi-server
# Start stopped container
docker start cesivi-server
# Remove container
docker rm cesivi-server
# Remove container and volumes
docker rm -v cesivi-server
Volume Mapping¶
MockData Persistence¶
Why volume mapping? - Data persists after container restart - Data survives container removal - Easy backup and restore - Can share data between containers
Volume mapping syntax:
-v <host-path>:<container-path>
Example Configurations¶
1. Relative path (development):
volumes:
- ./MockData:/app/MockData
2. Absolute path (production):
volumes:
- /var/lib/Cesivi/data:/app/MockData
- /var/log/Cesivi:/app/logs
3. Named volumes (Docker-managed):
volumes:
- mockdata:/app/MockData
- logs:/app/logs
volumes:
mockdata:
driver: local
logs:
driver: local
4. Read-only volumes:
volumes:
- ./config:/app/config:ro
Backup and Restore¶
Backup MockData:
# Create backup from running container
docker exec cesivi-server tar czf /tmp/backup.tar.gz /app/MockData
# Copy backup to host
docker cp cesivi-server:/tmp/backup.tar.gz ./mockdata-backup.tar.gz
# Or backup from host-mapped volume
tar czf mockdata-backup.tar.gz ./MockData
Restore MockData:
# Stop container
docker-compose down
# Restore from backup
tar xzf mockdata-backup.tar.gz
# Start container
docker-compose up -d
Environment Configuration¶
Common Environment Variables¶
# ASP.NET Core
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=http://+:8080
# Cesivi
Cesivi__DataRootPath=/app/MockData
Cesivi__LogPath=/app/logs
Cesivi__HostName=mocksharepoint.local
# Performance
Cesivi__Performance__CacheEnabled=true
Cesivi__Performance__CacheDurationMinutes=30
# Logging
Logging__LogLevel__Default=Information
Logging__LogLevel__Microsoft.AspNetCore=Warning
Docker Compose with .env File¶
Create .env file:
# .env
ASPNETCORE_ENVIRONMENT=Production
MOCKDATA_PATH=/app/MockData
HTTP_PORT=8080
CONTAINER_NAME=cesivi-server
Use in docker-compose.yml:
services:
cesivi:
container_name: ${CONTAINER_NAME}
ports:
- "${HTTP_PORT}:8080"
environment:
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
- Cesivi__DataRootPath=${MOCKDATA_PATH}
Multi-Instance Deployment¶
Run multiple containers on different ports:
docker-compose-dev.yml:
services:
cesivi-dev:
image: Cesivi:latest
container_name: spmock-dev
ports:
- "8080:8080"
volumes:
- ./MockData-dev:/app/MockData
docker-compose-staging.yml:
services:
cesivi-staging:
image: Cesivi:latest
container_name: spmock-staging
ports:
- "8081:8080"
volumes:
- ./MockData-staging:/app/MockData
Start both:
docker-compose -f docker-compose-dev.yml up -d
docker-compose -f docker-compose-staging.yml up -d
Health Checks¶
Docker Health Check¶
The Dockerfile includes a built-in health check:
HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=40s \
CMD curl -f http://localhost:8080/_vti_bin/health || exit 1
Check Container Health¶
# View health status
docker ps
# Output shows health status:
# CONTAINER ID STATUS
# abc123def456 Up 5 minutes (healthy)
# Detailed health information
docker inspect cesivi-server | grep -A 10 Health
# View health check logs
docker inspect cesivi-server --format='{{json .State.Health}}' | jq
Custom Health Checks¶
For load balancers:
# Endpoint: GET /_vti_bin/health
# Expected: 200 OK with {"status": "Healthy"}
curl http://localhost:8080/_vti_bin/health
For orchestration (Kubernetes):
livenessProbe:
httpGet:
path: /_vti_bin/health
port: 8080
initialDelaySeconds: 40
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /_vti_bin/health
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
Production Best Practices¶
1. Security¶
Run as non-root user:
Dockerfile already includes this:
RUN addgroup --gid 1000 appuser && \
adduser --uid 1000 --gid 1000 --disabled-password --gecos "" appuser
USER appuser
Use secrets for sensitive data:
# Don't use environment variables for secrets
# Use Docker secrets (Swarm) or Kubernetes secrets
# Docker Swarm example
echo "my-secret-token" | docker secret create api-token -
docker service create \
--secret api-token \
Cesivi:latest
Restrict network access:
services:
cesivi:
networks:
- internal
# Only expose via reverse proxy
nginx:
networks:
- internal
- external
ports:
- "443:443"
networks:
internal:
internal: true
external:
2. Reverse Proxy (SSL Termination)¶
nginx as reverse proxy:
# /etc/nginx/conf.d/cesivi.conf
upstream cesivi {
server 127.0.0.1:8080;
}
server {
listen 443 ssl http2;
server_name mocksharepoint.example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
proxy_pass http://cesivi;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Docker Compose with nginx:
version: '3.8'
services:
cesivi:
image: Cesivi:latest
networks:
- internal
volumes:
- ./MockData:/app/MockData
nginx:
image: nginx:alpine
ports:
- "443:443"
networks:
- internal
- external
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- cesivi
networks:
internal:
external:
3. Resource Limits¶
services:
cesivi:
image: Cesivi:latest
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
4. Logging¶
Docker logging driver:
services:
cesivi:
image: Cesivi:latest
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "10"
Forward logs to centralized system:
services:
cesivi:
image: Cesivi:latest
logging:
driver: "syslog"
options:
syslog-address: "tcp://logserver:514"
tag: "Cesivi"
5. Auto-Restart Policy¶
services:
cesivi:
image: Cesivi:latest
restart: unless-stopped # or "always", "on-failure"
Restart policies:
- no - Never restart (default)
- always - Always restart on failure
- on-failure - Restart only on error exit code
- unless-stopped - Always restart unless manually stopped
Troubleshooting¶
Issue: Container Won't Start¶
Check logs:
docker-compose logs cesivi
docker logs cesivi-server
Common causes: - Port already in use - Invalid environment variables - Volume mount permission errors - Missing required files
Issue: Port Already in Use¶
Symptoms:
Error: bind: address already in use
Solution:
# Find process using port
netstat -ano | findstr :8080
# Kill process or use different port
docker-compose down
# Edit docker-compose.yml to use different port
# ports:
# - "8081:8080"
docker-compose up -d
Issue: Volume Permission Denied¶
Symptoms:
System.UnauthorizedAccessException: Access to path '/app/MockData' is denied
Solution:
# Fix permissions on host
sudo chown -R 1000:1000 ./MockData
# Or run container as root (not recommended for production)
docker run -u root ...
Issue: Health Check Failing¶
Check health:
docker inspect cesivi-server --format='{{json .State.Health}}' | jq
Common causes:
- Server not fully started (increase start_period)
- Port not exposed correctly
- Application crashed
Solution:
# Increase start period in docker-compose.yml
healthcheck:
start_period: 60s # Give more time to start
# Check application logs
docker-compose logs cesivi
Issue: Container Exits Immediately¶
Check exit code:
docker ps -a
docker logs cesivi-server
Solution:
# Run interactively to debug
docker run -it --rm Cesivi:latest bash
# Or check application logs
docker-compose logs -f
Issue: Can't Access from Host¶
Symptoms:
- curl http://localhost:8080 fails
- Container is running
Solution:
# Verify container is listening
docker exec cesivi-server netstat -tuln | grep 8080
# Check firewall
sudo ufw status
sudo ufw allow 8080/tcp
# Verify port mapping
docker port cesivi-server
Kubernetes Deployment¶
Example Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: cesivi
spec:
replicas: 2
selector:
matchLabels:
app: cesivi
template:
metadata:
labels:
app: cesivi
spec:
containers:
- name: cesivi
image: Cesivi:latest
ports:
- containerPort: 8080
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: Cesivi__DataRootPath
value: "/app/MockData"
volumeMounts:
- name: mockdata
mountPath: /app/MockData
livenessProbe:
httpGet:
path: /_vti_bin/health
port: 8080
initialDelaySeconds: 40
periodSeconds: 30
readinessProbe:
httpGet:
path: /_vti_bin/health
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
resources:
limits:
cpu: "2"
memory: "2Gi"
requests:
cpu: "500m"
memory: "512Mi"
volumes:
- name: mockdata
persistentVolumeClaim:
claimName: cesivi-pvc
---
apiVersion: v1
kind: Service
metadata:
name: cesivi
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: cesivi
Next Steps¶
- Configure environment → Configuration Guide
- Import data → Migration Tool Guide
- Monitor performance → Troubleshooting Guide
- Learn APIs → Features Overview
Support Resources¶
- Docker issues → Docker Troubleshooting
- Configuration → Configuration Guide
- General troubleshooting → General Troubleshooting