Skip to main content
ipMoodle includes custom PHP settings optimized for Moodle’s requirements. These settings are baked into the Docker image during build time via the moodle.ini configuration file.

Default PHP configuration

The PHP settings are defined in the Dockerfile and written to /usr/local/etc/php/conf.d/moodle.ini:
Dockerfile:30-36
RUN { \
    echo 'max_input_vars=5000'; \
    echo 'memory_limit=512M'; \
    echo 'upload_max_filesize=512M'; \
    echo 'post_max_size=512M'; \
    echo 'max_execution_time=600'; \
} > /usr/local/etc/php/conf.d/moodle.ini

Configuration parameters

max_input_vars

max_input_vars
integer
default:"5000"
Maximum number of input variables allowed in a single requestMoodle forms with many fields (like course settings or quiz configuration) require higher values than PHP’s default (1000).Recommended: 5000 or higher for large Moodle installations

memory_limit

memory_limit
string
default:"512M"
Maximum amount of memory a script can allocateMoodle’s course backup, restore, and grade operations can be memory-intensive. The 512M limit handles most scenarios.Increase to 1024M or higher if:
  • Backing up very large courses (1000+ students)
  • Processing large CSV imports
  • Running complex reports

upload_max_filesize

upload_max_filesize
string
default:"512M"
Maximum size of an uploaded fileAllows students and teachers to upload large files like videos, presentations, or course backups.Note: Must be coordinated with Nginx’s client_max_body_size (also set to 512M)

post_max_size

post_max_size
string
default:"512M"
Maximum size of POST dataMust be equal to or greater than upload_max_filesize since file uploads are sent via POST requests.
Set this slightly larger than upload_max_filesize to account for other form data

max_execution_time

max_execution_time
integer
default:"600"
Maximum time in seconds a script can run before being terminated600 seconds (10 minutes) allows for long-running operations like:
  • Course backups and restores
  • Large file processing
  • Quiz report generation
  • Batch user enrollments
Coordinated with Nginx: The Nginx fastcgi_read_timeout is set to 300 seconds

Modifying PHP settings

Option 1: Rebuild the Docker image

For permanent changes, modify the Dockerfile:
1

Edit Dockerfile

nano Dockerfile
Modify lines 30-36 with your desired values:
RUN { \
    echo 'max_input_vars=10000'; \
    echo 'memory_limit=1024M'; \
    echo 'upload_max_filesize=1024M'; \
    echo 'post_max_size=1024M'; \
    echo 'max_execution_time=900'; \
} > /usr/local/etc/php/conf.d/moodle.ini
2

Rebuild and restart

docker compose build app
docker compose up -d --force-recreate app
3

Verify changes

docker compose exec app php -i | grep -E "memory_limit|upload_max_filesize"

Option 2: Runtime configuration with volume mount

For temporary testing without rebuilding:
1

Create local PHP ini file

mkdir -p ./php-config
cat > ./php-config/custom.ini <<EOF
memory_limit=1024M
upload_max_filesize=1024M
post_max_size=1024M
max_execution_time=900
max_input_vars=10000
EOF
2

Add volume mount to docker-compose.yml

Edit the app service:
app:
  build: .
  volumes:
    - ./html:/var/www/html
    - ./moodledata:/var/www/moodledata
    - ./php-config/custom.ini:/usr/local/etc/php/conf.d/custom.ini:ro
3

Restart the container

docker compose restart app

PHP extensions

The Dockerfile installs all PHP extensions required by Moodle:
Dockerfile:26-27
RUN docker-php-ext-install -j$(nproc) \
    intl soap zip pgsql pdo_pgsql exif opcache bcmath sockets mbstring sodium

Installed extensions

ExtensionPurpose
intlInternationalization support for multiple languages
soapWeb services integration
zipCourse backup/restore compression
pgsqlPostgreSQL database driver
pdo_pgsqlPDO driver for PostgreSQL
exifImage metadata reading
opcachePHP bytecode caching for performance
bcmathArbitrary precision math for grading
socketsNetwork communication
mbstringMulti-byte string handling (UTF-8)
sodiumModern cryptography library
gdImage manipulation (configured lines 22-23)

Opcache configuration

Opcache is enabled by default in PHP 8.2-FPM. For production optimization, add opcache settings:
cat > ./php-config/opcache.ini <<EOF
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.fast_shutdown=1
EOF
Mount this file and restart the app container.

Checking current configuration

View all PHP settings

docker compose exec app php -i

Check specific settings

docker compose exec app php -r "echo ini_get('memory_limit') . PHP_EOL;"
docker compose exec app php -r "echo ini_get('upload_max_filesize') . PHP_EOL;"
docker compose exec app php -r "echo ini_get('max_execution_time') . PHP_EOL;"

View loaded configuration files

docker compose exec app php --ini
Expected output:
Configuration File (php.ini) Path: /usr/local/etc/php
Loaded Configuration File:         (none)
Scan for additional .ini files in: /usr/local/etc/php/conf.d
Additional .ini files parsed:      /usr/local/etc/php/conf.d/docker-php-ext-gd.ini,
                                   /usr/local/etc/php/conf.d/docker-php-ext-intl.ini,
                                   /usr/local/etc/php/conf.d/moodle.ini

Performance tuning

PHP-FPM worker processes

The default PHP-FPM configuration uses dynamic process management. For high-traffic sites, create a custom www.conf:
[www]
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
Adjust pm.max_children based on available memory. Rule of thumb: (Total RAM - RAM for other services) / average memory per PHP process

Monitor PHP-FPM status

Enable the status page in www.conf:
pm.status_path = /status
Then access it via:
docker compose exec app php-fpm -t  # Test configuration
docker compose exec app env SCRIPT_NAME=/status SCRIPT_FILENAME=/status REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000

Troubleshooting

  1. Increase max_execution_time in Dockerfile
  2. Increase Nginx fastcgi_read_timeout in nginx/Default.conf
  3. Rebuild and restart both app and web containers
docker compose build app
docker compose up -d --force-recreate app web
Check that all three values are aligned:
  1. PHP upload_max_filesize (Dockerfile:33)
  2. PHP post_max_size (Dockerfile:34)
  3. Nginx client_max_body_size (nginx/Default.conf:8)
All should be set to the same value (512M by default).
  1. Increase memory_limit to 1024M or higher
  2. Check available container memory: docker stats moodle_app
  3. Consider increasing Docker resource limits if needed
For very large courses, you may need to use Moodle’s CLI backup:
docker compose exec app php /var/www/html/admin/cli/backup.php --courseid=123

Next steps

Nginx configuration

Align web server timeouts and upload limits

Custom PHP extensions

Add additional PHP extensions

Performance monitoring

Monitor PHP-FPM performance

Database configuration

Optimize PostgreSQL settings

Build docs developers (and LLMs) love