
Dans les projets de moyenne et grande envergure, le site n'est pas limité à un seul service - par exemple, seulement un site, en règle générale, il existe une base de données, une API, un serveur qui achemine les demandes vers tous ces services. Déployer et mettre à jour tout cela sans aucune normalisation n'est pas facile, et la mise à l'échelle vers de nombreux serveurs est encore plus difficile.
Docker, qui est devenu la norme de facto dans le monde des applications d'emballage, de livraison et de publication, nous aidera à résoudre ce problème.
Docker nous permet d'envelopper une application ou un service avec toutes les dépendances et paramètres dans un conteneur isolé, garantissant la cohérence du contenu sur n'importe quelle plate-forme.
En tant qu'application isomorphe, nous utiliserons le framework Nuxt.js, qui se compose de Vue.js et Node.js, nous permettant d'écrire des applications Web universelles avec un rendu côté serveur (SSR).
Ce choix est dû à des préférences personnelles, cependant, de la même manière, vous pouvez prendre n'importe quel autre framework, par exemple Next.js.
Nous collectons et publions la première image.
Tout d'abord, vous devez configurer le port et l'hôte à l'intérieur de l'application. Il existe plusieurs
façons de le faire, nous utiliserons les paramètres de package.json en ajoutant une nouvelle section:
"config": { "nuxt": { "host": "0.0.0.0", "port": "3000" } }
Pour d'autres actions, nous avons besoin de docker, de docker-compose installé dans le système et d'un éditeur avec un projet ouvert.
Créez un Dockerfile que nous avons mis à la racine et décrivez les instructions pour construire l'image.
Nous devons construire l'image en fonction de l'image de la version 10 de Node.js, dans ce cas, la version légère d'alpin est utilisée:
FROM node:10-alpine
Définissez ensuite la variable d'environnement avec le nom du répertoire:
ENV APP_ROOT /web
Définissez comme répertoire de travail et ajoutez la source:
WORKDIR ${APP_ROOT} ADD . ${APP_ROOT}
Installez les dépendances et générez l'application:
RUN npm ci RUN npm run build
Et nous écrivons la commande de lancement d'application à l'intérieur de l'image:
CMD ["npm", "run", "start"]
Dockerfile FROM node:10-alpine ENV APP_ROOT /web ENV NODE_ENV production WORKDIR ${APP_ROOT} ADD . ${APP_ROOT} RUN npm ci RUN npm run build CMD ["npm", "run", "start"]
Après cela, ouvrez le dossier actuel dans le terminal et collectez l'image:
docker build -t registry.gitlab.com/vik_kod/nuxtjs_docker_example .
Exécutez l'image localement pour vérifier que tout fonctionne correctement:
docker run -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example
En allant Ă
localhost: 3000, nous devrions voir ce qui suit:

Super! Nous avons lancé avec succès la production en créant l'application sur la machine locale.
Nous devons maintenant publier l'image dans le référentiel Docker afin d'utiliser l'image assemblée finie sur le serveur cible. Vous pouvez utiliser un référentiel auto-hébergé ou tout autre, par exemple, le
hub.docker.com officiel.
J'utiliserai le référentiel dans gitlab, l'onglet avec les référentiels docker là -bas s'appelle registre. Auparavant, j'avais déjà créé un référentiel pour le projet, alors maintenant j'exécute la commande:
docker push registry.gitlab.com/vik_kod/nuxtjs_docker_example
Une fois l'image démarrée avec succès, vous pouvez commencer à configurer le serveur VPS,
le mien est le suivant:
- 1 Go de RAM
- 4 noyaux
- Disque de 30 Go
J'ai également profité de l'occasion pour installer docker immédiatement lors de la création du serveur, donc s'il n'est pas installé sur votre VPS, vous pouvez lire les instructions sur le
site officiel.Après avoir créé le serveur, allez-y et connectez-vous au référentiel docker, dans mon cas c'est gitlab:
docker login registry.gitlab.com
Après autorisation, nous pouvons démarrer l'application avec la commande vue précédemment:
docker run -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example

L'image a été téléchargée et démarrée, vérifions:

