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,还可以上传自己的镜像文件。

image

安装

去官网下载,安装。

安装完记得镜像加速,搜索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
1

-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
1

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
1
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 .
1

.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
1

验证 Docker Compose 是否已成功安装:

docker-compose --version
1

配置文件

  • 配置 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:
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
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 即可连接容器中的数据库
1
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 # 设置时区
1
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
}
1
2
3
4
// 修改mongodb连接配置
Object.assign(devConf.mongodbConf, {
  host: 'editor-mongo',
});

// 修改mysql连接配置
Object.assign(devConf.mysqlConf, {
  host: 'editor-mysql',
});
1
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
1

删除 none 镜像

docker image prune -a
1

遇到的问题

  • 使用 Sequelize 同步数据表失败,关闭同步功能即可

  • 服务启动顺序问题导致 mysql 连接失败,添加 depends_on 解决

Last Updated: 2023/5/9 10:43:56
Contributors: licong96