
En proyectos medianos y grandes, el sitio no se limita a un servicio; por ejemplo, solo un sitio, como regla general, hay una base de datos, una API, un servidor que enruta las solicitudes a todos estos servicios. Implementar y actualizar todo esto sin ninguna estandarización no es fácil, y escalar a muchos servidores es aún más difícil.
Docker, que se ha convertido en el estándar de facto en el mundo de las aplicaciones de empaque, entrega y publicación, nos ayudará a resolver este problema.
Docker nos permite envolver una aplicación o servicio con todas las dependencias y configuraciones en un contenedor aislado, garantizando la consistencia del contenido en cualquier plataforma.
Como aplicación isomórfica, utilizaremos el marco Nuxt.js, que consiste en Vue.js y Node.js, lo que nos permite escribir aplicaciones web universales con representación del lado del servidor (SSR).
Esta elección se debe a la preferencia personal, sin embargo, de la misma manera, puede tomar cualquier otro marco, por ejemplo Next.js.
Recopilamos y publicamos la primera imagen.
En primer lugar, debe configurar el puerto y el host dentro de la aplicación. Hay varias
formas de hacer esto, usaremos la configuración en package.json agregando una nueva sección:
"config": { "nuxt": { "host": "0.0.0.0", "port": "3000" } }
Para acciones adicionales, necesitamos docker, docker-compose instalado en el sistema y un editor con un proyecto abierto.
Cree un Dockerfile que colocamos en la raíz y describa las instrucciones para construir la imagen.
Necesitamos construir la imagen basada en la imagen Node.js versión 10, en este caso se usa la versión ligera de alpine:
FROM node:10-alpine
Luego configure la variable de entorno con el nombre del directorio:
ENV APP_ROOT /web
Establecer como el directorio de trabajo y agregar la fuente:
WORKDIR ${APP_ROOT} ADD . ${APP_ROOT}
Instale las dependencias y compile la aplicación:
RUN npm ci RUN npm run build
Y escribimos el comando de inicio de la aplicación dentro de la imagen:
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"]
Después de eso, abra la carpeta actual en la terminal y recopile la imagen:
docker build -t registry.gitlab.com/vik_kod/nuxtjs_docker_example .
Ejecute la imagen localmente para verificar que todo funcione correctamente:
docker run -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example
Yendo a
localhost: 3000, deberíamos ver lo siguiente:

Genial Lanzamos con éxito la producción construyendo la aplicación en la máquina local.
Ahora necesitamos publicar la imagen en el repositorio de Docker para usar la imagen ensamblada terminada en el servidor de destino. Puede usar un repositorio
autohospedado o cualquier otro, por ejemplo, el
hub.docker.com oficial.
Usaré el repositorio en gitlab, la pestaña con los repositorios docker allí se llama registro. Anteriormente, ya creé un repositorio para el proyecto, así que ahora ejecuto el comando:
docker push registry.gitlab.com/vik_kod/nuxtjs_docker_example
Después de que la imagen se haya iniciado correctamente, puede comenzar a configurar el servidor VPS,
el mío es el siguiente:
- 1 GB de RAM
- 4 núcleos
- Unidad de 30 GB
También aproveché la oportunidad de instalar Docker inmediatamente al crear el servidor, por lo que si no está instalado en su VPS, puede leer las instrucciones en el
sitio web oficial.Después de crear el servidor, vaya a él e inicie sesión en el repositorio de Docker, en mi caso es gitlab:
docker login registry.gitlab.com
Después de la autorización, podemos iniciar la aplicación con el comando visto anteriormente:
docker run -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example

La imagen se ha descargado y comenzado, verifiquemos:

