头图

Docker open source application container engine, if you are a back-end developer, I believe you should know or be familiar with this technology. For many front-end developers, you may just stay at the stage where you have heard it, or even don’t know what it is. ? Or think that this is a back-end technology, I don't need to know, for example, I really don't know what it is, but if I want to become a senior front-end, this part of the vacancy needs to be filled. 161d509c018c9a Salted fish should have dreams too, maybe someday they can

This article will start by building a full-stack node.js mongoDB database to learn more about Docker and its purpose.

What is Docker

Docker is an open source application container engine, based on the Go language and open source in compliance with the Apache2.0 protocol. Docker allows developers to package their applications and dependent packages into a lightweight, portable container, and then publish to any popular Linux, Window machine, it can also be virtualized.

If you don't understand, can you explain Docker's past and present life in general?

In 2010, a few young people engaged in IT established a company called dotCloud (container technology) in San Francisco, USA. As a result, I couldn't keep going, so I open sourced it. The result Docker . It was so popular that it had a new name, so 061d509c018d2b appeared.

Docker appeared, how to simulate a isolated system environment? The answer is virtual machine, it should not unfamiliar, many developers will be installed inside the computer VMWare , through which we can conjure up several units child computer, install a window11 , a loaded CentOS , installed on my favorite QQ , WeChat and other software, multiple sub-computers are isolated from each other and do not affect each other. However, there are only a few Gs or dozens of Gs at every turn. The disks are too much to handle, and the startup is slow.

As mentioned earlier, before Docker virtual machine was the industry’s Internet celebrity in terms of environmental isolation, but the drawback is that heavy, and the Docker container technology is actually a virtualization technology, and light, fast, and integrated , Only MB level or even KB level is required. Unlike the virtual machine, which needs to simulate an operating system, Docker only needs to virtualize a small-scale environment (similar to a "sandbox").

No, I need to see the data comparison before I believe it and arrange...

Docker core concepts

In the previous section, we learned that Docker is a kind of container virtualization technology, which is lighter, faster and easier to integrate with . Next, we will quickly understand its core concepts and then go to our topic today. It is better to understand by writing code.

The three core concepts of Docker

  • Image
  • Container
  • Repository

The above relationship diagram can reflect the relationship between the three. It should be noted here that we say that Docker is a container technology, but Docker itself is not a container , it is a tool for creating containers, it is an application container engine.

image, also known as the Docker image, is a special file system. In addition to providing programs, libraries, resources, configuration and other files required by the container runtime, it also contains some configuration parameters (such as environment variables) prepared for runtime. At the same time, the image does not contain any dynamic data.

We can have a lot of images, we want to save them, and then we can go anywhere to use them to create a container environment, then we need warehouse to store, that is, Docker warehouse.

How does a warehouse exist, so everyone can store mirror images in it? No, if a problematic image is stored, won't it hang when the container is created? So there needs to be a role responsible for Docker image, which is the Docker Registry service (similar to a warehouse administrator). The official also provides a public Registry service, which is Docker Hub (a bit like our npm market), which stores many high-quality official images.

At the same time, we can also Dockfile file , which will be introduced later

Through the above description, I believe everyone Docker should also have a rough understanding, and to provide some common here Docker command,

# 容器
$ docker run  // 创建并启动容器
$ docker start // 启动容器
$ docker ps // 查看容器
$ docker stop // 终止容器
$ docker restart // 查看容器
$ docker attach // 进入容器
$ docker exec // 查看容器
$ docker export // 导出容器
$ docker import // 导入容器快照
$ docker rm // 删除容器
$ docker log // 查看日志

# 镜像
$ docker search // 检索镜像
$ docker pull // 获取镜像
$ docker images // 列出镜像
$ docker image ls // 列出镜像
$ docker rmi // 删除镜像
$ docker image rm // 删除镜像
$ docker save // 导出镜像
$ docker load // 导入镜像

# Dockfile定制镜像以及常用指令

$ docker build // 构建镜像
$ docker run // 运行镜像

COPY // 复制文件
ADD // 高级复制
CMD // 容器启动指令
ENV // 环境变量
EXPOSE // 暴露接口


# 服务
$ docker -v // 查看docker的简要信息
$ docker -version // 查看docker版本的简详细信息
$ systemctl start docker // 启动docker
$ systemctl stop docker // 关闭docker
$ systemctl enable docker // 设置开机启动
$ service docker restart // 重启docker服务
$ service docker stop // 关闭docker服务

Create Hello-World container

First you need to download Docker download address , I downloaded Window Docker Desktop , then check the version information to see if the download is successful,

I downloaded the 20.10.11 version

Then pulling Docker Hub official hello-world mirror,

Create and execute the container,

In this way, our first container is created, and we can use the above-mentioned command line docker image ls / docker image prune to view or delete it is useless ( will not be deleted when the container is stopped, which will help speed up the download and installation next time ) Mirror, you can try more commands!

Create Node program

Next, we create a Node program, which will be used in the following tutorials. The specific code details will not be introduced. You can view the following server.js and package.json:

const express = require("express");
const app = express();
const port = 8080;

app.get("/", async (req, res) => {
  res.setHeader("Content-Type", "text/html");
  res.status(200);
  res.send("<h1>你好呀!前端晚间课</h1>");
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});
{
  "name": "docker-example",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "start": "nodemon server.js"
  },
  "author": "前端晚间课",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.2"
  },
  "devDependencies": {
    "nodemon": "^2.0.15"
  }
}

