Docker简笔

166 阅读4分钟

前言

简单记录一些 Docker 相关的笔记,首先我们先明确何为 Docker?

由于之前一直做的是前端,在构建项目时,都是直接在服务器上装 node,nginx,又或者 pm2 之类的。直接了当,但如果出现那种,你需要将你的项目部署到对方的服务器上,当然你可以选择在对方服务器上安装 node,安装 nginx,前端部署相对简单,但如果涉及到后端,要部署软件就会偏多。

Docker 正是解决了这个痛点,Docker 会将你需要的软件安装到这个服务器上开辟的一个空间里,对于对方来说,他只需要安装 Docker 并且将你写好的 DockerFile 文件运行起来即可。

这种感觉非常像是虚拟机, Docker 经常也拿来与虚拟机做比较,但相对于虚拟机,Docker 的轻巧便捷是毋庸置疑的。

Docker 运行

Docker 运行绕不开 Image(镜像)Container(容器)

一般有 2 种方式:

  1. 编写 DockerFile ,然后执行 build 命令,构建成 Image(镜像)

  2. 从 仓库 中直接 pull 镜像下来(与 git 类似)

有了镜像,则可执行 run 命令将其运行起来,Container 就是运行起来的程序。

    graph LR
    D>DockerFile] --build--> I(Image镜像)
    I --push--> 远程仓库 --pull--> I

    I --run--> C(Container容器) --commit--> I
    C --restart--> C

命令整理

docker images # 显示本地所有的镜像列表
docker build # 使用Dockerfile创建镜像(推荐)
docker commit # 从容器创建镜像
docker rmi # 删除一个镜像

docker create # 创建一个容器但是不启动它
docker run # 创建并启动一个容器
docker stop # 停止容器运行,发送信号SIGTERM,在一段时间后发送SIGKILL信号
docker start # 启动一个停止状态的容器
docker restart # 重启一个容器
docker rm # 删除一个容器
docker kill # 发送SIGKILL信号,立即停止该容器

Volume 数据卷

镜像是只读的,容器只是在镜像的基础上增加了一层 读写层,那么既然涉及到了写入操作,容器如果一旦被删除了,那么容器里的数据也将会被删除,数据卷就可以解决这个问题。

即使容器被删除,数据卷依然持久化保存在于你本地(这里的本地是相对于容器而言,即不保存在容器内),且数据卷可以在容器之间共享复用。

一般我们如何将源代码放进容器里?

  1. 制作镜像时直接把源代码嵌入里面(一般不考虑这种做法)

  2. 把源代码挂载到容器的读写层(数据卷做法)

如何编写数据卷?

你可以在镜像编写完成,准备生成容器时执行命令:

docker run --name v-test3 -v D:\Desktop\index.html:/usr/share/nginx/html/index.html -d -p 7778:7777 my-docker-test

这里用了非常多的选项,但只有 -v 是数据卷命令,其他顺便一起简单记录下。

--name:给容器命名,这里我命名了 v-test3

-d:容器在后台运行

-p:本机的 7778 端口 指向容器内的 7777 端口

my-docker-test:是我要运行的镜像名

-v:本机的 D:\Desktop\index.html 路径指向容器内 /usr/share/nginx/html/index.html,如此之后,修改本地的 index.html 就会使得容器内的一起改变。

当然你也可以在 Dockerfile 里定义一个数据卷:

# 指定数据卷
VOLUME /path/to/volume

通过该 dockerfile 创建的镜像运行的容器,在运行时候会自动创建数据卷,并将其关联到容器内的 /path/to/volume 路径。

但如果你要关联到本地的特定路径,那么还是要使用 -v 来指定。

【注】我这只是最浅显的,实际上 docker 也有 docker volume 命令,但这里就不记录了。

.dockerignore

和 .gitignore 类似,写在 .dockerignore 里的文件会在 docker build 时候被忽略掉。

node_modules/
.git
.vscode/
*.md
.gitignore

Dockerfile 例子

这里用到了多阶段构建一个简单的前端项目,让我们程序能自己 build ,自己弄到 nginx 上。当然前端也有很多构建方式,不一定使用这个,只作为举例使用,后面想结合 jenkins ,k8s 搞 CI/CD 之类的,由读者自己搞搞。

# 多阶段构建

# 拉取 node,并将当前构建阶段命名为 build-stage
FROM node:18-alpine3.14 as build-stage

# 指定工作目录:为容器内的 /docker-app
WORKDIR /docker-app

# 复制当前目录文件 到容器的工作目录内
COPY . .

# 设置变量
RUN npm config set registry https://registry.npmmirror.com

# 执行install 和 build。 现如今的node中默认安装了npm 和yarn,我们直接使用 yarn
RUN yarn install
RUN yarn build

# CMD 指令类似于 RUN 指令,不过是用来执行程序的,二者运行时机不一样
# CDM 在 docker run 时运行,RUN 是在 docker build 时运行

# =============================================================
# 这时候 build-stage 内已经存在了 dist 目录
# 拉取 nginx
FROM nginx as nginx-stage

# 从本地中拷贝 nginx 配置过去
COPY /nginx.conf /etc/nginx/nginx.conf
# 由于 build-stage 里的工作目录是 /docker-app,所以这里要注意前缀
# /usr/share/nginx/html 这个是我在 nginx.conf 里配置的根目录
COPY --from=build-stage /docker-app/dist /usr/share/nginx/html

# 仅作为声明端口
EXPOSE 7777