Vemos una imagen familiar, lanzamos el contenedor con la aplicación, pero ya en el servidor remoto.
El toque final permaneció, ahora cuando el terminal está cerrado, la imagen se detendrá, por lo que agregaremos el atributo -d para iniciar el contenedor en segundo plano.
Parar y reiniciar:
docker run -d -p 3000:3000 registry.gitlab.com/vik_kod/nuxtjs_docker_example
Ahora podemos cerrar el terminal y asegurarnos de que nuestra aplicación funciona correctamente.
Logramos lo que era necesario: lanzamos la aplicación en Docker y ahora es adecuada para la implementación, tanto como una imagen independiente como parte de una infraestructura más grande.
Agregar proxy inverso
En la etapa actual, podemos publicar proyectos simples, pero ¿qué pasa si necesitamos poner la aplicación y la API en el mismo dominio y, además de esto, dar las estadísticas no a través de Node.js?
Por lo tanto, surge la necesidad del llamado servidor proxy inverso, al que se recibirán y redireccionarán todas las solicitudes en función de la solicitud a los servicios relacionados.
Como tal servidor usaremos nginx.
Administrar contenedores si hay más de uno individualmente no es muy conveniente. Por lo tanto, usaremos docker-compose como una forma de organizar y administrar contenedores.
Cree un nuevo proyecto vacío, en cuya raíz agreguemos el archivo docker-compose.yml y la carpeta nginx.
En docker-compose.yml escribimos lo siguiente:
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"
En la carpeta nginx, agregue la configuración, que recomienda el sitio oficial
Nuxt.js , con pequeños cambios.
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; } }
Ejecutamos el comando para ejecutar:
docker-compose up

Todo comenzó correctamente, ahora si vamos a la dirección que está escuchando nginx, localhost: veremos nuestra aplicación, no habrá diferencias visuales, sin embargo, ahora todas las solicitudes van primero a nginx donde se redirigen según las reglas especificadas.
Ahora que no tenemos servicios o estadísticas adicionales, agreguemos una carpeta estática en la que colocaremos alguna imagen.
Móntelo en el contenedor nginx agregando una línea para docker-compose:
... container_name: proxy_nginx volumes: # - ./static:/var/www/static ...
Actualizado docker-compose.yml 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"
Luego agregue la nueva ubicación a nginx.conf:
location /static/ { try_files $uri /var/www/static; }
Actualizado 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; } }
Reinicie docker-compose:
docker-compose up --build
Vaya a
localhost / static / demo.jpg

Ahora las estadísticas están dadas a través de Nginx, eliminando la carga de Node.js en la aplicación principal.
Después de asegurarse de que todo funciona, puede publicar nuestro ensamblado en el servidor. Para hacer esto, crearé un repositorio en el directorio actual. Habiendo agregado previamente los registros y la carpeta estática a .gitignore.
Después de eso, vamos al servidor, detenemos la imagen del acoplador que se lanzó previamente y clonamos el repositorio.

Antes de comenzar el ensamblaje, debe mover la carpeta con las estadísticas al servidor, ir a la terminal en la máquina local y usar la utilidad de línea de comandos scp para mover la carpeta al servidor:
scp -r /Users/vik_kod/PhpstormProjects/nuxtjs_docker_proxy_example/static root@5.101.48.172:/root/example_app/
Si el volumen de estática es grande, es mejor comprimir primero la carpeta y enviarla como un archivo comprimido, y luego descomprimirla en el servidor. De lo contrario, la descarga puede llevar mucho tiempo.
Regresamos a la terminal en el servidor y vamos a la carpeta clonada, ejecutamos el comando:
docker-compose up -d
Cierra la terminal y ve al sitio:


Genial Usando proxy inverso, separamos las estadísticas de la aplicación.
Pasos adicionales
Todo lo que hemos hecho anteriormente es una opción bastante simple, en proyectos grandes necesita considerar más cosas, a continuación hay una breve lista de lo que puede hacer a continuación.
- Contenedores de solo datos para áreas administrativas estáticas, aplicaciones SPA y bases de datos
- Servicios adicionales para procesamiento y optimización de imágenes, ejemplo
- Integración de CI / CD, ensamblaje de la imagen cuando se empuja a la rama seleccionada, así como servicios automáticos de actualización y reinicio
- Cree un clúster de Kubernetes o Swarm si hay más de 1 servidores, para el equilibrio de carga y el escalado horizontal fácil
Total
- Hemos publicado con éxito la aplicación en el servidor y la hemos preparado para una mayor ampliación.
- Conocimos Docker y tuvimos una idea de cómo envolver su aplicación en un contenedor.
- Aprendimos qué pasos se pueden seguir para mejorar la infraestructura.
Código fuente
AppConfiguraciones¡Gracias por su atención y espero que este material lo haya ayudado!