Docker
理解:Docker 就是一种虚拟机技术,比传统虚拟机(有图像界面的那些比如 vmware、virtualbox)更加简单、轻量,更适合运行服务。
用途:可以把开发、测试环境,一键部署到任何一台机器上。
概念
- Docker image 镜像
- Docker containers 容器
- Docker 仓库
- Dockerfile
- Docker Compose
Docker image
就是一个系统的镜像文件,类似于上学的时候我们用 U 盘重装系统,在里面先下载一个.ios
的镜像文件,这个镜像文件可以安装出一个又一个的系统,这些系统就叫Docker containers
。
Docker 仓库里面存储了很多镜像文件,常用的仓库地址是https://hub.docker.com/open in new window,还可以上传自己的镜像文件。
安装
去官网下载,安装。
安装完记得镜像加速,搜索docker镜像加速
,可以大幅度提高镜像下载速度。
使用
常用命令
- 验证 Docker 是否安装成功:
docker --version
image 镜像命令
下载镜像:
docker pull <image-name>:<tag>
查看所有镜像:
docker images
删除镜像:
docker rmi <image id>
上传镜像:
docker push <username>/<repository>:<tag>
遇到 none 的情况,运行删除:
docker image prune
containers 容器命令
启动容器:
docker run <参数>
-p
端口映射-v
数据卷,文件映射-d
后台运行--name
定义容器名称
查看所有容器:
docker ps
- 显示隐藏容器:
-a
- 显示隐藏容器:
停止容器:
docker stop <container id>
删除容器:
docker rm <container id>
查看容器信息:
docker inspect <container id>
查看日志:
docker logs <container id>
进入控制台:
docker exec -it <container id> /bin/sh
nginx containers
服务启动之后,默认指向容器中的index.html
文件。
文件位置:
/usr/share/nginx/html
-v 文件映射
可以将 docker 中 nginx 容器变为一个本机服务,启动指定的项目。
参数-v
,可以修改容器中 nginx 服务默认的index.html
文件位置,修改为本机文件,启动后运行的是本机项目。
这样的好处是可以在任何系统中快速部署服务。
用法:本机电脑,安装 docker,启动 nginx 容器,配置运行本机文件。
docker run -p 81:80 -d -v /Users/cass/Desktop/code/learning/docker/html:/usr/share/nginx/html --name nginx1 nginx
Dockerfile
一个配置文件,名叫Dockerfile
,描述如何构建一个新的 image 镜像,必须放在根目录下面。
语法:
# 设置基础镜像,基于当前某个镜像文件去创建一个新的镜像
FROM node:16
# 设置工作目录,Docker将在此目录中执行后续指令
WORKDIR /app
# 将当前目录(Dockerfile文件所在的目录)下所有文件拷贝到工作目录
COPY . /app
# 在镜像中执行命令,构建镜像时,做一些系统配置,安装必备的软件
RUN npm install
RUN xxx
# 设置容器启动时默认执行的命令,只能在Dockerfile中指定一个CMD指令
# 最后需要执行一个阻塞控制台的命令: npx pm2 log
CMD npm run dev & npx pm2 log
# 设置环境变量
ENV NODE_ENV=production
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
docker build 构建
构建出一个新的 docker image 镜像
docker build -t my-node-app:latest .
.dockerignore
使用 .dockerignore
文件排除不必要的文件。
Docker Compose
通过一个配置文件,就可以让你的系统一键启动所有的运行环境:nodejs、mysql、mongodb、redis,并且将这些环境连接起来。
软件设计和开发有单一职责原则。Docker 每个容器只负责一个服务,如果开发环境有多个服务,就需要启动多个 Docker 容器,要将这些容器连接起来,就需要用到 Docker-compose。
安装
注意:版本 1 和版本 2 在命令使用上有些区别
需要通过命令单独安装,安装命令:
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
验证 Docker Compose 是否已成功安装:
docker-compose --version
配置文件
- 配置 Redis
- 配置 Mysql
- 配置 Mongodb
在项目根目录中创建一个docker-compose.yml
文件
version: '3.9' # Docker Compose 文件的版本
services: # 定义了应用程序中的所有服务,每个服务都是一个独立的容器
editor-server: # service-name 服务名称
build: # 使用自定义的 Dockerfile 来构建服务的镜像
context: . # 指定构建上下文的目录,当前目录
dockerfile: Dockerfile # 指定它的名称
image: editor-server # 指定构建出来的镜像名称
container_name: editor-server # 为服务容器指定一个自定义名称
ports: # 将容器的端口映射到宿主机的端口,您可以通过宿主机的 IP 地址和端口访问容器中的服务
- 8081:3000
environment: # 为服务设置环境变量
- MY_VARIABLE=value
- TZ=Asia/Shanghai # 设置时区
networks: # 将服务连接到一个或多个网络
- mynetwork
volumes: # 将卷挂载到服务的容器,这可以用于在容器之间共享数
- myvolume:/path/in/container
command: ['./my-script.sh', 'arg1', 'arg2'] # 覆盖服务容器默认的启动命令
depends_on: # 定义服务之间的依赖关系,决定启动顺序,在editor-mysql之后启动
- editor-mysql
- editor-mongo
- editor-redis
editor-redis:
image: redis
container_name: editor-redis
ports:
- 6378:6379
environment:
- TZ=Asia/Shanghai
db:
image: postgres:latest
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
volumes: # 定义了应用程序中使用的卷。卷用于在容器之间共享数据或持久化数据
db-data:
app-data:
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
28
29
30
31
32
33
34
35
36
37
38
39
配置 Mysql 和 Mongodb
redis 无数据库,Mysql 和 Mongodb 需要创建数据库,需要数据持久化。会有更多配置。
Mongodb:
editor-mongo:
image: mongo
container_name: editor-mongo
restart: always # 报错后重启
volumes:
- '.docker-volumes/mongo/data:/data/db' # 数据持久化
environment:
- MONGO_INITDB_DATABASE=imooc_lego_course
# - MONGO_INITDB_ROOT_USERNAME=root
# - MONGO_INITDB_ROOT_PASSWORD=123456
- TZ=Asia/Shanghai # 设置时区
ports:
- '27016:27017' # 宿主机可以用 127.0.0.1:27016 即可连接容器中的数据库
2
3
4
5
6
7
8
9
10
11
12
13
Mysql:
editor-mysql:
image: mysql # 引用官网 mysql 镜像
container_name: editor-mysql
restart: always
privileged: true # 高权限,执行下面的 mysql/init
command: --default-authentication-plugin=mysql_native_password # 解决无法远程访问的问题
ports:
- 3305:3306 # 宿主机可以用 127.0.0.1:3305 即可连接容器中的数据库
volumes:
- .docker-volumes/mysql/log:/var/log/mysql # 记录日志
- .docker-volumes/mysql/data:/var/lib/mysql # 数据持久化
- ./mysql/init:/docker-entrypoint-initdb.d/ # 初始化 sql
environment:
- MYSQL_DATABASE=imooc_lego_course # 初始化容器时创建数据库
- MYSQL_ROOT_PASSWORD=123456
# - MYSQL_USER=shuangyue #创建 test 用户
# - MYSQL_PASSWORD=shuangyue #设置 test 用户的密码
- TZ=Asia/Shanghai # 设置时区
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
./mysql/init
初始化 sql,解除安全模式,让 root 用户可以通过外网访问数据库。
项目根目录下.docker-volumes
文件夹非常重要,存储了很多数据库相关内容,不需要提交到 git,但是不要误删。
命令
构建容器:
docker-compose build <service-name>
启动所有服务:
docker-compose up -d
停止所有服务:
docker-compose down
查看服务:
docker-compose ps
docker-compose 容器中的服务相互连接
修改 redis 配置,将editor-server
连接到editor-redis
{
host: 'editor-redis', // 连接docker-compose.yml 中配置的 editor-redis
port: 6379
}
2
3
4
// 修改mongodb连接配置
Object.assign(devConf.mongodbConf, {
host: 'editor-mongo',
});
// 修改mysql连接配置
Object.assign(devConf.mysqlConf, {
host: 'editor-mysql',
});
2
3
4
5
6
7
8
9
宿主机连接 docker 中的 redis
使用 redis-cli 工具,连接到 docker-compose 中的 editor-redis 服务,向外暴露的端口号是 6378:
redis-cli -h 127.0.0.1 -p 6378
删除 none 镜像
docker image prune -a
遇到的问题
使用 Sequelize 同步数据表失败,关闭同步功能即可
服务启动顺序问题导致 mysql 连接失败,添加 depends_on 解决