Creating a simple environment with Docker, PHP 8.4, Composer, Nginx, and MariaDB.
Source: Dev.to
First article on this platform – keeping things simple, practical, and easy to follow.
If you’ve ever struggled with installing PHP extensions, configuring Nginx, or setting up a local database, Docker can make your life much easier.
In this guide we’ll build a modern, minimal development stack that runs with a single command.
Stack
- PHP 8.4 (FPM)
- Composer
- Nginx
- MariaDB
- Docker & Docker Compose
All services will start together with one command.
Folder Structure
root-folder/
├── docker/
│ ├── nginx/
│ │ └── default.conf
│ └── php/
│ └── Dockerfile
├── src/
│ └── index.php
├── docker-compose.yml
└── composer.json
| Folder | Responsibility |
|---|---|
docker/php | Custom PHP image & extensions |
docker/nginx | Nginx configuration |
src | Application source code |
1. PHP Dockerfile
Create docker/php/Dockerfile:
# Base image with PHP 8.4 and FPM
FROM php:8.4-fpm
# Install system dependencies and PHP extensions
RUN apt-get update && apt-get install -y \
git \
unzip \
libzip-dev \
&& docker-php-ext-install pdo pdo_mysql zip
# Install Composer from the official image
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# Set the working directory
WORKDIR /var/www/html
What it does
- Uses PHP 8.4‑FPM (ideal for Nginx).
- Installs common tools (
git,unzip). - Enables essential extensions (
pdo,pdo_mysql,zip). - Adds Composer without a manual download.
2. Nginx Configuration
Create docker/nginx/default.conf:
server {
listen 80;
index index.php index.html;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Key points
- Listens on port 80.
- Serves files from
/var/www/html. - Forwards
.phprequests to the PHP container via FastCGI.
3. Docker‑Compose File
Create docker-compose.yml in the project root:
version: '3.9'
services:
php:
build: ./docker/php
container_name: php84
volumes:
- ./src:/var/www/html
depends_on:
- mariadb
nginx:
image: nginx:latest
container_name: nginx
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
mariadb:
image: mariadb:11
container_name: mariadb
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: app
ports:
- "3306:3306"
volumes:
- mariadb_data:/var/lib/mysql
volumes:
mariadb_data:
Explanation
| Service | Purpose |
|---|---|
php | Builds a custom PHP 8.4 image, mounts src/ so changes are reflected instantly, and waits for MariaDB to start. |
nginx | Uses the official Nginx image, maps host port 8080 → container port 80, shares the same code volume, and loads the custom config. |
mariadb | Runs MariaDB 11, creates a database & user on startup, exposes port 3306 (optional), and stores data in a named volume (mariadb_data). |
volumes | mariadb_data persists the database across container restarts. |
4. Sample PHP Application
Create src/index.php:
PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
echo "PHP is running and connected to MariaDB successfully!";
} catch (PDOException $e) {
echo "Database connection failed: {$e->getMessage()}";
}
- Uses PDO (the recommended way to talk to databases in PHP).
- Connects to MariaDB via the service name
mariadb. - Prints a success message on a good connection, otherwise shows the error.
5. Composer Configuration
Create composer.json:
{
"name": "example/docker-php",
"require": {}
}
Running Composer inside the container
docker compose run --rm php composer install
This uses the same PHP environment defined in Docker, avoiding any local PHP version issues.
6. Bring It All Up
From the project root:
docker compose up -d --build
Open your browser and visit:
http://localhost:8080
You should see:
PHP is running and connected to MariaDB successfully!
If the message appears, PHP, Nginx, and MariaDB are communicating correctly. 🎉
What You Get
- PHP 8.4 ready for development
- Composer fully integrated
- Nginx as a lightweight web server
- MariaDB with persistent data
- A clean and isolated development environment
This is a solid starting point for plain PHP projects and APIs.
That’s all for today, folks!