← Customise this setup

Docker Compose for PHP + MySQL + RabbitMQ

Stack
PHP-FPM + Nginx + MySQL + RabbitMQ

A plain PHP setup gives complete control over your application with no framework overhead — ideal for learning Docker with PHP, running legacy codebases, or building lightweight applications with minimal dependencies.

MySQL 8 is the world's most widely deployed open-source relational database. It integrates seamlessly with Symfony via Doctrine ORM and with Laravel via Eloquent, and benefits from extensive tooling and hosting support.

RabbitMQ is a reliable AMQP message broker for decoupling services and handling async workloads. Symfony Messenger and Laravel Queues both support RabbitMQ natively via the AMQP transport.

When should you use this stack?

PHP with MySQL and RabbitMQ is a solid default for local development when your production environment matches it. If you're evaluating alternatives, the related configurations below swap one piece at a time — same framework with a different database, or the same data layer under a different framework — so you can compare without starting from scratch.

Quick start
Start stack docker compose up -d
Web http://localhost:8080

compose.yml

compose.yml
services:
  nginx:
    image: nginx:latest
    ports:
      - "${WEB_PORT-8080}:80"
    volumes:
      - .:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - php

  php:
    image: php:8.5-fpm
    volumes:
      - .:/var/www/html

  mysql:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD-root}
      MYSQL_DATABASE: ${MYSQL_DATABASE-app}
      MYSQL_USER: ${MYSQL_USER-app}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD-secret}
    ports:
      - "${MYSQL_PORT-3306}:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  rabbitmq:
    image: rabbitmq:3-management
    environment:
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER-app}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS-secret}
    ports:
      - "${RABBITMQ_PORT-5672}:5672"
      - "${RABBITMQ_MANAGEMENT_PORT-15672}:15672"
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mysql_data:

docker/nginx/default.conf

Run mkdir -p docker/nginx first

docker/nginx/default.conf
server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

.env.example

Optional — Compose uses ${VAR-default} fallbacks

.env.example
WEB_PORT=8080

MYSQL_PORT=3306
MYSQL_DATABASE=app
MYSQL_USER=app
MYSQL_PASSWORD=secret

RABBITMQ_PORT=5672
RABBITMQ_MANAGEMENT_PORT=15672
RABBITMQ_DEFAULT_USER=app
RABBITMQ_DEFAULT_PASS=secret

Frequently asked questions

How do I start this PHP stack?
Download the files, run `docker compose up -d` from the project root, then open http://localhost:8080 in your browser. The web port is configurable via the `WEB_PORT` variable in `.env`.
Which PHP version does this configuration use?
This page uses PHP 8.5 by default. Use the generator above to pick 8.1 through 8.5 and regenerate the files with your chosen version.
How do I connect to MySQL from my host machine?
From your host, connect with `mysql -h 127.0.0.1 -P 3306 -u app -p` (password `secret` by default). From other containers on the same network, use host `mysql` and port 3306.
What port does RabbitMQ run on?
RabbitMQ listens on port 5672 for AMQP connections, with a management UI at http://localhost:15672 (default login `app` / `secret`).
Is this configuration production-ready?
No — it is tuned for local development (bind-mounted source, default credentials, exposed ports). For production, remove the bind mounts, set real secrets, and add resource limits and restart policies.

Related configurations