This guide provides comprehensive instructions for deploying the code2markdown Streamlit application using Docker containers.
- Docker Engine 20.10+
- Docker Compose 2.0+
- 4GB+ available RAM
- Internet connection for initial image pull
# Clone the repository
git clone https://github.com/yourusername/code2markdown.git
cd code2markdown
# Start the application
docker-compose --profile prod up -dAccess the application at: http://localhost:8501
graph TB
A[Python 3.12 Base] --> B[Build Stage]
B --> C[Install Dependencies]
C --> D[Copy Source Code]
D --> E[Runtime Stage]
E --> F[Streamlit App]
F --> G[SQLite Database]
F --> H[File System Access]
- Multi-stage build for optimized image size (~200MB vs ~800MB)
- Non-root user execution for enhanced security
- Health checks with automatic restart
- Environment variable configuration support
- Volume mounting for persistent data
- Cross-platform support (Linux/Windows/macOS)
Copy .env.example to .env and customize:
# Core Configuration
ENVIRONMENT=production
STREAMLIT_SERVER_PORT=8501
STREAMLIT_SERVER_ADDRESS=0.0.0.0
# Security Settings
STREAMLIT_SERVER_ENABLECORS=false
STREAMLIT_SERVER_ENABLECSRF_PROTECTION=true
# Database
DATABASE_URL=sqlite:///app/data/code2markdown.db
# Logging
LOG_LEVEL=INFO# Development mode with live code reloading
docker-compose --profile dev up -d
# Production mode with optimized settings
docker-compose --profile prod up -d
# Production with Nginx reverse proxy
docker-compose --profile prod-nginx up -d# Start development environment
docker-compose --profile dev up -d
# View logs
docker-compose logs -f app-dev
# Stop development
docker-compose --profile dev down# Start production environment
docker-compose --profile prod up -d
# Scale horizontally (if needed)
docker-compose --profile prod up -d --scale app-prod=3
# Stop production
docker-compose --profile prod down# Build and push to container registry
docker build -t your-registry/code2markdown:latest .
docker push your-registry/code2markdown:latest
# Deploy using cloud-specific tools
# (See cloud-specific sections below)- Runs as non-root user (
appuser) - Minimal base image (
python:3.12-slim) - No unnecessary packages in runtime
- Regular security scanning with Trivy
- CORS disabled by default
- CSRF protection enabled
- Configurable allowed hosts
- Health check endpoint exposed
- SQLite database in mounted volume
- No sensitive data in container image
- Environment variables for secrets
# Check application health
curl -f http://localhost:8501/_stcore/health
# Expected response: HTTP 200 OK# Check container status
docker ps
# View health check logs
docker inspect <container-id> | grep Health# View real-time logs
docker-compose logs -f app-prod
# View specific log level
docker-compose logs app-prod | grep ERROR# Find process using port 8501
netstat -tulpn | grep 8501
# Use alternative port
docker-compose --profile prod up -d -p 8502:8501# Fix data directory permissions
sudo chown -R 1000:1000 ./data
# Or use Docker user mapping
export USER_ID=$(id -u)
export GROUP_ID=$(id -g)
docker-compose --profile prod up -d# Check container logs
docker-compose logs app-prod
# Verify configuration
docker-compose config
# Rebuild without cache
docker-compose build --no-cache# Monitor resource usage
docker stats
# Adjust memory limits
# Add to docker-compose.yml:
# deploy:
# resources:
# limits:
# memory: 1G# Enable verbose logging
export VERBOSE=true
docker-compose --profile prod up -d
# Check startup time
docker-compose logs app-prod | grep "Starting"Create streamlit_config.toml:
[server]
port = 8501
address = "0.0.0.0"
headless = true
maxUploadSize = 200
[browser]
gatherUsageStats = false
[theme]
primaryColor = "#FF6B6B"
backgroundColor = "#FFFFFF"
secondaryBackgroundColor = "#F0F2F6"
textColor = "#262730"server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://app-prod:8501;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}# Backup data volume
docker run --rm -v code2markdown_data:/data -v $(pwd):/backup alpine tar czf /backup/data-backup.tar.gz -C /data .
# Restore data volume
docker run --rm -v code2markdown_data:/data -v $(pwd):/backup alpine tar xzf /backup/data-backup.tar.gz -C /data# Export SQLite database
docker exec -it code2markdown-app-prod-1 sqlite3 /app/data/code2markdown.db ".backup /app/data/backup.db"
# Import SQLite database
docker cp backup.db code2markdown-app-prod-1:/app/data/code2markdown.db# Pull latest image
docker-compose pull
# Rolling update with zero downtime
docker-compose --profile prod up -d --no-deps app-prod
# Clean up old images
docker image prune -f# Scan for vulnerabilities
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image your-registry/code2markdown:latest
# Update base image
# Edit Dockerfile to use latest Python version
# Rebuild and redeployThe repository includes a comprehensive GitHub Actions workflow (.github/workflows/docker-build.yml) that:
- Builds multi-platform images
- Runs security scans
- Deploys to staging/production
- Performs health checks
# Trigger workflow manually
gh workflow run docker-build.yml -f environment=production# Build image
docker build -t code2markdown .
# Run container
docker run -d -p 8501:8501 --name code2markdown code2markdown
# Interactive shell
docker run -it --rm code2markdown /bin/bash
# View logs
docker logs -f code2markdownFor issues and questions:
- Check the troubleshooting section above
- Review container logs:
docker-compose logs - Open an issue on GitHub with:
- Docker version:
docker --version - Compose version:
docker-compose --version - Error logs and configuration
- Docker version:
This Docker configuration is provided under the same license as the main project.