Understanding the MobileAudit Docker Compose Architecture: Web, Worker, and Service Interactions

MobileAudit uses a five-service Docker Compose architecture where Nginx proxies external traffic to a Django web application, which delegates background tasks to Celery workers via RabbitMQ, with PostgreSQL persisting all audit data.

The mpast/mobileaudit repository implements a clean microservice-style Docker Compose architecture that separates concerns across five distinct containers. This design isolates the web interface, background processing, message queuing, data persistence, and reverse proxying into dedicated services that communicate over a shared Docker network.

Overview of the MobileAudit Service Stack

The architecture defined in docker-compose.yaml orchestrates five primary services:

  • db: PostgreSQL 16 database for persistent storage
  • web: Django application server handling HTTP requests
  • nginx: Reverse proxy terminating external traffic on port 8888
  • rabbitmq: Message broker managing asynchronous task queues
  • worker: Celery background processor consuming tasks from RabbitMQ

Each service runs in isolation but resolves other services by their container names (e.g., db, rabbitmq) through Docker's internal DNS.

Service Definitions and Configurations

Database Service (db)

The db service uses the official postgres:16-bullseye image and exposes port ${SQL_PORT:-5432}. It mounts a named volume db-data to ensure audit records survive container restarts.

Configuration loads from .env.example, defining the database name, user, and password. The web and worker services connect via the hostname db on the default PostgreSQL port.

Web Application Service (web)

Built from the repository root using Dockerfile, the web service produces the mobile_audit image. It executes entrypoint/web_entrypoint.sh to initialize Django and start the development server on port 8000.

The service mounts the source code into /app for live reloading during development. It declares an explicit dependency on the db service to ensure database readiness before application startup.

Reverse Proxy Service (nginx)

The nginx service runs nginx:stable-bullseye and binds host port 8888 to container port 8888. It loads nginx/app.conf, which defines upstream proxying to the web service.

Nginx terminates SSL (if configured) and handles static file serving, load balancing, and connection pooling. The service depends on web, ensuring the application server is available before accepting external traffic.

Message Broker Service (rabbitmq)

Using rabbitmq:3.13.0-management, this service provides AMQP messaging on port 5672 and the management UI. Credentials source from .env.example, matching the configuration used by Django's Celery integration.

The worker service links directly to rabbitmq, enabling hostname resolution and network access for message consumption.

Background Worker Service (worker)

Also using the mobile_audit image, the worker service executes entrypoint/worker_entrypoint.sh to start Celery workers. It processes audit tasks asynchronously, fetching jobs from rabbitmq and persisting results to the db service.

The worker links to both rabbitmq (for task consumption) and web (for configuration access), with an explicit depends_on constraint ensuring RabbitMQ starts first.

Service Interactions and Data Flow

Startup Sequence and Dependencies

Docker Compose orchestrates startup order through depends_on directives defined in docker-compose.yaml:

  1. db initializes first, creating the PostgreSQL instance
  2. web starts once db is ready, running migrations and starting the Django server
  3. nginx launches after web is healthy, opening port 8888 for external access
  4. rabbitmq starts independently, providing the message queue
  5. worker initializes last, after rabbitmq is available, to begin consuming tasks

HTTP Request Handling Flow

External clients interact with the Docker Compose architecture through the following path:

  1. Client sends request to http://localhost:8888
  2. nginx (listening on host port 8888) receives the connection
  3. Nginx proxies the request to the web service at web:8000 according to nginx/app.conf
  4. The Django application processes the request, querying the db service via PostgreSQL protocol on port 5432
  5. Response flows back through nginx to the client

Asynchronous Task Processing Flow

Background audit jobs flow through the message broker architecture:

  1. The web service publishes audit tasks to rabbitmq using Celery's AMQP producer on port 5672
  2. rabbitmq queues the message in the appropriate exchange
  3. The worker service (running Celery workers) consumes the message from rabbitmq:5672
  4. The worker performs the audit, fetching additional configuration from web if needed
  5. Results are persisted to the db service using SQLAlchemy or Django ORM connections

Data Persistence Strategy

The architecture ensures data durability through Docker volumes and service separation:

  • db-data volume: Mounts /var/lib/postgresql/data in the db container, preserving audit records across container restarts and rebuilds
  • Source mounts: The web and worker services mount the repository root into /app, enabling live code updates without image rebuilds during development
  • Configuration externalization: All sensitive credentials and environment variables load from .env.example, keeping secrets out of the container images

Key Configuration Files

The Docker Compose architecture relies on several critical files located in the repository root:

  • docker-compose.yaml: Defines the five services, their dependencies, port mappings, volume mounts, and environment variable injection
  • Dockerfile: Multi-stage build definition creating the mobile_audit image used by both web and worker services
  • entrypoint/web_entrypoint.sh: Initialization script that waits for database readiness, runs Django migrations, and starts the Gunicorn development server
  • entrypoint/worker_entrypoint.sh: Startup script that initializes Celery workers and connects them to the RabbitMQ broker
  • nginx/app.conf: Reverse proxy configuration defining upstream servers, static file handling, and client connection parameters

Common Operations and Commands

Manage the MobileAudit Docker Compose architecture using these standard commands:

Start the entire stack in detached mode:

docker compose up -d

View real-time logs across all services:

docker compose logs -f

Execute Django management commands inside the web container:

docker compose exec web python manage.py migrate

Access the PostgreSQL database directly from the host:

psql -h localhost -p 5432 -U postgres -d audit

Publish a test message to the RabbitMQ queue:

docker compose exec rabbitmq rabbitmqadmin publish exchange=amq.default routing_key=task payload='{"type":"audit","target":"example.com"}'

Summary

  • MobileAudit implements a five-service Docker Compose architecture separating web serving, background processing, data persistence, message queuing, and reverse proxying.
  • Nginx terminates external traffic on port 8888 and proxies to the Django web service, which depends on the db PostgreSQL container.
  • RabbitMQ handles asynchronous task distribution between the web application and worker processes, enabling scalable background audit jobs.
  • All services communicate over Docker's internal network using service names as hostnames, with data persisted via named volumes and environment configuration externalized to .env.example.

Frequently Asked Questions

What is the startup order of services in MobileAudit?

Docker Compose starts services according to the depends_on directives defined in docker-compose.yaml. The db service initializes first, followed by the web service once the database is ready. Nginx starts after the web service is healthy, while rabbitmq launches independently. The worker service starts last, ensuring the message broker is available before consuming tasks.

How does Nginx communicate with the web service?

Nginx acts as a reverse proxy using the configuration defined in nginx/app.conf. It listens on host port 8888 and forwards incoming HTTP requests to the web service at its internal address web:8000. The depends_on constraint ensures Nginx only starts after the web container is running, preventing connection errors during startup.

What is the role of RabbitMQ in the MobileAudit architecture?

RabbitMQ serves as the message broker for Celery-based asynchronous task processing. When the web service enqueues an audit job, it publishes a message to RabbitMQ's AMQP endpoint at rabbitmq:5672. The worker service consumes these messages, executes the background audit tasks, and persists results to the database, decoupling heavy processing from the HTTP request/response cycle.

How is data persisted across container restarts?

MobileAudit uses Docker named volumes and externalized configuration to ensure data durability. The db service mounts a volume named db-data to /var/lib/postgresql/data, preserving all audit records and schema changes across container restarts. Environment variables and credentials load from .env.example, ensuring configuration persists independently of container lifecycles.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →