Skip to main content

Overview

This guide covers deploying the Electronic Invoice Processing API using Docker containers. Docker provides a consistent, isolated environment for running the application across different platforms.

Prerequisites

Before starting, ensure you have:

Docker

Docker Engine 20.10+ installedDownload Docker

Docker Compose

Docker Compose v2.0+ installedInstall Compose

Project Files

Dockerfile

The project includes a Dockerfile that defines the container image:
dockerfile
# Usa una imagen base oficial de Python
FROM python:3.9-slim

# Establece el directorio de trabajo dentro del contenedor
WORKDIR /app

# Copia los archivos de requerimientos y los instala
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copia el resto del código de la aplicación
COPY . .

# Expone el puerto en el que la aplicación va a escuchar
EXPOSE 8000

# Define el comando para iniciar la aplicación con Uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Base Image: python:3.9-slim
  • Lightweight Python 3.9 image
  • Minimal size for faster builds and deployments
Working Directory: /app
  • All application files stored here
Dependencies:
  • Copies requirements.txt first (layer caching)
  • Installs Python packages with --no-cache-dir flag
Application Code:
  • Copies all source files to container
Exposed Port: 8000
  • FastAPI/Uvicorn default port
Startup Command:
  • Runs Uvicorn ASGI server
  • Binds to all network interfaces (0.0.0.0)

Docker Compose Configuration

The docker-compose.yml file simplifies container orchestration:
docker-compose.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    command: uvicorn main:app --host 0.0.0.0 --port 8000
Version: 3.8
  • Docker Compose file format version
Service Name: web
  • Single service for the API
Build Context: . (current directory)
  • Builds from local Dockerfile
Port Mapping: 8000:8000
  • Host port 8000 → Container port 8000
Volume Mount: .:/app
  • Live code synchronization (development mode)
  • Changes reflect immediately without rebuild
Command Override:
  • Uses same Uvicorn command as Dockerfile

Deployment Methods

Port Configuration

Default Port Mapping

The application uses port 8000 by default:
Host Port 8000 → Container Port 8000

Changing the Host Port

If port 8000 is already in use, modify the port mapping:
services:
  web:
    ports:
      - "8080:8000"  # Host:Container
Only change the host port (left side). The container port (8000) should remain unchanged as it’s configured in the application.

Accessing on Custom Port

After changing to port 8080:

Volume Configuration

Development Volume

The default volume mount enables live code updates:
volumes:
  - .:/app
Development Mode Benefits:
  • Code changes reflect immediately
  • No need to rebuild container
  • Faster iteration cycle

Production Volume

For production, remove the volume mount or use specific volumes:
services:
  web:
    build: .
    ports:
      - "8000:8000"
    # volumes removed for production

Environment Variables

Adding Environment Variables

You can configure the application using environment variables:
services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - ENVIRONMENT=production
      - LOG_LEVEL=info
      - MAX_UPLOAD_SIZE=10485760

Example .env File

.env
ENVIRONMENT=production
LOG_LEVEL=info
MAX_UPLOAD_SIZE=10485760
CORS_ORIGINS=https://yourdomain.com
Add .env to .dockerignore to prevent copying sensitive data into the image.

Health Checks and Monitoring

Adding Health Checks

Enhance your docker-compose.yml with health checks:
docker-compose.yml
services:
  web:
    build: .
    ports:
      - "8000:8000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/docs"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Viewing Health Status

docker-compose ps
Healthy service shows (healthy) status.

Viewing Logs

docker-compose logs -f web

Container Resource Usage

docker stats invoice-api-container
Shows CPU, memory, network I/O, and disk I/O in real-time.

Production Considerations

Remove Development Volume

Remove or restrict volume mounts to prevent code modification in production.

Configure CORS Properly

Restrict CORS origins to specific domains. See CORS Configuration.

Use Environment Variables

Store sensitive configuration in environment variables, not in code.

Enable Health Checks

Implement health check endpoints for container orchestration.

Set Resource Limits

Define CPU and memory limits to prevent resource exhaustion.

Use Specific Tags

Avoid latest tag in production. Use specific version tags.

Resource Limits Example

docker-compose.yml
services:
  web:
    build: .
    ports:
      - "8000:8000"
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M

Troubleshooting

Error: Bind for 0.0.0.0:8000 failed: port is already allocatedSolution:
  1. Find process using the port:
    lsof -i :8000
    
  2. Kill the process or change port mapping:
    ports:
      - "8080:8000"
    
Error: ERROR: Could not find a version that satisfies the requirement...Solution:
  1. Ensure requirements.txt is present and valid
  2. Verify Python version compatibility
  3. Try building with no cache:
    docker-compose build --no-cache
    
Error: Container status shows Exited (1)Solution:
  1. Check logs for errors:
    docker-compose logs web
    
  2. Verify main.py exists and is valid
  3. Test locally without Docker first
Error: Connection refused or timeoutSolution:
  1. Verify container is running:
    docker-compose ps
    
  2. Check port mapping is correct
  3. Ensure firewall allows port 8000
  4. Try accessing from container:
    docker-compose exec web curl http://localhost:8000/docs
    
Error: Updated code doesn’t run in containerSolution:
  1. Verify volume mount is configured:
    volumes:
      - .:/app
    
  2. Restart the container:
    docker-compose restart
    
  3. If still not working, rebuild:
    docker-compose up --build
    

Next Steps

CORS Configuration

Configure CORS for production security

API Reference

Learn how to use the API endpoints

Excel Format

Understand required Excel file format

Docker Documentation

Official Docker documentation

Build docs developers (and LLMs) love