Service Overview
The ipMoodle stack consists of four Docker services, each with a specific role in the system. This page provides detailed information about each service’s configuration, purpose, and dependencies.db
PostgreSQL 16 database server
app
PHP-FPM application processor
cron
Automated task scheduler
web
Nginx web server
Database Service (db)
The database service provides persistent data storage for Moodle using PostgreSQL 16.Configuration
Key Details
Image Information
Image Information
Image:
postgres:16-alpineUses the official PostgreSQL 16 image based on Alpine Linux for minimal size and security. This version provides:- Latest PostgreSQL 16 features and performance improvements
- Reduced image size (~80MB compressed vs ~140MB for Debian-based)
- Alpine Linux security hardening
Environment Variables
Environment Variables
- POSTGRES_DB: Database name created on first run
- POSTGRES_USER: Superuser account for database access
- POSTGRES_PASSWORD: Password for the superuser account
.env file for security.Volume Mounts
Volume Mounts
Host Path:
Container Path:
./db_dataContainer Path:
/var/lib/postgresql/dataThis volume persists all PostgreSQL data files, including:- Database tables and indexes
- Transaction logs (WAL files)
- Configuration files (
postgresql.conf,pg_hba.conf)
Networking
Networking
Network:
Internal Port:
External Access: Not exposed to hostThe database is only accessible from within the Docker network, accessible by service name
moodle-net (bridge)Internal Port:
5432 (default PostgreSQL port)External Access: Not exposed to hostThe database is only accessible from within the Docker network, accessible by service name
db.Restart Policy
Policy:always
The container automatically restarts on:
- Container failure or crash
- Docker daemon restart
- System reboot
Application Service (app)
The app service runs PHP-FPM to process Moodle’s PHP code and handle business logic.Configuration
Key Details
Custom Image Build
Custom Image Build
Build Context:
Dockerfile:
Base Image:
. (root directory)Dockerfile:
./DockerfileBase Image:
php:8.2-fpm-alpineThe custom image includes:- PHP 8.2 with FPM (FastCGI Process Manager)
- Moodle-required extensions:
intl,soap,zip,pgsql,pdo_pgsql,exif,opcache,bcmath,sockets,mbstring,sodium - GD library with JPEG and FreeType support
- Optimized PHP configuration for Moodle
- Ghostscript for PDF generation
- dcron for cron functionality
Environment Variables
Environment Variables
- MOODLE_DB_TYPE:
pgsql(PostgreSQL driver) - MOODLE_DB_HOST:
db(service name, resolves via Docker DNS) - MOODLE_DB_NAME: Database name from
.env - MOODLE_DB_USER: Database user from
.env - MOODLE_DB_PASSWORD: Database password from
.env - MOODLE_URL: Public-facing URL for Moodle site
config.php.Volume Mounts
Volume Mounts
Mount 1:
./html:/var/www/html (read-write)- Moodle application code
- Installed plugins
- Theme files
config.phpconfiguration
./moodledata:/var/www/moodledata (read-write)- User uploaded files
- Cache data
- Session storage
- Temporary files
Both volumes are shared with the
cron service to ensure consistency.Dependencies
Dependencies
Depends On:
dbDocker Compose ensures the database container starts before the app container. However, this doesn’t guarantee the database is ready to accept connections.The deployment script (
deploy.sh) includes a database readiness check before installing Moodle.FastCGI Configuration
The app service listens on port9000 for FastCGI connections from Nginx:
Cron Service (cron)
A dedicated sidecar container that executes Moodle’s scheduled maintenance tasks every minute.Configuration
Key Details
Custom Command
Custom Command
The container overrides the default entrypoint with a shell command that:
- Creates a crontab file for the
www-datauser - Schedules Moodle’s cron script to run every minute (
*/1 * * * *) - Redirects output to
/dev/nullto prevent log accumulation - Starts
crondin foreground mode (-f) with log level 8 (debug)
The
-f flag keeps crond running in the foreground, which is required for Docker containers to remain active.Why a Separate Container?
Why a Separate Container?
Using a dedicated cron container instead of running cron inside the app container provides:
- Isolation: Cron failures don’t affect PHP-FPM processing
- Scalability: App containers can be scaled horizontally without duplicating cron jobs
- Monitoring: Easier to monitor and restart cron independently
- Resource Management: Separate CPU/memory limits for scheduled tasks
Shared Volumes
Shared Volumes
Cron Schedule
Cron Schedule
Frequency: Every 1 minute (
*/1 * * * *)This matches Moodle’s recommended cron frequency for optimal performance. The cron script handles:- Sending queued emails
- Processing scheduled tasks
- Cleaning up temporary files
- Updating search indexes
- Running plugin-specific maintenance
Monitoring Cron Execution
Check cron logs with:Web Service (web)
The web service runs Nginx as a reverse proxy, handling HTTP requests and serving static files.Configuration
Key Details
Image Information
Image Information
Image:
nginx:alpineOfficial Nginx image based on Alpine Linux:- Lightweight (~24MB compressed)
- Includes Nginx 1.25+ with HTTP/2 support
- Production-ready with minimal attack surface
Port Mapping
Port Mapping
Host Port:
Container Port:
80Container Port:
80This is the only external port exposed by the entire stack. All web traffic enters through this port.For HTTPS support, you’ll need to modify the port mapping and add SSL certificates. See SSL/HTTPS Configuration.
Volume Mounts
Volume Mounts
Mount 1:
./html:/var/www/html:ro (read-only)- Nginx needs access to static files (CSS, JS, images)
- Read-only mount improves security
- Prevents accidental file modification via web server
./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro (read-only)- Custom Nginx configuration for Moodle
- Overrides default Nginx site configuration
- Read-only to prevent container modifications
Nginx Configuration Highlights
Nginx Configuration Highlights
The See Nginx Configuration for detailed documentation.
default.conf file includes Moodle-specific optimizations:Request Routing
Nginx routes requests based on file type:- Static Files (CSS, JS, images): Served directly from
/var/www/html - PHP Files: Proxied to
app:9000via FastCGI - Sensitive Paths: Blocked (vendor, node_modules, .git)
Dockerfile Details
Bothapp and cron services are built from the same Dockerfile:
Build Stages Explained
Stage 1: Dependencies
Installs Alpine packages needed for PHP extensions and tools
Stage 2: GD Configuration
Configures GD library with JPEG and FreeType support for image manipulation
Stage 3: PHP Extensions
Compiles and installs all PHP extensions required by Moodle
Stage 4: PHP Tuning
Sets custom PHP.ini values optimized for Moodle workloads
The UID/GID alignment (82) ensures consistent file permissions across containers and the host system.
Service Communication
All services communicate exclusively through themoodle-net network:
- No direct database access from the internet
- Centralized request handling through Nginx
- Isolated cron execution without network exposure
Next Steps
Network Details
Learn about network topology and communication
Configuration
Configure environment variables and settings