Cómo empacar la aplicación VueJS + NodeJS + MongoDB en Docker

Nuevo-Proyecto-1
Como puede ver en el artículo anterior, trabajé con diferentes proyectos. Los primeros días en un nuevo equipo generalmente son de la misma manera: el back-end se sienta a mí y realiza acciones mágicas para instalar y desplegar la aplicación. Docker es indispensable para frontenderov porque el backend se escribe a menudo sobre una amplia variedad de pilas PHP / Java / Python / C # y el frente no es necesario cada vez para distraer a Beck que toda configurar y desplegar. Solo en un lugar vi un montón de Docker-Jenkins con un despliegue transparente, registros, atornillados por autocomprobaciones.

Se han escrito muchos artículos detallados sobre docker. Este artículo discutirá el despliegue de la Aplicación de Página Única usando VueJS / Vue Router, la parte del servidor como API RESTful con NodeJS, y MongoDB se usa como la base de datos. Docker Compose se usa para describir y ejecutar varias aplicaciones de contenedor.

¿Por qué necesito acoplable


Docker le permite automatizar el proceso de implementación de una aplicación. El desarrollador ya no necesita instalar programas por su cuenta, para lidiar con la incompatibilidad de versiones en su máquina. Es suficiente instalar Docker y conducir 1-2 equipos en la consola. Es más conveniente hacer esto en Linux.

Empezando


Conjunto del estibador y acoplable El componer

estructura de carpetas

Creamos 2 carpetas para aplicaciones de cliente y servidor. Un archivo con la extensión .yml es una configuración de Docker Compose donde los contenedores de aplicaciones se definen y vinculan.
Docker-compose.yml:

version: "3" services: mongo: container_name: mongo hostname: mongo image: mongo ports: - "27017:27017" server: build: server/ #command: node ./server.js #   CMD  Dockerfile  /server ports: - "3000:3000" links: - mongo client: build: client/ #command: http-server ./dist #   CMD  Dockerfile  /client network_mode: host ports: - "8089:8089" depends_on: - server 

Creamos 3 servicios en docker: para NodeJS, MongoDB y para estadísticas en Vue. Para asociar el cliente con un servidor añadido depende del servidor. Enlaces mongo se usa para vincular MongoDB con la API del servidor. nombres de servicio - servidor, cliente, mongo.

Cliente en VueJS


La carpeta / client contiene la aplicación en VueJS. Aplicación creada con Vue Cli . Al compilar la imagen, la aplicación cliente se integra en un conjunto de archivos estáticos en la carpeta / dist . Dockerfile describe un conjunto de comandos para construir una imagen:

 FROM node:10 WORKDIR /client COPY ./package*.json ./ RUN npm install RUN npm install -g http-server COPY . . RUN npm run build EXPOSE 8081 CMD ["npm", "test:dev"] 

Tenga en cuenta que package.json copiado e instalado por separado del resto de los archivos del proyecto. Esto se hace para el rendimiento, de modo que el contenido de la carpeta / node_modules se almacena en caché cuando se reconstruye. Cada línea de comando se almacena en caché por separado.

Finalmente, cuando se inicia el contenedor, se npm run dev comando npm run dev . Este comando se describe en package.json:

 "scripts": { "test:dev": "http-server dist -p 8081 -c 1 --push-state" } 

Para ejecutar archivos desde la carpeta / dist , http-server instalado globalmente, y el paquete spa-http-server está configurado en dependencias de desarrollo para que Vue Router funcione correctamente. El indicador –push-state redirige a index.html. -C bandera con un valor de 1 segundo se añade al servidor HTTP no a los scripts de caché. Este es un caso de prueba; en un proyecto real es mejor usar nginx.

En Vuex tienda crea un campo apiHost: 'http://localhost:3000' , que se prescribe puerto NodeJS Api. La parte del cliente está lista. Ahora todas las solicitudes del cliente para volver a esta URL.

API del servidor NodeJS


En la carpeta /server , cree server.js y Dockerfile:

 FROM node:10 WORKDIR /server COPY ./package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["node", "server.js"] 

Server.js especifica la url para la base de datos const url = 'mongodb://mongo:27017/'; . Permitimos solicitudes de dominio cruzado del cliente:

 const clientUrl = 'http://localhost:8081'; const corsOptions = { origin: clientUrl, optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204 }; app.use(cors()); app.all('/*', (req, res, next) => { res.header('Access-Control-Allow-Origin', clientUrl); res.header('Access-Control-Allow-Headers', 'X-Requested-With'); next(); }); app.get('/getProducts', cors(corsOptions), (req, res) => { products.getContent .then(data => res.json(data), err => res.json(err)); }); app.get('/getUsers', cors(corsOptions), (req, res) => { db.getUsers() .then(data => res.json(data), err => res.json(err)); }); (corsOptions), (req, res) => { const clientUrl = 'http://localhost:8081'; const corsOptions = { origin: clientUrl, optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204 }; app.use(cors()); app.all('/*', (req, res, next) => { res.header('Access-Control-Allow-Origin', clientUrl); res.header('Access-Control-Allow-Headers', 'X-Requested-With'); next(); }); app.get('/getProducts', cors(corsOptions), (req, res) => { products.getContent .then(data => res.json(data), err => res.json(err)); }); app.get('/getUsers', cors(corsOptions), (req, res) => { db.getUsers() .then(data => res.json(data), err => res.json(err)); }); 

Conclusión


Ahora vamos al directorio del proyecto y ejecutar la docker-compose build longitud para la construcción de imágenes y docker-compose up a los contenedores de lanzamiento. El comando generará 3 contenedores: servidor, cliente, mongo . Para un servidor en NodeJS, puede configurar la recarga en caliente asociándola con la carpeta del usuario. Y el cliente está en desarrollo para ejecutarse localmente con recarga en caliente, ejecutando por separado el servidor y el mongo . Para iniciar un servicio independiente, es suficiente para indicar el nombre de docker-compose up client . No se olvide de hacer de vez en cuando prune , y la eliminación de los recipientes (contenedores), redes (redes) e imágenes (imágenes), para liberar recursos.

El código completo se puede encontrar aquí . El proyecto aún está en desarrollo.

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


All Articles