Maison >développement back-end >tutoriel php >Comment personnaliser une seule image Nginx pour plusieurs conteneurs PHP-FPM

Comment personnaliser une seule image Nginx pour plusieurs conteneurs PHP-FPM

不言
不言original
2018-07-09 09:28:522254parcourir

Cet article présente principalement la méthode de personnalisation d'une seule image Nginx pour plusieurs conteneurs PHP-FPM. Il a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer

Récemment, je le partage. J'ai travaillé sur le déploiement d'un ensemble de microservices PHP à l'aide de conteneurs Docker. L'un des problèmes est que notre application PHP est configurée pour fonctionner avec PHP-FPM et Nginx (plutôt qu'une simple configuration Apache/PHP[1] comme indiqué ici), donc deux conteneurs sont requis par microservice PHP (également équivalent à deux Images Docker) :

  • Conteneur PHP-FPM

  • Conteneur Nginx

En supposant qu'une application s'exécute plus de six microservices PHP, y compris vos environnements de développement et de production, il y aura à terme près de 30 conteneurs. Au lieu de créer une image Nginx unique pour chaque image de microservice PHP-FPM, j'ai décidé de créer une image Docker Nginx distincte et de mapper le nom d'hôte PHP-FPM en tant que variable d'environnement sur un fichier de configuration unique dans cette image.

Comment personnaliser une seule image Nginx pour plusieurs conteneurs PHP-FPM


Dans cet article de blog, je décrirai mon processus de la méthode 1 à la méthode 2 ci-dessus, en terminant par une introduction sur la façon d'utiliser la nouvelle image Docker Nginx personnalisée. . Solution pour terminer ce blog.
J'ai rendu cette image open source sur GitHub [2], donc si cela s'avère être un problème que vous rencontrez souvent, n'hésitez pas à la consulter.

Pourquoi Nginx ?

Comment personnaliser une seule image Nginx pour plusieurs conteneurs PHP-FPM

PHP-FPM et Nginx utilisés ensemble peuvent produire de meilleures performances d'application PHP [3], mais l'inconvénient est que l'image Docker PHP-FPM n'est pas par défaut celle de PHP Apache. image Fourni avec Nginx.
Si vous souhaitez connecter un conteneur Nginx à un backend PHP-FPM, vous devez ajouter les enregistrements DNS de ce backend à votre configuration Nginx.
Par exemple, si le conteneur PHP-FPM s'exécute en tant que conteneur nommé php-fpm-api, alors votre fichier de configuration Nginx devrait lire :

nginx
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # This line passes requests through www.dongfan178.com to the PHP-FPM container
        fastcgi_pass php-fpm-api:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param www.huayi1.cn/ www.dongfan178.com SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param www.00534.cn PATH_INFO $fastcgi_path_info;
    }

Si vous ne servez qu'un seul PHP-FPM containers Application, il est possible de coder en dur le nom correspondant dans le fichier de configuration de votre conteneur Nginx. Cependant, comme je l'ai mentionné ci-dessus, chaque service PHP nécessite un conteneur Nginx correspondant, nous devons donc exécuter plusieurs conteneurs Nginx. Créer une nouvelle image Nginx (que nous devrons maintenir et mettre à niveau plus tard) sera pénible car même gérer un tas de volumes différents semble demander beaucoup de travail pour changer un seul nom de variable.

Première solution : Utiliser la méthode envsubst mentionnée dans la documentation Docker

Comment personnaliser une seule image Nginx pour plusieurs conteneurs PHP-FPM

Au début, je pensais que c'était facile. Il y a un petit chapitre sympa dans la documentation Docker sur la façon d'utiliser envsubst[4], mais malheureusement cela ne fonctionne pas avec mon fichier de configuration Nginx :
vhost.conf