Nous voyons une image familière, nous avons lancé le conteneur avec l'application, mais déjà sur le serveur distant.
La touche finale est restée, maintenant lorsque le terminal est fermé, l'image sera arrêtée, nous allons donc ajouter l'attribut -d afin de démarrer le conteneur en arrière-plan.
Arrêtez et redémarrez:
docker run -d -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example
Nous pouvons maintenant fermer le terminal et nous assurer que notre application fonctionne correctement.
Nous avons réalisé ce qui était nécessaire - nous avons lancé l'application dans Docker et maintenant elle est adaptée au déploiement, à la fois en tant qu'image indépendante et dans le cadre d'une infrastructure plus large.
Ajouter un proxy inverse
Au stade actuel, nous pouvons publier des projets simples, mais que se passe-t-il si nous devons mettre l'application et l'API sur le mĂŞme domaine et, en plus de cela, donner les statistiques non via Node.js?
Ainsi, le besoin se fait sentir de ce que l'on appelle le serveur proxy inverse, vers lequel toutes les demandes seront reçues et redirigées en fonction de la demande vers les services associés.
En tant que tel serveur, nous utiliserons nginx.
La gestion des conteneurs s'il y en a plusieurs individuellement n'est pas très pratique. Par conséquent, nous utiliserons docker-compose pour organiser et gérer les conteneurs.
Créez un nouveau projet vide, à la racine duquel nous ajoutons le fichier docker-compose.yml et le dossier nginx.
Dans docker-compose.yml, nous écrivons ce qui suit:
version: "3.3" # services: # , nginx nginx: image: nginx:latest # 80 http 443 https ports: - "80:80" - "443:443" # container_name: proxy_nginx volumes: # nginx , - ./nginx:/etc/nginx/conf.d # - ./logs:/var/log/nginx/ # Nuxt.js nuxt: # image: registry.gitlab.com/vik_kod/nuxtjs_docker_example container_name: nuxt_app # ports: - "3000:3000"
Dans le dossier nginx, ajoutez la configuration, qui est recommandée par le site officiel
Nuxt.js , avec des modifications mineures.
nginx.conf map $sent_http_content_type $expires { "text/html" epoch; "text/html; charset=utf-8" epoch; default off; } server { root /var/www; listen 80; # nginx server_name localhost; # ip gzip on; gzip_types text/plain application/xml text/css application/javascript; gzip_min_length 1000; location / { expires $expires; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 1m; proxy_connect_timeout 1m; # , # docker-compose , nuxt_app proxy_pass http://nuxt_app:3000; } }
Nous exécutons la commande pour exécuter:
docker-compose up

Tout a commencé correctement, maintenant si nous allons à l'adresse qui écoute nginx, localhost - nous verrons notre application, il n'y aura pas de différences visuelles, mais maintenant toutes les demandes vont à nginx où elles sont redirigées en fonction des règles spécifiées.
Maintenant que nous n'avons plus de services ou de statiques, ajoutons un dossier statique dans lequel nous placerons une image.
Montez-le dans le conteneur nginx en ajoutant une ligne Ă docker-compose:
... container_name: proxy_nginx volumes: # - ./static:/var/www/static ...
Docker-compose.yml mis Ă jour version: "3.3" # services: # , nginx nginx: image: nginx:latest # 80 http 443 https ports: - "80:80" - "443:443" # container_name: proxy_nginx volumes: # nginx , - ./nginx:/etc/nginx/conf.d # - ./logs:/var/log/nginx/ # - ./static:/var/www/static # Nuxt.js nuxt: # image: registry.gitlab.com/vik_kod/nuxtjs_docker_example container_name: nuxt_app # ports: - "3000:3000"
Ajoutez ensuite le nouvel emplacement Ă nginx.conf:
location /static/ { try_files $uri /var/www/static; }
Mise Ă jour de nginx.conf map $sent_http_content_type $expires { "text/html" epoch; "text/html; charset=utf-8" epoch; default off; } server { root /var/www; listen 80; # nginx server_name localhost; # ip gzip on; gzip_types text/plain application/xml text/css application/javascript; gzip_min_length 1000; location / { expires $expires; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 1m; proxy_connect_timeout 1m; # , # docker-compose , nuxt_app proxy_pass http://nuxt_app:3000; } location /static/ { try_files $uri /var/www/static; } }
Redémarrez docker-compose:
docker-compose up --build
AccĂ©dez Ă
localhost / static / demo.jpg

Maintenant, la statique est donnée via Nginx, supprimant la charge de Node.js dans l'application principale.
Après vous être assuré que tout fonctionne, vous pouvez publier notre assemblage sur le serveur. Pour ce faire, je vais créer un référentiel dans le répertoire courant. Après avoir ajouté les journaux et le dossier statique à .gitignore.
Après cela, nous allons sur le serveur, arrêtons l'image du docker qui a été précédemment lancée et clonons le référentiel.

Avant de démarrer l'assemblage, vous devez déplacer le dossier contenant les données statiques vers le serveur, accéder au terminal sur la machine locale et utiliser l'utilitaire de ligne de commande scp pour déplacer le dossier vers le serveur:
scp -r /Users/vik_kod/PhpstormProjects/nuxtjs_docker_proxy_example/static root@5.101.48.172:/root/example_app/
Si le volume de la statique est important, il est préférable de compresser d'abord le dossier et de l'envoyer sous forme d'archive, puis de le décompresser sur le serveur. Sinon, le téléchargement peut prendre du temps.
Nous retournons au terminal sur le serveur et allons dans le dossier cloné, exécutons la commande:
docker-compose up -d
Fermez le terminal et accédez au site:


Super! En utilisant un proxy inverse, nous avons séparé la statique de l'application.
Etapes supplémentaires
Tout ce que nous avons fait ci-dessus est une option assez simple, dans les grands projets, vous devez considérer plus de choses, voici une courte liste de ce que vous pouvez faire ensuite.
- Conteneurs de données uniquement pour les zones d'administration statiques, les applications SPA et les bases de données
- Services supplémentaires pour le traitement et l'optimisation d'images, exemple
- Intégration de CI / CD, assemblage de l'image lors du push vers la branche sélectionnée, ainsi que mise à jour et redémarrage automatique des services
- Créez un cluster Kubernetes ou Swarm s'il y a plus de 1 serveurs, pour l'équilibrage de charge et une mise à l'échelle horizontale facile
Total
- Nous avons publié avec succès l'application sur le serveur et l'avons préparée pour une mise à l'échelle ultérieure.
- Nous avons appris à connaître Docker et avons eu une idée de la façon d'envelopper votre application dans un conteneur.
- Nous avons appris quelles mesures peuvent être prises pour améliorer l'infrastructure.
Code source
AppConfigurationsMerci de votre attention et j'espère que ce matériel vous a aidé!