Docker pour Symfony 4 - du LAN à la production

Préhistoire


Un beau jour, j'ai eu besoin de déployer un environnement de développement pour mon projet. Vagrant en avait déjà assez et voulait avoir un environnement de développement unique pour tous les participants au projet qui serait identique au serveur de production. En conséquence, après avoir écouté des informations sur le docker hipster, j'ai décidé de commencer à y faire face. Ensuite, j'essaierai de décrire le plus en détail possible toutes les étapes de l'installation d'un docker sur un LAN jusqu'au déploiement d'un produit sur KVM.

Pile de technologie d'origine:

- docker
- symfony 4
- nginx
- php-fpm
- postgresql
- elasticsearch
- rabbitmq
- jenkins

Fer:

- ordinateur portable sous OS Ubuntu 16.04
- serveur de production sur hébergement KVM

Pourquoi, en plus de la pile technologique, j'ai également répertorié la pile de fer?

Si vous n'avez jamais travaillé avec un docker, vous pouvez rencontrer un certain nombre de problèmes liés spécifiquement au matériel, au système d'exploitation de votre ordinateur portable ou au type de virtualisation d'hébergement.

Le premier et probablement le plus important aspect lorsque vous commencez à travailler avec le docker est le système d'exploitation de votre ordinateur portable. La façon la plus simple de travailler avec Docker est sur les systèmes Linux. Si vous travaillez sur Windows ou Mac, vous aurez 100% de difficultés, mais ces difficultés ne seront pas critiques et si vous voulez "google" comment cela est résolu, il n'y aura pas de problèmes.

La deuxième question est l'hébergement. Pourquoi l'hébergement est-il nécessaire avec le type de virtualisation KVM? La raison en est que la virtualisation VPS est très différente de KVM et que vous ne pourrez tout simplement pas installer Docker sur VPS, car VPS alloue dynamiquement les ressources du serveur.

Sous-total: pour le démarrage le plus rapide du docker, il est plus raisonnable de choisir Ubuntu en tant qu'OS local et hébergement KVM (ou votre propre serveur). De plus, l'histoire s'appuiera précisément sur ces deux éléments.

Docker-compose pour LAN


L'installation


Vous devez d'abord installer le docker lui-même localement. Vous pouvez voir les instructions d'installation sur le lien du site officiel vers la documentation officielle d'ubuntu (vous devez installer docker et docker-compose), ou en exécutant la commande dans la console:

curl -sSl https://get.docker.com/ | sh 

Cette commande installera à la fois docker et docker-compose. Après cela, vérifiez la version du docker avec la commande:

 docker --version 

Je commence tout ça sur la version docker 18.06.0-ce.

L'installation est terminée!

Sensibilisation


Pour travailler avec quelque chose de moins efficace, vous devez avoir une idée de son fonctionnement. Si vous ne travailliez auparavant qu'avec Vagrant ou quelque chose de similaire, cela sera extrêmement inhabituel et incompréhensible au début, mais ce n'est qu'au début.

Je vais essayer de faire une analogie pour Vagrant. Maintenant, beaucoup peuvent dire que comparer Vagrant et Docker est fondamentalement faux. Oui, je suis d'accord avec cela, mais je ne vais pas les comparer, je vais juste essayer de transmettre aux nouveaux arrivants qui ne travaillent qu'avec le système de travail Vagrant the Docker, en faisant appel à ce que les nouveaux arrivants savent.

Ma vision du conteneur «sur les doigts» est la suivante: chaque conteneur est un petit monde isolé. Chaque conteneur peut être imaginé comme s'il s'agissait d'un minuscule Vagrant sur lequel un seul outil est installé, par exemple nginx ou php. Initialement, les conteneurs sont généralement isolés de tout ce qui l'entoure, mais par des manipulations délicates, vous pouvez tout configurer pour qu'ils communiquent entre eux et fonctionnent ensemble. Cela ne signifie pas que chacun des conteneurs est une machine virtuelle distincte, pas du tout. Mais c'est plus facile pour la compréhension initiale, comme il me semble.

Vagrant mord simplement une partie des ressources de votre ordinateur, crée une machine virtuelle, y installe un système d'exploitation, installe des bibliothèques, installe tout ce que vous avez écrit dans le script après avoir vagabondé. En fin de compte, cela ressemble à ceci:

Voir le schéma

Docker, à son tour, fonctionne radicalement différent. Il ne crée pas de machines virtuelles. Docker crée des conteneurs (pour l'instant, vous pouvez les considérer comme des machines micro-virtuelles) avec son système d'exploitation Alpine et 1 à 3 bibliothèques nécessaires au fonctionnement de l'application, par exemple php ou nginx. Dans le même temps, Docker ne bloque pas les ressources de votre système pour lui-même, mais les utilise simplement si nécessaire. En fin de compte, pour illustrer, cela ressemblera à quelque chose comme ceci:

Voir le schéma

Chacun des conteneurs a une image à partir de laquelle il est créé. La grande majorité des images est une extension d'une autre image, par exemple Ubuntu xenial ou Alpine ou Debian, sur laquelle des pilotes supplémentaires et d'autres composants sont roulés sur le dessus.

Ma première image était pour php-fpm. Mon image étend l'image php officielle: 7.2-fpm-alpine3.6. Autrement dit, il prend l'image officielle et fournit les composants dont j'ai besoin, par exemple, pdo_pgsql, imagick, zip, etc. Ainsi, vous pouvez créer l'image dont vous avez besoin. Si vous le souhaitez, vous pouvez l'utiliser ici .

Avec la création d'images, tout est assez simple à mon avis si elles sont faites à base de xénial par exemple, mais elles délivrent un peu d'hémorroïdes si elles sont faites à base d'alpine. Avant de commencer à travailler avec le docker, je n'ai pas entendu parler d'Alpine, car Vagrant a toujours travaillé pour moi sous Ubuntu xenial. Alpine est un système d'exploitation Linux vide, dans lequel il n'y a pratiquement rien du tout (minimum extrême). Par conséquent, au début, il est extrêmement gênant de travailler avec, car il y a par exemple la même installation apt-get (à laquelle vous êtes habitué), mais il n'y a que apk add et un ensemble de packages pas tout à fait sain d'esprit. Un gros plus d'Alpine est son poids, par exemple, si Xenial pèse (abstraitement) 500 sacs, alors Alpine (abstraitement) est d'environ 78 sacs. Qu'est-ce que cela affecte même? Et cela affecte la vitesse de construction et le poids final de toutes les images qui seront finalement stockées sur votre serveur. Disons que vous avez 5 conteneurs différents et que tout basé sur le xénial, leur poids total sera supérieur à 2,5 concerts et alpin - environ 500 sacs seulement. Par conséquent, idéalement, nous devons nous efforcer de veiller à ce que les conteneurs soient aussi minces que possible. (Lien utile pour installer des packages dans Alpine - Packages Alpine ).

Partout sur le hub docker, ils écrivent comment lancer le conteneur à l'aide de la docker run , et pour une raison quelconque, ils n'écrivent pas comment il peut être lancé via docker-compose, et c'est via docker-compose qu'il démarrera la plupart du temps, car il y a très peu de chasse démarrer manuellement tous les conteneurs, réseaux, ports ouverts et plus encore. Docker-compose au nom de l'utilisateur ressemble à un fichier yaml avec des paramètres. Il comprend une description de chacun des services qui doivent être démarrés. Ma construction pour l'environnement local est la suivante:

 version: '3.1' services: php-fpm: image: otezvikentiy/php7.2-fpm:0.0.11 ports: - '9000:9000' volumes: - ../:/app working_dir: /app container_name: 'php-fpm' nginx: image: nginx:1.15.0 container_name: 'nginx' working_dir: /app ports: - '7777:80' volumes: - ../:/app - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf postgres: image: postgres:9.6 ports: - '5432:5432' container_name: 'postgresql' working_dir: /app restart: always environment: POSTGRES_DB: 'db_name' POSTGRES_USER: 'db_user' POSTGRES_PASSWORD: 'db_pass' volumes: - ./data/dump:/app/dump - ./data/postgresql:/var/lib/postgresql/data rabbitmq: image: rabbitmq:3.7.5-management working_dir: /app hostname: rabbit-mq container_name: 'rabbit-mq' ports: - '15672:15672' - '5672:5672' environment: RABBITMQ_DEFAULT_USER: user RABBITMQ_DEFAULT_PASS: password RABBITMQ_DEFAULT_VHOST: my_vhost elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:6.3.0 container_name: 'elastic-search' environment: - discovery.type=single-node - "discovery.zen.ping.unicast.hosts=elasticsearch" - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ports: - 9200:9200 - 9300:9300 working_dir: /app volumes: - ../:/app - ./data/elasticsearch:/usr/share/elasticsearch/data volumes: elasticsearch: postgresql: 

docker-compose.yaml pour SF4 est un certain ensemble de services: nginx, php-fpm, postgresql, rabbitmq (si vous en avez besoin), elasticsearch (si vous en avez besoin). Pour l'environnement local, cela suffit. Pour que tout fonctionne, il existe un ensemble minimal de paramètres sans lesquels rien ne fonctionnera. Il s'agit le plus souvent d'images, de volumes, de ports, d'environnement, de rép_travail et de nom_conteneur. Tout pour lancer telle ou telle image est décrit dans sa documentation sur hub.docker.com . Il n'y a pas toujours de description pour docker-compose, mais cela ne signifie pas qu'il ne fonctionne pas avec. Il est juste nécessaire de transférer toutes les données entrantes de la commande docker run vers docker-compose et tout fonctionnera.

Par exemple, il y a une image pour RabbitMQ ici . Lorsque vous voyez cela pour la première fois, cela provoque des sentiments et des émotions mitigés, mais tout n'est pas si effrayant. Les balises sont indiquées dans cette image. Généralement, les balises - représentent différentes images, différentes versions de l'application avec différentes images extensibles. Par exemple, la balise 3.7.7-alpine signifie que cette image est plus mince que, par exemple, 3.7.7, car elle est basée sur Alpine. Eh bien et aussi dans les balises le plus souvent, les versions de l'application sont indiquées. Je choisis généralement la dernière version et la version stable de l'application elle-même et de l'image alpine.

Après avoir étudié et sélectionné une balise, vous voyez souvent quelque chose de ce genre:

 docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password rabbitmq:3-management 

Et la première pensée est WTF? Comment transférer cela vers docker-compose?

Tout est assez simple. En fait, cette ligne indique tous les mêmes paramètres que dans le fichier yaml, uniquement abrégés. Par exemple, -e est un environnement dans lequel divers paramètres sont passés, il peut également y avoir des entrées comme -p - ce sont des ports appelés ports dans yaml. En conséquence, afin d'utiliser une image inconnue de manière qualitative, il vous suffit de "google" les abréviations de docker run et d'appliquer les noms complets dans le fichier yaml.

Revenons maintenant à docker-compose.yml, que j'ai cité comme exemple ci-dessus.

Cet exemple utilise mon image php7.2 faite comme une extension pour l'image officielle php7.2-fpm-alpine, mais si vous n'avez pas besoin d'autant de bibliothèques supplémentaires, vous pouvez créer votre extension pour l'image officielle et l'utiliser. Les autres images pour LAN sont complètement originales et officielles.

image - indiquez l'image à télécharger. Par exemple (rabbitmq: 3.7.7-management-alpine).

ports - spécifiez les ports que le conteneur utilisera (voir la documentation de l'image). Par exemple, le port nginx est 80. Par conséquent, si vous souhaitez utiliser le port 80, vous devez spécifier 80:80 ici et votre site sera disponible sur localhost. Ou vous pouvez spécifier 7777: 80, puis votre site sera à l'URL localhost: 7777. Cela est nécessaire pour que plusieurs projets puissent être déployés sur le même hôte.

volumes - les répertoires partagés sont indiqués ici. Par exemple, votre projet se trouve dans le répertoire ~ / projects / my-sf4-app, et le conteneur php est configuré pour fonctionner avec le répertoire / app (le même que dans / var / www / my-sf4-app). En conséquence, il serait pratique que le conteneur ait accès au projet. En conséquence, dans les volumes, nous écrivons ~/projects/my-sf4-app:/app (voir cet exemple dans docker-compose.yml ci-dessus (je l'ai indiqué de manière relative ../:/app)).

Ainsi, le dossier sera partagé pour le conteneur et il pourra y effectuer diverses actions comme php bin/console doctrine:migrations:migrate . Il est également pratique d'utiliser ces répertoires pour enregistrer les données d'application. Par exemple, postgresql, vous pouvez spécifier un répertoire pour stocker les données de la base de données, puis lorsque vous recréez le conteneur, vous n'aurez pas besoin de faire un vidage ou des appareils.

working_dir - indique le répertoire de travail du conteneur. Dans ce cas, / app (ou par analogie avec le vagrant / var / www / my-sf4-app).

environnement - toutes les variables du conteneur sont passées ici. Par exemple, pour rabbitmq, le nom d'utilisateur et le mot de passe sont transmis, pour postgresql, le nom de base, le nom d'utilisateur et le mot de passe sont transmis.

nom_conteneur est un champ facultatif, mais je préfère spécifier, pour la commodité de la connexion aux conteneurs. S'il n'est pas spécifié, des noms par défaut avec des hachages seront attribués.

Ce sont les principaux paramètres qui doivent être spécifiés. Le reste peut être facultatif pour des paramètres supplémentaires, ou selon la documentation du conteneur.

Maintenant, pour démarrer tout cela, vous devez exécuter la commande docker-compose up -d dans le répertoire où se trouve le fichier docker-compose.

Comment et où stocker tout cela pour le LAN?


Pour le LAN, j'utilise le dossier docker à la racine du projet.


Il contient le dossier de données dans lequel je stocke toutes les informations postgresql et elasticsearch, de sorte que lorsque vous recréez le projet, vous n'avez pas à faire rouler les appareils à partir de zéro. Il y a aussi un papa nginx dans lequel je stocke la configuration du conteneur nginx local. Je synchronise ces dossiers dans docker-compose.yml avec les fichiers et dossiers correspondants dans les conteneurs. De plus, à mon avis, il est très pratique d'écrire des scripts bash pour travailler avec docker. Par exemple, le script start.sh lance les conteneurs, puis le compositeur installe, nettoie le cache et migre. C'est aussi pratique pour les collègues du projet, ils n'ont rien à faire, ils exécutent simplement le script et tout fonctionne.

Exemple de script Start.sh

 #!/usr/bin/env bash green=$(tput setf 2) toend=$(tput hpa $(tput cols))$(tput cub 6) echo -n '   ?: ' read name echo "  $name!       tutmesto.ru" echo -n "$name,      ? (y/n): " read use_dump echo '    !' docker-compose up -d || exit echo -en '\n' echo -n "  ! ${green}${toend}[OK]" echo -en '\n' echo '    .' ./composer-install.sh echo -en '\n' echo -n "   ${green}${toend}[OK]" echo -en '\n' echo '     40 ,    postgres-' sleep 5 echo '  35 ...' sleep 5 echo '  30 ...' sleep 5 echo '  25 ...' sleep 5 echo '  20 ...' sleep 5 echo '  15 ...' sleep 5 echo '  10 ...' sleep 5 echo '  5 ...' sleep 5 echo ' .   postgres-        !' case "$use_dump" in y|Y) ./dump.sh echo -en '\n' echo -n "  ! ${green}${toend}[OK]" echo -en '\n' ;; *) echo "$name, ,   ! =)" ;; esac echo '    !' ./migrations-migrate.sh echo -en '\n' echo -n "  ! ${green}${toend}[OK]" echo -en '\n' echo '  !' ./php-fpm-command.sh rm -rf var/cache/* ./php-fpm-command.sh chmod 777 var/ -R ./cache-clear.sh echo -en '\n' echo -n "  ! ${green}${toend}[OK]" echo -en '\n' echo '    !' ./env.sh echo -en '\n' echo -n "   ! ${green}${toend}[OK]" echo -en '\n' echo ", $name,    !    localhost:7777  !" echo -en '\n' echo "------------------------------------------------------------------------------" echo -en '\n' echo "    :" echo "./cache-clear.sh |  symfony 4" echo "./composer.sh [command(ex. install)] |  " echo "./composer-install.sh | composer install" echo "./connect-to-php-fpm.sh |   php" echo "./console.sh [command(ex. cache:clear)] |  php bin/console" echo "./destroy.sh |  .    ." echo "./dump.sh | ,     (dump.sql)" echo "./env.sh |   " echo "./migrations-migrate.sh | " echo "./php-fpm-command.sh [command(ex. php -m)] |   php-fpm " echo "./start.sh |  ( )" echo "./stop.sh |Gracefull shutdown " echo -en '\n' echo "        :" echo "client@c.cc | QWEasd123" echo "admin@a.aa | QWEasd123" echo "moderator@m.mm | QWEasd123" echo -en '\n' echo "------------------------------------------------------------------------------" echo -en '\n' echo -en '\n' echo 'OtezVikentiy brain corporation!' echo -en '\n' echo -en '\n' 

Exemple de script Php-fpm-command.sh

 #!/usr/bin/env bash cd "`dirname \"$0\"`" && \ docker-compose exec -T "php-fpm" sh -c "cd /app && $*" 

Exemple de script connect-to-php-fpm.sh

 #!/usr/bin/env bash docker exec -i -t --privileged php-fpm bash 

L'environnement de développement local s'arrête ici. Félicitations, vous pouvez partager le résultat final avec vos collègues! )

Productif


La préparation


Supposons que vous ayez déjà écrit quelque chose sur un LAN et que vous souhaitiez le mettre sur un serveur de production ou sur un serveur de test. Vous avez l'hébergement sur virtualisation KVM ou votre serveur dans la pièce voisine avec climatisation.

Pour déployer un produit ou une version bêta - le serveur doit avoir un système d'exploitation (idéalement linux) et un docker installé. Docker peut être installé de la même manière que sur LAN, il n'y a aucune différence.

Docker en termes de productivité est légèrement différent du LAN. Premièrement, vous ne pouvez pas simplement prendre et spécifier des mots de passe et d'autres informations et composer-docker. Deuxièmement, vous ne pouvez pas utiliser directement Docker-compose.

Docker utilise l'essaim de docker et la pile de docker pour la productivité. S'il est juste sur les doigts, alors ce système ne diffère que par d'autres commandes et en ce que l'essaim docker est un équilibreur de charge pour le cluster (encore un peu abstrait, mais il sera plus facile à comprendre).

PS: Je vous conseille de vous entraîner à mettre en place un essaim de docker sur Vagrant (aussi paradoxal que cela puisse paraître). Une recette simple pour la formation - prenez un Vagrant vide avec le même système d'exploitation que dans le produit et configurez-le pour démarrer.

Pour configurer l'essaim de docker, il vous suffit d'exécuter quelques commandes:

 docker swarm init --advertise-addr 192.168.***.** (ip-  ) mkdir /app (          app) chown docker /app (     ) docker stack deploy -c docker-compose.yml my-first-sf4-docker-app 

Nous considérons maintenant tout cela un peu plus en détail.

docker swarm init --advertise-addr - il lance directement docker swarm et tâtonne un lien afin que vous puissiez connecter un autre serveur à cet "essaim" afin qu'ils fonctionnent dans le cluster.
mkdir / app && chown .. - vous devez créer tous les répertoires nécessaires pour que le docker fonctionne à l'avance afin que pendant la construction, il ne se plaigne pas du manque de répertoires.
docker stack deploy -c docker-compose.yml my-first-sf4-docker-app - cette commande démarre l'assemblage de votre application elle-même, un analogue de docker-compose up -d uniquement pour l'essaim de dockers.

Pour démarrer un assemblage, vous avez besoin du même docker-compose.yaml, mais il est déjà légèrement modifié spécifiquement pour productif / beta.

 version: '3.1' services: php-fpm: image: otezvikentiy/php7.2-fpm:0.0.11 ports: - '9000:9000' networks: - my-test-network depends_on: - postgres - rabbitmq volumes: - /app:/app working_dir: /app deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [node.role == manager] nginx: image: nginx:1.15.0 networks: - my-test-network working_dir: /app ports: - '80:80' depends_on: - php-fpm volumes: - /app:/app - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [node.role == manager] postgres: image: postgres:9.6 ports: - '5432:5432' working_dir: /app networks: - my-test-network secrets: - postgres_db - postgres_user - postgres_pass environment: POSTGRES_DB_FILE: /run/secrets/postgres_db POSTGRES_USER_FILE: /run/secrets/postgres_user POSTGRES_PASSWORD_FILE: /run/secrets/postgres_pass volumes: - ./data/dump:/app/dump - ./data/postgresql:/var/lib/postgresql/data deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [node.role == manager] rabbitmq: image: rabbitmq:3.7.5-management networks: - my-test-network working_dir: /app hostname: my-test-sf4-app-rabbit-mq volumes: - /app:/app ports: - '5672:5672' - '15672:15672' secrets: - rabbitmq_default_user - rabbitmq_default_pass - rabbitmq_default_vhost environment: RABBITMQ_DEFAULT_USER_FILE: /run/secrets/rabbitmq_default_user RABBITMQ_DEFAULT_PASS_FILE: /run/secrets/rabbitmq_default_pass RABBITMQ_DEFAULT_VHOST_FILE: /run/secrets/rabbitmq_default_vhost deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [node.role == manager] elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:6.3.0 networks: - my-test-network depends_on: - postgres environment: - discovery.type=single-node - discovery.zen.ping.unicast.hosts=elasticsearch - bootstrap.memory_lock=true - ES_JAVA_OPTS=-Xms512m -Xmx512m ports: - 9200:9200 - 9300:9300 working_dir: /app volumes: - /app:/app - ./data/elasticsearch:/usr/share/elasticsearch/data deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [node.role == manager] jenkins: image: otezvikentiy/jenkins:0.0.2 networks: - my-test-network ports: - '8080:8080' - '50000:50000' volumes: - /app:/app - ./data/jenkins:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [node.role == manager] volumes: elasticsearch: postgresql: jenkins: networks: my-test-network: secrets: rabbitmq_default_user: file: ./secrets/rabbitmq_default_user rabbitmq_default_pass: file: ./secrets/rabbitmq_default_pass rabbitmq_default_vhost: file: ./secrets/rabbitmq_default_vhost postgres_db: file: ./secrets/postgres_db postgres_user: file: ./secrets/postgres_user postgres_pass: file: ./secrets/postgres_pass 

Comme vous pouvez le voir, le fichier de paramètres du produit est légèrement différent du fichier LAN. Il a ajouté des secrets, déployer et réseaux.

secrets - fichiers pour stocker les clés. Les clés sont créées tout simplement. Vous créez un fichier avec le nom de la clé - écrivez la valeur à l'intérieur. Après cela, dans docker-compose.yml, vous spécifiez la section secrets et transférez la liste complète des fichiers avec les clés. Plus de détails .
réseaux - cela crée une certaine grille interne à travers laquelle les conteneurs communiquent entre eux. Sur LAN - cela se fait automatiquement, mais sur le productif - cela doit être fait un peu manuellement. De plus, vous pouvez spécifier des paramètres supplémentaires, à l'exception de ceux par défaut. Plus de détails .
le déploiement est la principale différence entre le LAN et le produit / bêta.

  deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [node.role == manager] 

Ensemble de chasse minimum:

répliques - indiquez le nombre de répliques que vous devez exécuter (en fait, cela est utilisé si vous avez un cluster et que vous utilisez l'équilibreur de charge du docker). Par exemple, vous avez deux serveurs et vous les avez connectés via swarm docker. En spécifiant le numéro 2 ici, par exemple, 1 instance sera créée sur 1 serveur et la seconde sur le deuxième serveur. Ainsi, la charge sur le serveur sera divisée en deux.
restart_policy - la politique de «ré-élévation» automatique du conteneur au cas où il tomberait pour une raison quelconque.
placement - l'emplacement de l'instance de conteneur. Par exemple, il arrive que vous souhaitiez que toutes les instances d'un conteneur tournent sur 1 seul des 5 serveurs et ne soient pas réparties entre eux.

Je veux lire la documentation!

Nous avons donc un peu mieux compris ce qui distingue docker-compose.yaml pour LAN de la version produit / bêta. Essayons maintenant de gérer cette entreprise.

Supposons que vous vous entraînez sur Vagrant et qu'à la racine du serveur vous disposez déjà du fichier configuré pour le produit docker-compose.yml

 sudo apt-get update sudo apt-get -y upgrade sudo apt-get install -y language-pack-en-base export LC_ALL=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LANG=en_US.UTF-8 curl -sSl https://get.docker.com/ | sh sudo usermod -aG docker ubuntu sudo apt-get install git sudo docker swarm init --advertise-addr 192.168.128.77 sudo mkdir /app sudo chmod 777 /app -R docker stack deploy -c /docker-compose.yml my-app git clone git@bitbucket.org:JohnDoe/my-app.git /app docker stack ps my-app docker stack ls docker stack services my-app 

PS: ne lancez pas pour sudo et 777, bien sûr, cela ne vaut pas la peine de le faire sur le productif. C'est juste pour apprendre la vitesse.

Donc, nous sommes plus intéressés par les lignes associées au docker.
D'abord, nous initialisons le «swarm» (docker swarm).
Ensuite, nous créons les répertoires nécessaires au travail.
Téléchargez le navet avec notre code SF4 dans le répertoire / app.
Après cela, il y a trois commandes: ps, ls et services.

Chacun d'eux est utile à sa manière. J'utilise ps le plus souvent, car il affiche l'état des conteneurs et une partie de l'erreur, le cas échéant.

Disons que les conteneurs ont augmenté, mais certains d'entre eux se bloquent constamment avec une erreur et dans docker stack ps my-app, vous voyez un tas de redémarrages. Pour voir la raison de la chute, vous devez exécuter le docker container ps -a - et là un conteneur apparaîtra qui tombe constamment. Il y aura de nombreuses instances du même conteneur, par exemple my-app_php-fpm.1. * Un hachage féroce *.

En conséquence, maintenant, connaissant le nom du conteneur, exécutez les journaux docker my-app_php-fpm.1. * Un hachage féroce * et parcourez les journaux. Corrigez l'erreur et redémarrez TOUT. Pour frapper tous les conteneurs, vous pouvez procéder comme suit:

 docker stack rm my-app 

Après cela, vous aurez un essaim propre sans aucun conteneur. Corrigez l'erreur - et encore une fois docker stack deploy -c docker-compose.yml my-app.

Source: https://habr.com/ru/post/fr420673/


All Articles