nginx
server {
    listen 80;
    index index.php index.html;
    root /var/www/public;
    client_max_body_size 32M;
    location / {
        try_files $uri /index.php?$args;
    }
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass ${NGINX_HOST}:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

moi Le vhost Le fichier .conf utilise plusieurs variables d'environnement intégrées à Nginx. Par conséquent, lorsque j'exécute la ligne de commande suivante mentionnée dans la documentation Docker, un message d'erreur apparaît : $uri et fastcgi_script_name ne sont pas définis.

shell
/bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g &#39;daemon off;&#39;"

Ces variables sont généralement transmises par Nginx lui-même [5], il n'est donc pas facile de comprendre ce qu'elles sont et comment transmettre les paramètres, et cela affectera la configurabilité dynamique du conteneur

Une autre image Docker qui a presque réussi

Comment personnaliser une seule image Nginx pour plusieurs conteneurs PHP-FPM

Ensuite, j'ai commencé à rechercher différentes images de base Nginx. J'en ai trouvé deux, mais tous deux n'ont pas été mis à jour depuis deux ans. J'ai commencé avec martin/nginx[6] et j'ai essayé de voir si je pouvais obtenir un prototype fonctionnel.
L’image de Martin est un peu différente car elle nécessite une structure de répertoires de fichiers spécifique. J'ai d'abord ajouté au Dockerfile :

FROM martin/nginx

Ensuite, j'ai ajouté le répertoire app/vide et le répertoire conf/ contenant uniquement un fichier vhost.conf.
vhost.conf

nginx
server {
    listen 80;
    index index.php index.html;
    root /var/www/public;
    client_max_body_size 32M;
    location / {
        try_files $uri /index.php?$args;
    }
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass $ENV{"NGINX_HOST"}:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Ceci est similaire à mon fichier de configuration d'origine, avec une seule ligne modifiée : fastcgi_pass $ENV{"NGINX_HOST"}:9000;. Désormais, lorsque je souhaite démarrer un conteneur Nginx et un conteneur PHP appelé php-fpm-api, je peux d'abord compiler une nouvelle image puis lui transmettre la variable d'environnement correspondante lors de son exécution :

shell
docker build -t shiphp/nginx-env:test .
docker run -it --rm -e NGINX_HOST=php-fpm-api shiphp/nginx-env:test

Succès ! Cependant, il y a deux problèmes qui me dérangent avec cette méthode :

  1. La version de l'image de base est ancienne et n'a pas été mise à jour depuis plus de deux ans. Cela peut créer des risques en matière de sécurité et de performances.

  2. Exiger un répertoire vide pour l'application semble inutile, de plus mes fichiers sont dans des répertoires différents.

Solution finale

Comment personnaliser une seule image Nginx pour plusieurs conteneurs PHP-FPM

Je pense que le miroir de Martin est un bon choix pour une solution personnalisée. J'ai donc créé son référentiel et construit une nouvelle image de base Nginx qui a résolu les deux problèmes ci-dessus. Maintenant, si vous souhaitez exécuter une application backend nommée dynamiquement avec un conteneur nginx, faites simplement ceci :

shell
# Pull down the latest from Docker Hub
docker pull shiphp/nginx-env:latest
# Run a PHP container named "php-fpm-api"
docker run --name php-fpm-api -v $(pwd):/var/www php:fpm
# Start this NGinx container linked to the PHP-FPM container
docker run --link php-fpm-api -e NGINX_HOST=php-fpm-api shiphp/nginx-env

如果你想自定义这个镜像,添加你自己的文件或者Nginx配置文件,只需要像下面这样扩展你的Dockerfile:

FROM shiphp/nginx-env
ONBUILD ADD <PATH_TO_YOUR_CONFIGS> /etc/nginx/conf.d/

现在我所有的PHP-FPM容器都使用单个Nginx镜像的实例,当我需要升级Nginx、修改权限或者配置一些东西的时候,这让我的生活变得简单多了。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

PHP缓存区ob的介绍

如何配置php客户端(phpredis)并连接Redis

使用PHPstudy在Windows服务器下部署PHP系统

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn