 
 
      As you can see from the previous article, I worked with different projects. The first days in a new team usually go the same way: the back-end sits down to me and performs magical actions for installing and deploying the application. Docker is indispensable for front-end since the backend is often written on a wide range of PHP / Java / Python / C # stacks and the front does not need to distract the backend every time to install and deploy everything. Only in one place did I see a bunch of Docker-Jenkins with a transparent deploy, logs, screwed by self-tests.
A lot of detailed articles have been written about docker. This article will focus on deploying Single Page Application using VueJS / Vue Router, the server part as a RESTful API with NodeJS, and MongoDB is used as the database. Docker Compose is used to describe and run several container applications.
Why do I need a docker
Docker allows you to automate the process of deploying an application. The developer no longer needs to install programs on his own, to combat incompatibility of versions on his machine. It is enough to install Docker and drive 1-2 teams into the console. It is most convenient to do this on Linux.
Getting started
Install Docker and Docker compose
Folder structure
We create 2 folders for client and server applications. A file with the .yml extension is a Docker Compose config where application containers are defined and linked.
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
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     We create 3 services in docker: for NodeJS, MongoDB and for statics on Vue. To connect the client to the server, depends on server is added. Links mongo is used to link MongoDB with the server API. Server, client, mongo - service names.
Client on VueJS
The / client folder contains the application on VueJS. Application created using Vue Cli . When building the image, the client application builds into a set of static files in the / dist folder. Dockerfile describes a set of commands for building an image:
 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"]
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      Please note that package.json is copied and installed separately from other project files. This is done for performance, so that the contents of the / node_modules folder are cached when the build is repeated. Each command line is cached separately.
Finally, when the container starts, the
npm run dev
      
      command is executed. This command is described in package.json:
 "scripts": { "test:dev": "http-server dist -p 8081 -c 1 --push-state" }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      To run files from the / dist folder,
http-server
      
      installed globally, and
spa-http-server
      
      installed in dev-dependencies so that Vue Router works correctly. The –push-state flag redirects to index.html. The -c flag with a value of 1 second is added so that the http-server does not cache scripts. This is a test case; on a real project it is better to use nginx.
In the Vuex store, create the
apiHost: 'http://localhost:3000'
      
      field, where the NodeJS Api port is registered. The client part is ready. Now all requests from the client to the back go to this url.
NodeJS server API
In the
/server
      
      folder, create server.js and Dockerfile:
 FROM node:10 WORKDIR /server COPY ./package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["node", "server.js"]
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      Server.js specifies the url for the database
const url = 'mongodb://mongo:27017/';
      
      . We allow cross-domain requests from the client:
 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)); });
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     
      Conclusion
Now go to the project directory and run
docker-compose build
      
      images and
docker-compose up
      
      to start the containers. The command will raise 3 containers: server, client, mongo . For a server on NodeJS, you can configure hot-reload by associating it with the user folder. And the client is under development to run locally with hot reload, running separately server and mongo . To start a separate service, just specify its name
docker-compose up client
      
      . Remember to sometimes do
prune
      
      and delete containers, networks, and images to free up resources.
The full code can be found here . The project is still under development.