Run npm run start , and it ran successfully...

Trouble with different Node versions

For the above server.js file, we add the following code:

 // ...
 const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("good");
  }, 300);
  reject("bad");
});

myPromise.then(() => {
  console.log("this will never run");
});

Then Node < 15 and Node >= 15 respectively, the result will get two different results,

Node < 15

(node:764) UnhandledPromiseRejectionWarning: something happened
(Use `node --trace-warnings ...` to show where the warning was created)
(node:764) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:764) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Node >= 15

node:internal/process/promises:218
          triggerUncaughtException(err, true /* fromPromise */);
          ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "recipe 
could not be generated".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

You will find that the execution results of the two versions will be inconsistent. The higher version (Node >= 15) will directly cause the program to crash ( ERR_UNHANDLED_REJECTION ), which is unhandled rejected Promise error.

Now suppose that for some reason, this application must run on Node v14 or earlier to work ( ignore try...catch). Every developer in the team must be ready to develop and run in this environment, but our company has a new application to run Node v17

How to solve this problem at this time? Answer: Docker

Create Dockerfile

The previous section, we introduced two different versions of Node due question was rejected untreated Promise, we describe how to use Docker to solve this problem, is actually very simple, is the need for a Node < 15 operating environment to ensure Our program will not crash,
We Docker Hub can find any of Node mirror, but there are many versions of information is optional.

Of course, we don’t need to directly use docker pull node to pull the node image. We mentioned that Dockerfile can be used to customize the custom image. It automatically judges whether there is a Node image on the current machine. If not, it will automatically go to Docker Hub pull it. Take a look at us The Dockerfile file:

# 首先先选择你需要的镜像,运行在alpine的node版本是当下最流行的
FROM node:14-alpine3.12

# 工作目录
# 这是您你将在容器内的位置
WORKDIR /usr/src/app

# 通配符用于确保 package.json 和 package-lock.json 都被复制
# COPY 源目录 容器的工作目录
COPY package*.json ./

# 安装应用依赖
RUN npm install

# 如果你正在构建用于生产的代码
# RUN npm ci --only=production

# 捆绑应用程序源
COPY . .

# 配置这个端口可以从容器外部访问
# 浏览器向 Node 应用程序发送 HTTP 请求所必需的
EXPOSE 8080

# CMD 在docker run 时运行
# 就是执行shell npm run start
CMD [ "npm", "run", "start"]

Ok, our Dockerfile file has been created successfully. The Dockerfile instruction is also briefly introduced in the code above. More detailed instruction usage can be searched on Google, but you may be curious about the above configuration file, why COPY needs to execute two Second, the last COPY . . did not copy the entire directory, so why do we need to copy package*.json above?

Docker's layers and cache

COPY twice is necessary, because Docker has layers (characteristics of the layer), each execution of an instruction will create another layer based on the layer created by the previous instruction, and the created layer will be cached as long as it happens It will be recreated again when it is changed, and we will look back at the Dockerfile file.

COPY package*.json ./ We created a layer based on the content of the file, and then ran npm install , which means that unless we change package.json , the next time we build Docker , we will use the npm install , we don’t need to install it every time we run All dependencies docker build. This will save us a lot of time.

COPY . . will look at every file in our project directory, so this layer will be rebuilt when any file changes (except package*.json ). This is exactly what we want.

Build the application container

Let's add another .dockerignore file, similar to our .gitignore , because we don't want to copy these files.

node_modules
npm-debug.log

Everything is ready, we start to build our own image,

# 以当前项目目录为源目录,给镜像名个名叫做qianduanwanjianke
$ docker build . -t qianduanwanjianke

Check again whether the image we created exists?

After creating the image, we are now ready to build a container from the image to run our application:

# --name 我们给容器名了个名,叫做qianduanwanjianke-container
# -p标志将端口从我们的主机(我们的计算机)环境3001端口映射到容器环境的8080端口,当然也可以是8080:8080。
docker run -p 3001:8080 --name qianduanwanjianke-container qianduanwanjianke

You’re done, let’s visit http://localhost:3001/ see if it’s successful,

Concluding remarks

So far, we introduced Docker Node application, created our first custom Docker image and container, and run our application in it! This is an introduction to Docker for Javascript developers, starting from the Node program. The content of the article Docker , and it should be a good introductory tutorial for our front-end developers. Due to the length of the space, I decided to introduce Docker Volume ("connect" the program copy inside the container with the copy in the project directory, update synchronization) and into the database, analyze the different database hosting servers, how to create separation, Docker Compose, etc. Put it to the next content for introduction.

The pit stepped on in the process

1. An error is reported when the image is pulled, and the error message is reported: error during connect: This error may indicate that the docker daemon is not running...

Solution:

# 在Powershell 提升访问权限解决此问题
cd "C:\Program Files\Docker\Docker"
./DockerCli.exe -SwitchDaemon

2. When creating the application container, execute docker build . -t my-node-app , and the error message: no matching manifest for windows/amd64 10.0.18363 in the manifest list entries ?

Solution:
Open Docker Devlop software, settiong -> Docker Engine , set experimental to true, restart Docker


前端晚间课
235 声望12 粉丝