Aller au contenu

Docker pour ma stack LAMP - Guillaume Kulakowski's blog


Ldfa

Messages recommandés

business-cargo-cargo-container-900x481.j

J’avais déjà décrit ma précédente stack LAMP sous Docker, mais, à nouveau serveur, nouvelle architecture !

Tout d’abord posons le décor : un serveur Scaleway VC1M avec dessus, ce blog WordPress et un GitLab (que je ne décrirais pas). On s’attend donc à une stack avec un serveur HTTP, un daemon PHP-FPM et une base de données.

Pour illustrer le tout rien ne vaut un schéma (on commence par la version simplifiée) :

Schéma d'architecture Docker simplifiéSchéma d’architecture simplifié de la stack LAMP sous Docker.

Pour ce qui est de docker, je suis parti de la version officiellement disponible dans CentOS 7 avec comme système de stockage aufs.

docker info
Containers: 6
 Running: 6
 Paused: 0
 Stopped: 0
Images: 76
Server Version: 1.13.1
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 83
 Dirperm1 Supported: true
[..]
Kernel Version: 4.4.114-mainline-rev1
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 3
CPUs: 4
Total Memory: 3.857 GiB
[...]

2 services (HTTPd & PHP-FPM) donc 2 containers

Pour faire un serveur HTTP/PHP, certains font un gros container contenant les 2 services. Personnellement, je préfère respecter la bonne pratique qui consiste à avoir 1 container pour 1 service. Comme d’habitude, j’ai fait le choix de ne pas mettre WordPress dans le container PHP + le container HTTPd. C’est une solution de facilité mais qui s’explique :

  • Pas besoin de mettre à jour 2 containers pour mettre à jour WordPress.
  • Possibilité de mettre à jour WordPress depuis Deployer.
  • Plus simple.

Du coup j’ai un volume partagé entre les 2 containers et que je peux trifouiller depuis mon serveur.

Serveur HTTP

Pour le serveur HTTP, et bien que je maitrise également nginx, je reste fidèle à Apache. De mon point de vue, il n’y a rien de plus puissant et une fois configuré on a quelque chose de tout aussi performant (je sens que je viens de lâcher un gros Troll…).

En ce qui concerne le container Docker, je dérive de la dernière version officielle disponible sur le store, mais en version Alpine, c’est plus léger et plus joueur que la version Debian.

À ceci j’embarque quelques optimisations telles que :

Sources de mon images Apache HTTP disponibles sur GitHub.

Serveur PHP-FPM

Là encore, je pars de la version officielle du store mais sous Alpine. Mon image a de particulier que lorsqu’on la build via docker-compose, on peut lui passer des paramètres. Ça me permet d’avoir la même image en dev et en prod mais avec XDebug seulement sur la prod.

  php:
    container_name: php
    image: llaumgui/php:7.2-fpm
    build:
      context: build/php-fpm/7.2/
      args:
        DOCKER_PHP_ENABLE_APCU: 'on'
        DOCKER_PHP_ENABLE_COMPOSER: 'on'
        DOCKER_PHP_ENABLE_LDAP: 'off'
        DOCKER_PHP_ENABLE_MEMCACHED: 'off'
        DOCKER_PHP_ENABLE_MONGODB: 'off'
        DOCKER_PHP_ENABLE_MYSQL: 'on'
        DOCKER_PHP_ENABLE_POSTGRESQL: 'off'
        DOCKER_PHP_ENABLE_REDIS: 'on'
        DOCKER_PHP_ENABLE_SYMFONY: 'off'
        DOCKER_PHP_ENABLE_XDEBUG: 'off'
	DOCKER_USER_UID: 1000
	DOCKER_USER_GID:1000
[..]

À noter que lorsque je déploie mon application, j’ai besoin de lancer des tâches PHP. Or, je n’ai pas PHP sur mon serveur mais dans mon container. Pour ceci j’utilise un simple script shell qui va vérifier que je suis bien dans le bon répertoire et lancer php-cli via le container. Pour éviter des problèmes de droits, le php-cli s’exécute sous un ID identique à mon utilisateur de déploiement (passé en paramètre dans mon docker-compose).

#!/bin/bash

PHP_PATH=/var/www
[[ ! "$PWD" =~ ${PHP_PATH} ]] && echo "Les commandes php ne sont utilisables que sous ${PHP_PATH}" && exit 1 

CONTAINER_NAME="php"
COMMAND="php $@"
PWD=$(pwd)

docker exec -u user -i ${CONTAINER_NAME} /bin/sh -c "cd ${PWD} && ${COMMAND}"

Côté réseau, le port 9000 est accessible à partir du serveur uniquement pour des purges de l’OPCode, pour ceci j’utilise Deployer qui se base sur cachetool.

Sources de mon image PHP-FPM disponibles sur GitHub.

