The server stack is Nginx + KOA + PostgresQL. It takes a lot of effort to set up the environment and deploy it on centos, deploy the test server, and then deploy the production server when it goes live. There is a lot of “manual work” that is boring and requires energy. Therefore, I began to think about how to automate the construction and deployment of this part of the work, which led to Docker.

What is a Docker

Docker is a virtualization technology that is lighter than virtual machines. It virtualizes entities called containers. The container itself is a scoped Sandbox, and it contains only the base library and the services it hosts, which is very lean. After the container runs, it is just a process in the host machine, occupying very small resources, which creates conditions for the operating system to run container cluster, operability and flexibility is excellent.

What’s the relationship between the image and the container? The image can be regarded as a class and the container as an object. The container is generated by the image instantiation. Of course, one image can generate multiple containers.

The client Docker

How do we use Docker on the client side if it’s not on the server? On Windows and OSX you can use Docker Desktop, plus Kitematic, both Desktop management tools that are very convenient for general operations. Docker Desktop and Kitematic only visualize some operations, but the command line is still necessary, because many operations can only be done from the command line.

Docker basic operations

Name of the mirror

For mirror tags, such as Nginx :1.19.0-alpine, 1.19.0 is the version number of Nginx and Alpine is the code name for OS.

Jessie: debian 8

Stretch: debian 9

Buster: debian 10

Alpine: Alpine, recommended because it is very small

Alpine is one of the smallest, with some being a quarter the size of others. This means building images faster and running more efficiently because fewer components are loaded, which means fewer bugs and more security.

Pull the mirror

Docker pull nginx: 1.19.0 - alpineCopy the code

Start the container

–name web: Specifies the container name as web

-p 8080:80: container nginx listens on port 80 and maps to local port 8080

-v XXXX: XXXX: the local configuration file is mapped to the container nginx configuration file

-d: background running

Nginx :1.19.0-alpine: mirror used

docker run --name web -p 8080:80 -v /usr/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -dNginx: 1.19.0 - alpineCopy the code

Other operating

docker images # display mirror
docker rmi xxx # delete mirror
docker ps # display the running container
docker rm xxx # delete container
Copy the code

Dockerfile

The most convenient way to build an image is to use Dockerfile, which is the configuration file of the image. As long as there is a Dockerfile, you can build an image at any time. Here’s how to build a very simple nginx image. From is the base image to use:

FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
Copy the code

Docker-compose

More powerful management tools are needed when we have a project that not only has a single container, but needs to run multiple containers and communicate with each other. For example, K8S, but the official docker-compose is enough for our current small project.

Docker-comemage. yml configuration file (image, ports, and volumes)

version: "3"

services:
  webapp:
    image: web
    ports:
      - "8080:80"
    volumes:
      - "/data"
  redis:
    image: "redis:alpine"
Copy the code

You can then do this using the following command line:

docker-compose build [options] [SERVICE...] # Build (rebuild) the service container in the project
docker-compose up -d Compose project run in the background
Copy the code

Docker-compose up is a very powerful command that attempts to automate a series of operations including building an image, (re) creating a service, starting a service, and associating a service-related container. Linked services will be automatically started unless they are already running. Most of the time, you can start a project directly with this command.

Build the nginx-Node-Postgres project

With this in mind, we can then build our own project, starting with the Node service dockerfile, which does the following steps

  1. Create the container working directory
  2. Copy the relevant configuration files to the container
  3. Installation in containernpmpackage
  4. runpm2Start the container
FROM node:14.5.0-alpine3.12
# Working directory
WORKDIR /usr/src/app
Copy the configuration file
COPY package*.json ./
COPY process.yml ./
RUN npm set registry https://registry.npm.taobao.org/ \
  && npm install pm2 -g \
  && npm install
# Use PM2 management
CMD ["pm2-runtime"."process.yml"."--only"."app"."--env"."production"]
EXPOSE 3010
Copy the code

Next, configure docker-comemage.yml

  1. Db configures a databasepostgres, where the data volumevolumesThe database directory and initialization steps are mapped
  2. The app is configured withnodeService, among thembuildIt’s above the mapdockerfileThe directory in which it resides;depends_onIndicates the dependent container and startup sequence. Db is started before db is startednode;linksRepresents mapping the name of db to the app container
  3. Nginx containerdepend_onConfigure forwarding at the same time in the APP containernodeThe service of
version: '3'

services:
  db:
    image: Postgres: 12.3 - alpine
    container_name: postgres
    environment:
      - TZ=Asia/Shanghai
      - POSTGRES_PASSWORD=xxxx
    volumes:
      - ./postgres/data:/var/lib/postgresql/data
      - ./postgres/init:/docker-entrypoint-initdb.d
    ports:
      - 5432: 5432
    restart: always In the production environment, always is recommended
    expose:
      - 5432
      
  app: 
    image: koa-pg
    container_name: koa
    volumes:
      - ./dist:/usr/src/app/dist
      - ./logs:/usr/src/app/logs
    build: . /
    environment:
      - TZ=Asia/Shanghai
    restart: always
    depends_on:
      - db
    links:
      - db
    expose:
      - 3010
      
  nginx:
    image: Nginx: 1.19.0 - alpine
    container_name: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 8080: 80
    environment:
      - TZ=Asia/Shanghai
    restart: always
    depends_on:
      - app
    links: Configure nginx forwarding with host name instead of IP
      - app
    expose:
      - 8080
Copy the code

After configuring our project, it’s time to get it up and running

docker-compose up
Copy the code

This is true on our local development machine, as well as on the server, you can deploy as many servers as you want, as long as docker is installed, it is a command line to solve the matter.

Docker-compose up, docker-compose up, so easy!