Stack Docker con Apache, PHP e MySQL/MariaDB

In questo articolo proverò a spiegare come costruire un ambiente web di sviluppo o di test (sconsigliato per la produzione) attraverso container Docker. Lo stack sarà generato attraverso Docker Compose e sarà costituito da Apache, PHP e MySQL/MariaDB.

Prima di proseguire con la lettura di questo articolo è bene conoscere le basi sul mondo della containerizzazione e sopratutto su cosa sia Docker in quanto questo articolo tratta un aspetto avanzato dal semplice Hello Word!

Lo scopo è quello di realizzare un ambiente dove sia possibile sviluppare o testare una o più webapp senza la necessità di utilizzare applicativi tipo XAMPP / WampServer / MAMP, o creare sul proprio host un server web/db persistente.
Chi sviluppa sa bene quanto sia importante l’allineamento tra l’ambiente di sviluppo e quello di produzione e con Docker si può fare.

Per far ciò utilizzeremo l’orchestratore di Docker ovvero docker-compose. Le immagini ufficiali prelevate dall’hub di PHP php-apache e mysql o mariadb a discrezione personale. In questo articolo descrivo l’utilizzo di mysql ma usando mariadb cambia ben poco.


Parte tecnica.


Composizione dello Stack

  • Apache version: 2.4
  • PHP version: 7.1
  • MySQL version: 5.6

Il numero di versione è a discrezione ma va tenuto presente che ogni versione potrebbe avere la necessità di essere configurata in maniera diversa sul proprio Dockerfile utile alla costruzione build del container.

Immmagini Docker Utilizzate

Per avere lo stack sopra descritto useremo le seguenti immagini docker ufficiali reperibili dal Docker Hub.

  • php:7.1-apache
  • mysql:5.6

Alberatura cartella di progetto

docker-amp-slim
│   .env
│   .gitignore
│   docker-compose.yml
│   LICENSE
│   Makefile
│   README.md
│   
├───app
│       index.php
│       info.php
│       
├───db        
├───docker
│   ├───mysql
│   │   │   Dockerfile
│   │   │   
│   │   └───init
|   |           000-operations.sql
│   │           dbapp.sql
|   |           zzz-operations.sql
│   │       
│   └───php-apache
│           app.conf
│           Dockerfile
│           
└───logs
    ├───db
    └───web

Variabili d’Ambiente

Per avere una maggiore versatilità e dinamicità su vari sistemi o computer sul quale verrà svolto il lavoro le best practice sono quelle di utilizzare un file che contiene tutte le variabili d’ambiente principali (es. nome applicazione, password database, ecc.). L’utilizzo di questo file ci permette di poter modificare configurazioni fondamentali dello stack senza mettere mano ai file sorgenti applicativi.

Il file che contiene tali variabili è denominato semplicemente come .env è ed presente nella cartella principale di progetto, la root.

E’ molto importante visualizzare e nel caso modificare queste variabili prima di costruire lo stack.

File .env

#!/usr/bin/env bash

#### GENERAL ####

PROJECT_NAME=docker-amp-slim
VERSION_ID=1

# XDEBUG=1 / enabled | XDEBUG=0 / disabled
XDEBUG=1

TIME_ZONE=Europe/Rome
APP_URL=http://localhost/

DB_USER=mysql
DB_GROUP=mysql

#### APACHE #### # APACHE_VERSION=2.4
APACHE_PORT_EXPOSED=80

#### MYSQL #### # MYSQL_VERSION=5.6
DB_PORT_EXPOSED=3306
DB_ROOTPASS=pass
DB_USER=dbuser
DB_PASS=dbpass
DB_NAME=dbapp

#### PHP #### # PHP_VERSION=7.1

Descrizione delle variabili d’ambiente

  • PROJECT_NAME: Nome dello stack Docker
  • VERSION_ID: Identificativo del tuo stack di progetto. (Da usare solo se ritieni di lavorare con più versioni differenti tra loro)
  • XDEBUG: Libreria PHP per il debug. Usa 1 se la vuoi installare ed utilizzare altrimenti usa 0.
  • TIME_ZONE: Fuso orario, usato da PHP e MySQL.
  • APP_URL: Url della tua applicazione web. Usata principalmente per CMS/Frameweork come WordPress, Drupal, CodeIgniter, etc.
  • APACHE_PORT_EXPOSED: Porta utilizzata da Apache.
  • DB_PORT_EXPOSED: Porta utilizzata dal database. Usata per installare la web app tramite eventuali wizard di CMS o usata anche per connettersi tramite client esterni come HeidiSQL o MySQL Workbench per creare database o tabelle. Per configurare la connessione su un client esterno usare come parametri host 127.0.0.1, username root, per la password usa la DB_ROOTPASS impostata e per la port usa la DB_PORT_EXPOSED impostata sul file .env.
  • DB_ROOTPASS: Password di root. Non è un metodo sicuro da usare in produzione ma per lo sviluppo è accettabile.
  • DB_USER: Username usato dalla webapp per la connessione al database.
  • DB_PASS: Password usato dalla webapp per la connessione al database.
  • DB_NAME: Nome del database usato dalla webapp. Questo database verrà creato durante la costruzione dello stack, altrimenti puoi creare il database tramite docker exec o tramite client esterni.

Se vuoi approfondire il concetto del file di variabili e i parametri in esso contenuti ti consiglio di leggere questa guida.

Descrizione dello spazio di lavoro workspace

Cartella della webapp: app

Questa è la cartella contenente la tua webapp. Inserisci qui i sorgenti del tuo progetto o installa qui dentro i sorgenti del CMS/Framework.

Connessione al database tramite sorgenti PHP