Base de données

Pour la base de données, je suis resté simple : MariaDB 10.1 via l’image officielle.

En effet depuis qu’Oracle a racheté Sun et donc MySQL, je suis passé sous le fork officiel de l’équipe historique et supporté par la MariaDB Fondation. Là encore le serveur peut accéder au container via le port standard de MySQL et pour ceci je passe par le client mycli plus moderne que le client historique.

Les petits trucs en plus

Un serveur Redis

Pour améliorer les performances de WordPress, je mets le cache de WordPress en RAM. Pour ceci j’utilise Redis via l’image officielle. Du coup PHP peut accéder à Redis sur le port standard.

Un GitLab

Comme expliqué en préambule j’ai un GitLab perso. J’utilise l’image docker officielle qui, vu le nombre de services embarqués dans 1 même container est tout sauf respectueuse des guidelines. Pour rappel et comme évoqué précédemment c’est à cause de GitLab que je ne suis pas sur un serveur CV1S.

Et pour administrer Docker ?

Pour administrer tout ceci, je fais dans le simple, docker et docker-compose en ligne de commande, mais également ctop qui est un très bon TUI.

ctop en action

L’envoi d’email

J’ai fait le choix de ne pas avoir de container pour l’envoi des mails. En effet, que ce soit mon serveur ou mes containers, tout ce petit monde à besoin d’envoyer des mails. Du coup j’ai un postfix directement installé sur le serveur. Il est configuré pour permettre à Docker d’envoyer des mails et j’ai également une règle firewalld pour ouvrir le serveur SMTP au réseau docker :

firewall-cmd --permanent --zone=public --add-rich-rule='
  rule family="ipv4"
  source address="172.18.0.0/16"
  port protocol="tcp" port="25" accept'

Ensuite, j’ai mis un alias DNS vers mon serveur mail dans mes containers (vous pourrez le voir dans le paragraphe suivant).

Le fichier docker-compose.yml

Au final, l’architecture est la suivante :

Schéma d'architecture DockerSchéma d’architecture complet de la stack LAMP sous Docker.

Et toute cette architecture est portée par une seule configuration, le docker-compose.yml qui permet d’orchestrer une architecture multi-containers. C’est Compose qui va gérer les volumes, le réseau Docker et les échanges entre les différents containers.

version: '2.1'

################################################################### All services
services:
  httpd:
    container_name: httpd
    image: llaumgui/httpd24
    build:
      context: build/httpd/2.4/
    restart: always
    volumes:
     - /etc/localtime:/etc/localtime:ro
     - /docker/volumes/www:/var/www/
     - /docker/conf/httpd/vhost.d:/usr/local/apache2/conf/vhost.d:ro
     - /docker/conf/httpd/ssl:/usr/local/apache2/ssl:ro
    ports:
     - "80:80"
     - "443:443"

  php:
    container_name: php
    image: llaumgui/php:7.2-fpm
    build:
      context: build/php-fpm/7.2/
      args:
        DOCKER_PHP_ENABLE_APCU: 'on'
        DOCKER_PHP_ENABLE_COMPOSER: 'on'
        DOCKER_PHP_ENABLE_LDAP: 'off'
        DOCKER_PHP_ENABLE_MEMCACHED: 'off'
        DOCKER_PHP_ENABLE_MONGODB: 'off'
        DOCKER_PHP_ENABLE_MYSQL: 'on'
        DOCKER_PHP_ENABLE_POSTGRESQL: 'off'
        DOCKER_PHP_ENABLE_REDIS: 'on'
        DOCKER_PHP_ENABLE_SYMFONY: 'off'
        DOCKER_PHP_ENABLE_XDEBUG: 'off'
        DOCKER_USER_UID: 1001
        DOCKER_USER_GID: 1001
    restart: always
    volumes:
     - /etc/localtime:/etc/localtime:ro
     - /docker/volumes/www:/var/www/
    expose:
     - 9000
    ports:
     - "127.0.0.1:9000:9000"
    depends_on:
     - httpd
     - mariadb
     - redis
    links:
     - mariadb:database
    extra_hosts:
     - "mailserver:172.18.0.1"

  mariadb:
    container_name: mariadb
    image: mariadb:10.1
    restart: always
    env_file:
     - /docker/conf/mariadb.env
    volumes:
     - /etc/localtime:/etc/localtime:ro
     - /docker/volumes/mariadb:/var/lib/mysql
     - /docker/volumes/mysqldump:/mysqldump
    expose:
     - 3306
    ports:
     - "127.0.0.1:3306:3306"

  redis:
    container_name: redis
    image: redis:4-alpine
    restart: always
    volumes:
     - /etc/localtime:/etc/localtime:ro
    expose:
     - 6379

Afficher l’article complet

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.