React + koa + mongodb + docker development environment

Time:2020-6-15

preface

This blog post is still rightmulti-spa-webpack-cliTo expand and improve.

  1. integratemongoose
  2. integrateDockerDevelopment environment.

multi-spa-webpack-cliIt has been published to NPM, and only needs to be installed in node environment.

npm install multi-spa-webpack-cli -g

The operation steps are as follows:

#1. Initialization project

multi-spa-webpack-cli init spa-project

#2. Enter the file directory

cd spa-project

#Docker not used
#3. Package unchanged parts

npm run build:dll

#4. Start the project (open the browser manually: localhost:8090 )

npm start

#5. Start mongodb

mongod

#6. Start service

cd server
npm install
npm start

#Using docker (docker needs to be installed)
#3. Start the project (open the browser manually: localhost:8090 )

npm run docker:dev

As can be seen from the above steps, docker only needs 3 steps to start the project.

mongoose

Mongoose is in node.js An object model tool for mongodb to operate conveniently in the environment.

Before you start, install mongodb. During the installation of mongodb, there may be some small troubles, especially the company’s computer (no one knows what is configured in the computer). For the installation process, please refer to [official website: mongodb installation]

Also know some concepts of mongodb.

SQL terms / concepts Mongodb terms / concepts Explanation / explanation
database database database
table collection Database tables / collections
row document Data record lines / documents
column field Data fields / fields
index index Indexes
table joins Table connection, not supported by mongodb
primary key primary key Primary key, mongodb will automatically_ ID field set as primary key

Database services and clients:

SQL MongoDB
Mysqld/Oracle mongod
mysql/sqlplus mongo

Look at the official website for mongoose related concepts

The usage is simple: define schema, convert to model, operate on model, and generate instance.

/* model.js */
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//Define schema
const UserSchema = new Schema({
  username: {
    type: String,
    unique: true,
    require: true
  },
  password: {
    type: String,
    require: true
  }
});

//Convert to Model
const UserModel = mongoose.model('User', UserSchema);

module.exports = UserModel;

/* user.js */
//Operation model
let user = await UserModel.findOne({ username });
    if (!user) {
        try {
            //Build instance
            await new UserModel({
            username,
            password
            }).save();
            ctx.body = {
            "success": true,
            "Message": "registration succeeded"
            }
        } catch (error) {
            ctx.body = {
            "success": false,
            "Message": "registration failed"
            }
        }
    } else {
    ctx.body = {
        "success": false,
        "Message": "user name already exists"
    }
}

Docker

From the above steps, we can see that the project startup steps are troublesome and easy to be disturbed when installing mongodb environment.

Next, use docker to build the development environment and improve the development experience.

Before using docker, let’s understand the following concepts.

  • Image: image is just a virtual concept. Its actual embodiment is not composed of one file, but a group of file systems, or a combination of multiple file systems.

When the image is built, it will be built layer by layer, and the former layer is the foundation of the latter layer. Each layer will not change after it is built, and any change on the latter layer will only happen on its own layer. For example, to delete a file of the previous layer, the actual operation is not to delete the file of the previous layer, but only to mark the file as deleted in the current layer. When the final container runs, you will not see the file, but in fact, the file will always follow the image. Therefore, when building the image, you need to be extra careful. Each layer should contain only what needs to be added to that layer, and any extra things should be cleaned up before the end of the layer construction.

Therefore, during production deployment, ensure the purity of each layer and eliminate unnecessary files. For example, develop compile time files (nodes_ module )。 This also avoids unnecessary overstaffing of the image.

  • Container: the essence of a container is a process, but different from the process executed directly in the host, the container process runs in its own independent namespace.

The processes in the container run in an isolated environment, which is used as if they are operating under a host independent system. This feature makes container encapsulated applications more secure than running directly on the host.

When each container is running, it is based on the image layer, on which a storage layer of the current container is created. We can call this storage layer prepared for reading and writing when the container is running as the container storage layer.

The life cycle of the container storage layer is the same as that of the container. When the container dies, the container storage layer also dies. Therefore, any information saved in the container storage layer will be lost with the deletion of the container.

According to the requirements of docker best practice, the container should not write any data to its storage layer, and the container storage layer should remain stateless. All file write operations should use data volume or bind host directory. The read and write in these locations will skip the container storage layer and directly read and write to the host (or network storage), with higher performance and stability.

The development environment often modifies the files, so the data volume here can be used to bind the host directory.

  • Context: the file directory passed to the docker engine.

Docker is a docker engine (i.e. server daemons) and a client tool at runtime. When the image is built, the context is copied to the docker engine. Then the instruction is issued through the docker client, and the execution of the instruction is in the docker engine. Therefore, the context scope should be reasonable. If the scope is too large, the file will be copied to the docker engine for a long time; if the scope is too small, the file outside the scope cannot be operated.

Docker deployment development environment

The deployment of the development environment is very simple. You only need to configure the Dockerfile and docker-compose. Relevant documents can be seen in [dockerfile instruction details] and [compose template file]

Docker compose uses yaml language, [yaml language tutorial]

version: '3.6'

services:
  client:
    container_name: "client"
    build:
      context: ../
      dockerfile: Dockerfile.client.dev
    volumes:
      - ../src:/app/client/src
    ports:
      - "8090:8090"
    depends_on:
      - server

  server:
    container_name: "server"
    build:
      context: ../server
      dockerfile: Dockerfile.server.dev
    volumes:
      - ../server:/app/server
    ports:
      - "8080:8080"
    depends_on:
      - database


  database:
    container_name: mongo
    image: mongo
    volumes:
      - ../data:/data/db
    ports:
      - "27017:27017"

What the development environment needs is real-time display effect, so does the front-end page and the back-end service.
As mentioned above, the context has been submitted to the image, how can the front-end project realize hot replacement in the container? In fact, it’s very simple. It’s the configuration of volumes. In the same way, the back end is the same, but it needs the help of the Modelon tool.

During deployment, there are also some problems, that is, in the image, localhost cannot be used and needs to be replaced by IP.

//Front end projects
/* webpack.dev.js */
  devServer: {
    publicPath: '/',
    contentBase: path.resolve(__dirname, '..', 'dist'),
    port: APP_CONFIG.port,
    Host: '0.0.0.0', // please specify
    hot: true,
    historyApiFallback: {
      index: '/'
    }
  }

//Back end items
/* config.js */
module.exports = {
  'database': ' mongodb://database : 27017 / yexiaochen '// matches the database service name in docker compose
}

Recommended Today

nuxt.js Imitating wechat app communication chat | Vue + nuxt chat | imitating wechat interface

Project overview be based on vue.js + nuxt.js +Chat room imitating wechat app interface developed by vuex + webpack + node + vant and other technologiesNuxtchatroom project。 It realizes the functions of card type drag and slide, message / expression sending, picture / video preview, red packet / circle of friends and so on. Technology […]