跳转至

Docker 工作流\#

简单认识docker,分清镜像和docker容器的区别,简单操作docker程序运行

工作流\#

定制镜像文件 Dockerfile –> docker build -> 镜像 Image –> docker run -> 容器 Container

使用docker push将制作好的镜像推送到 Docker Hub

使用docker pull将镜像拉取到本地

使用docker run使用容器运行镜像

命令拆解\#

初始化服务\#

初始化项目,使用

npm init -y

自动生成package.json文件

使用express框架来构建服务器,安装一下

npm install express

在macOS下如果失败尝试加上sudo

成功后会生成node_modules,在目录下的package.json中依赖项dependencies中可以发现键值对express

创建app.js文件

touch app.js

写入下面的代码

const express = require('express');
const app = express();
const PORT = 3000;

app.get("/", (req, res) => {
    res.send("<p> hello world ! </p>")
});

app.listen(PORT, () => console.log("运行端口:3000"));

使用node.js试着在本地运行:

$ node app.js
运行端口:3000

配置文件\#

创建Dockerfile,注意大写

$ touch Dockerfile
$ vim Dockerfile
# 添加:
FROM node:18-alpine3.15 # 指定18版本的node,alpine3.15为linux的轻量级发行版
WORKDIR /work # 指定工作目录
COPY package.json . # 当前文件夹复制到镜像里的/work文件夹
RUN npm install # 运行安装命令,内容在package.json中
COPY . . # 本地全部文件复制到镜像的工作目录中
EXPOSE 3000 # 容器端口号和本地不一样
CMD ["node", "app.js"]

创建.dockerignore,把不想复制到镜像的文件和文件夹全都写进去

$ touch .dockerignore
$ vim .dockerignore

node_modules
Dockerfile
.dockerignore
.git
.gitignore

构建镜像\#

docker build .

这样,docker就会自行根据Dockerfile所在目录进行构建

注意,必须确保 Docker 服务已经启动,否则会报错:

ERROR: Cannot connect to the Docker daemon at unix:///Users/kiharari/.docker/run/docker.sock. Is the docker daemon running?

这表明 Docker 守护进程 (daemon) 没有运行,打开 Docker 客户端即可

如果发生错误,多半是网络问题,确保终端代理后再尝试

操作镜像\#

查看镜像\#

$ docker images
REPOSITORY                                    TAG              IMAGE ID       CREATED              SIZE
<none>                                        <none>           1b1df0c73a59   About a minute ago   172MB

此命令会显示所有镜像

因为没有指定名称,RESPOSITORY的值为<none>

添加镜像名称

docker tag 1b1 yourid/nodejs:v1.0 # 用户名/镜像名:版本名

也可以在进行build的时候定义,加上-t参数代表tag

登录\#

docker login

输入用户名密码

推送到 Docker Hub

docker push yourid/nodejs:v1.0

删除镜像\#

docker rmi -f yourid/nodejs:v1.0

rmi表示remove image

拉取镜像\#

docker pull yourid/nodejs:v1.0

🌟运行镜像\#

$ docker run -d imagename
cbc33e9290b82ea82836f11dab7e3b6c6088512f27376f0259321abe927dea72

-ddetached mode,在后台运行

确认容器状态

$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS      NAMES
cbc33e9290b8   kiharari/nodejs:v1.0   "docker-entrypoint.s…"   40 seconds ago   Up 40 seconds   3000/tcp   great_ride

psprocess status

端口映射

-p 3000:3000 # 主机端口:容器端口

定义容器名称

--name imagename

暂停容器

docker stop id

用以上的命令来运行容器

$ docker run -d -p 3000:3000 --name hello kiharari/nodejs:v1.0
3b62f31cbb69b603a712184ea246747c779246869c4899fb0b41a343df748bbd

$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                    NAMES
3b62f31cbb69   kiharari/nodejs:v1.0   "docker-entrypoint.s…"   13 seconds ago   Up 12 seconds   0.0.0.0:3000->3000/tcp   hello
cbc33e9290b8   kiharari/nodejs:v1.0   "docker-entrypoint.s…"   4 minutes ago    Up 4 minutes    3000/tcp                 great_ride

现在访问localhost:3000就能正常看见服务器返回的内容了

访问容器\#

使用docker exec命令

docker exec -it <NAMES> /bin/sh

参数i代表交互interactive,参数t代表以终端方式进行的interactive,即pseudo-TTY伪终端

/bin/sh表示执行 shell,这是Alpine进入 shell 的方式

现在我们执行一下试试

$ docker exec -it hello /bin/sh
/work #

可以发现直接进入了之前设置的工作目录

退出容器使用命令exit

🌟同步目录和容器\#

指定路径

创建时加上参数-v,为Volume的缩写,需要用绝对路径

docker run -d -v /Users/kiharari/documents/调试代码/docker_try/:/work -p 3000:3000 --name hello kiharari/nodejs:v1.0

这里将本地的文件映射到了docker的工作目录下

当文件被修改时,需要用nodemon

npm i nodemon --save-dev

安装成功后可以在package.json中看到依赖项nodemon,修改script

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
},
==>
"scripts": {
  "dev": "nodemon app.js"
},

如果npm run dev,就用nodemon执行

并且修改Dockerfile

CMD ["npm", "run", "dev"]

最后的命令\#

刚刚对镜像文件进行了一些修改,现在重新构建镜像:

docker build -t hello .

这将创建一个名称为hello的镜像

运行镜像,注意,在运行之前,由于我们会声明本地文件与镜像文件之间的绑定关系,因此镜像文件被删除,本地文件同样被删除,这通常是我们不想看到的,需要设置同步性,在第一个-v选项后增加第二个-v

-v /work/node_modules

这个参数声明node_modules文件夹不进行同步

并且如果镜像新增文件,本地同样会新增,如果不想本地新增,设置只读read only,在第一个-v最后加上:ro

因此,最后的命令为:

docker run -d -v /Users/kiharari/documents/调试代码/docker_try/:/work:ro -v /work/node_modules -p 3000:3000 --name hello kiharari/nodejs:v1.0

删除容器

docker rm -fv hello

记得加上-v删除对应的volume,否则volume会越积越多

docker-compose\#

上面启动容器的命令未免太长太过繁琐,因此有了docker-compose这样的自动化方式,只需要在yaml文件中配置好对应的项就可以按照要求正确地创建镜像并运行

创建docker-compose.yml,缩进采用空格两行,:必须跟空格

version: "3.8"
  services:
  docker_container:
    build: .
    ports:
        - "3000:3000"
    volumes:
      - ./:/work:ro
      - /work/node_modules

--build如果有修改,就会重建,如果不加下次就会使用之前的缓存

docker-compose up -d --build

使用docker images查看创建的镜像:

$ docker images
REPOSITORY                                    TAG              IMAGE ID       CREATED         SIZE
docker_try-docker_container                   latest           3aa616599463   3 minutes ago   174MB

docker-compose清除容器

docker-compose down -v

-v清除对应的volume

References\#

  1. https://www.bilibili.com/video/BV1MR4y1Q738/