Per connettersi al database dal Framework o tramite sorgenti hand made per versatilità usa la funzione PHP getenv() (vedi un esempio nei sorgenti di index.php).

$dbhost = getenv('DB_HOST');
$dbuser = getenv('DB_USER');
$dbpass = getenv('DB_PASS');
Per installare un CMS tramite procedura guidata

Usa i seguenti parametri quando richiesti.

  • hostname: db
  • database: DB_NAME assegnato nel file di variabili .env
  • username: DB_USER assegnato nel file di variabili .env
  • password: DB_PASS assegnato nel file di variabili .env
  • port: 3306 anche se è la porta di default è fondamentale dichiarala

Cartella del database: db

Se non hai questa cartella, essa verrà creata alla prima costruzione dello stack.

Contiene tutti i file sorgenti di tutti i database usati nello stack. E’ molto importante non lavorare in questa cartella e sopratutto non modificare i file al suo interno. E’ da usare solo come archivio ma qualora hai intenzione di migrare l’ambiente su altro computer ricordati di spostare questa cartella e tutto il suo contenuto ma senza apporre alcuna modifica ai file contenuti al suo interno.

Se non vuoi che i sorgenti dei database siano salvati all’interno di questa cartella usa i volumi nel docker-compose (vedi in seguito).

Cartella dei logs: logs

La scrittura dei logs è disabilitata di default. Se hai bisogno di abilitarla vedi nelle Note aggiuntive.

Note aggiuntive


  • Lo stack è stato testato anche con PHP 7.3, MySQL 5.7 e MariaDB 10.x. YPuoi modificare queste impostazioni direttamente dal Dockerfile.

  • Al termine della prima build dovrai attendere alcuni minuti prima di poterti connettere al database. Questo accade perchè tutti i micro servizi all’interno dei container dovranno essere inizializzati e queste operazioni effettuate in background richiedono del tempo.

  • Se vuoi avere i database in un posto sicuro devi usare i volumi di docker docker volumes modificando il file docker-compose.yml come segue. Questa procedura permette di avere i database in modo persistente e criptografato ma tale opzione non permette la portabilita tra più devices.

# ...
services:
# ...
  db:
# ...
    volumes:
      # - ./db:/var/lib/mysql
      - database:/var/lib/mysql
# ...

# add after services
volumes:
  database:


  • Se hai già un dump di un database che vuoi importare puoi aggiungere il file di dump .sql o .gz dentro la cartella docker\mariadb\init e rimuovere il commento dalla riga seguente. Il database verrà creato alla prima build.

# ...
services:
# ...
  db:
# ...
    volumes:
      - ./docker/mariadb/init:/docker-entrypoint-initdb.d
# ...


  • Inoltre, se è necessario eseguire altre operazioni sui database alla prima build, è possibile modificare i seguenti file inserendo le query di cui si ha bisogno:

    • docker\mariadb\init\000-operations.sql
    • docker\mariadb\init\zzz-operations.sql

Queste operazioni verranno eseguite esclusivamente alla prima build, ovvero quando il contaner del database verrà inizializzato la prima volta.


  • I log di PHP e Apache possono essere seguiti e visualizzati sul terminale (di default con stdout, stderr) lanciando il comando docker-compose logs -f web. Se invece vuoi averli in un file, modifica il docker-compose.yml aggiungendo questa riga come sotto.

# ...
services:
# ...
  web:
# ...
    volumes:
      - ./logs/web:/var/log/apache2
      # ...
# ...


  • Per abilitare il logs di MySQL modifica il file docker/mysql/Dockerfile togliendo il commento alle seguente riga.
RUN sed -i "s/#log-error/log-error/g" /etc/mysql/mysql.conf.d/mysqld.cnf

  • Quanto lo stack è pronto vai su http://localhost, per vedere il PHPinfo vai in http://localhost/info.php

Comandi utili per Build e Run

Se usi un sistema linux puoi eseguire direttamente il make usando i seguenti comandi:

  • make install – crea e inizializza lo stack
  • make start – avvia lo stack
  • make stop – arresta lo stack
  • make remove – rimuove lo stack mantenendo i databases e i logs, non rimuove i sorgenti della webapp
  • make purge – rimuove completamente lo stack compresi tutti i databases e i logs ma non rimuove i sorgenti della webapp
  • make validate – verifica che le impostazione di ambiente e dello stack siano corrette e non ci siano errori all’interno del file docker-compose.yml
  • make bash-db – entra con il terminale bash all’interno del contaner db
  • make bash-web – entra con il terminale bash all’interno del contaner web

Commandi utili in pillole

Da usare per creazione, avvio, arresto, rimozione e validazione dello stack docker.

  • docker-compose up -d --build – crea e inizializza lo stack

  • docker-compose down – rimuove lo stack mantenendo i databases e i logs, non rimuove i sorgenti della webapp

  • docker-compose start – avvia lo stack

  • docker-compose stop – arresta lo stack

  • docker-compose down --volumes – come down ma rimuove anche i volumi quindi cancella anche i databases

  • docker-compose config verifica che le impostazione di ambiente e dello stack siano corrette e non ci siano errori all’interno del file docker-compose.yml

  • docker-compose exec SERVICE_NAME bash entra con il termianle bash al’interno del container dichiarato


L’intero repository del progetto sopra descritto è disponibile su GitHub sotto il nome di Docker-AMP-Slim

Su GitHub sono disponibili anche altri repository con altri tipi di Stack.

  • Docker-EMP composto da NGINX, MYSQL (MariaDB), PHP (FPM)
  • Docker-AMP composto da APACHE, MYSQL (MariaDB), PHP (FPM)