简介
本项目针对刚刚接触 Docker 的新手,讲解 Docker 基本操作,并结合一个实际案例来讲解具体应用。
环境说明
操作系统:MacOS Ventura 13.0
安装 Docker
通过官方网站地址选择对应的操作系统进行安装即可 官方连接
查看 Docker 版本
安装成功会显示如下信息(MacOS 版)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| Client: Cloud integration: v1.0.35 Version: 24.0.2 API version: 1.43 Go version:go1.20.4 Git commit:cb74dfc Built: Thu May 25 21:51:16 2023 OS/Arch: darwin/amd64 Context: desktop-linux Server: Docker Desktop 4.21.1 (114176) Engine: Version: 24.0.2 API version: 1.43 (minimum version 1.12) Go version: go1.20.4 Git commit: 659604f Built:Thu May 25 21:52:17 2023 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.21 GitCommit:3dce8eb055cbb6872793272b4f20ed16117344f8 runc: Version: 1.1.7 GitCommit:v1.1.7-0-g860f061 docker-init: Version: 0.19.0 GitCommit:de40ad0
|
创建本地项目
初始化项目
1 2 3
| mkdir learn-docker npm init -y npm install express
|
启动简单的服务
创建 app.js 文件
1 2 3 4 5 6 7 8 9 10 11 12
| const express = require("express"); const app = express(); const PORT = 3000; app.get("/", (req, res) => { res.send("<p>大家好啊!</p>"); }); app.listen(PORT, () => { console.log("running at 3000 prot"); });
执行 `node app.js` 启动服务 此时我们可以在 `http://localhost:3000/` 访问到我们的内容。 接下来我们使用 Docker 来实现。
|
创建 Dockerfile 文件
在项目的根目录创建 Dockerfile 文件
1 2 3 4 5 6 7
| FROM node:20-alpine3.17 WORKDIR /myDocker COPY package.json . RUN npm install COPY . . EXPOSE 3000 CMD ["node","app.js"]
|
- 注意 1: Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐
- 注意 2:我们这里需要忽略 node_modules 等一些文件的复制
- 注意 3:EXPOSE 3000 只有文档说明作用 不起任何实际作用。实际开启 3000 端口的是 app.js 的内容;而 Dockerfile 里的 EXPOSE 只是让人们知道这个容器使用的是 3000 端口
创建 .dockerignore 文件
前面提到的注意 2 中的事项,我们已经通过 npm install 安装了 node_modules ,所以不需要再复制一遍。
1 2 3 4 5
| node_modules Dockerfile .dockerignore .git .gitignore
|
构建镜像
通过上面的操作我们就可以来构建镜像了。
查看镜像
会看到如下的展示
1 2
| REPOSITORYTAG IMAGE ID CREATED SIZE nodejs-image latest227b17a0a994 About an hour ago 189MB
|
给镜像取名字 tag
1
| docker tag 227 baituzai/nodejs:v1.0
|
- 227 是镜像 id 的前 3 位数字
- baituzai/nodejs:v1.0 用户名/镜像名:版本
注意:如果不加版本就是 lasted 建议务必加上
登录并推送 Docker Hub
1 2 3 4
| docker login
docker push baituzai/nodejs:v1.0
|
在构建镜像的时候就定义名字 具名镜像 -t
1
| docker build -t my_docker_image_name .
|
注意:. 表示相对地址
删除本地的镜像
已经存在于 Docker Hub 所以把本地删除
1
| docker rmi -f baituzai/nodejs:v1.0
|
- rm remove 移除
- i 表示 image 镜像
- f force 强制删除(在使用中的镜像会被删除)
把镜像拉取到本地
1
| docker pull baituzai/nodejs:v1.0
|
运行镜像
这种方式会占用我们的当前命令行窗口,使用 -d 选项使容器在后台运行
1
| docker run -d nodejs-image
|
查看在运行的容器
- ps 表示 process status
- -a 产看全部 包括未运行的容器
端口映射
当我们运行起容器后,想要在本地访问发现是不能成功的,我们需要把 Docker 服务器的端口转发到本地端口才能进行访问。
1
| docker run -d -p 3000:3000 nodejs-image
|
- 3000:3000 主机端口:容器端口,访问主机端口 3000 的时候就会访问容器端口 3000。使用其他端口也可以,只要不冲突就好。
给这个容器自定义一个名字
如果不定义那么系统就会给容器随机定义一个名字
1
| docker run -d -p 3000:3000 --name nodejs-container nodejs-image
|
停止运行容器(关机)
把不使用的容器停止运行,也就关机,节省资源。
1
| docker stop nodejs-container
|
删除容器
1
| docker rm container_id/contanier_name
|
强制删除
1
| docker rm -f container_id/contanier_name
|
修改本地文件 同步到 docker 文件
修改本地文件后,docker 不会自动同步, 镜像如同一张照片,只修改文件并没有修改镜像,所以需要生成新的镜像
查看我们正在运行的容器
如何访问容器呢?
1
| docker exec -it nodejs-container /bin/sh
|
- exec ececute 执行
- i interactive 交互
- t pseudo-TTY 伪终端
- nodejs-container 容器名
- /bin/sh 表示我们执行一个新的 bash shell
执行后会直接进入我的工作目录 myDocker 使用 exit
退出 shell
销毁容器
1
| docker rm -f nodejs-container
|
重新开启一个容器 -v
1
| docker run -d -v /Users/your_name/Desktop/learnDocker/:/myDocker -p 3000:3000 --name nodejs-container nodejs-image
|
- 绝对路径 本地文件夹路径:容器文件夹路径 (/Users/your_name/Desktop/learnDocker/:/myDocker)
- 本地文件夹路径使用
pwd
查看或者使用环境变量
改动后能否成功?
虽然文件内容同步更改了,但是还是不行 因为根据镜像启动容器的时候 使用 node app.js 是根据执行是的服务器文件来启动服务的。
如果文件有修改我们需要重新执行 node app.js 才能显示最新的内容。
使用 nodemon 来自动重启
修改 package.json 的脚本
1 2 3
| "scripts": { "dev": "nodemon app.js" }
|
修改 Dockerfile
将 CMD ["node","app.js"]
改成 CMD [ "npm","run","dev"]
删除之前的镜像 并重构镜像
使用-v 选项再次启动容器
1
| docker run -d -v /Users/jiajunhua/Desktop/learnDocker/:/myDocker -p 3000:3000 --name nodejs-container nodejs-image
|
特殊处理
不要同步的文件 node_modules
1
| docker run -d -v /Users/jiajunhua/Desktop/learnDocker/:/myDocker -v /myDocker/node_modules -p 3000:3000 --name nodejs-container nodejs-image
|
容器内容修改也会导致本地内容修改 这不是我们想要的
我们要让本地变成只读模式 readonly 也就是 容器修改不会影响到本地的内容 单项流通 在-v 后面加上冒号 ro :ro
1
| docker run -d -v /Users/jiajunhua/Desktop/learnDocker/:/myDocker:ro -v /myDocker/node_modules -p 3000:3000 --name nodejs-container nodejs-image
|
使用 volume 时 当删除容器的时候 把对应的 volume 也删除
1
| docker rm -fv nodejs-container
|
解决每次写命令都很长的问题 docker-compose
1
| touch docker-compose.yml
|
1 2 3 4 5 6 7 8 9
| version: '3.8' services: nodejs-contaier: build: . ports: - "3000:3000" volumes: - ./:/myDocker:ro - /myDocker/node_modules
|
注意这里的缩进是必要的
启动 docker-compose
1 2 3
| docker-compose up docker-compose up -d docker-compose up -d --build
|
清除 docker-compose
项目仓库地址
github项目地址