文章摘要
GPT 4
此内容根据文章生成,仅用于文章内容的解释与总结
投诉

Docker 是什么

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

docker 三个重要概念

1. Dockerfile

这是一个文本文件,包含了一系列的指令,用于描述如何构建一个镜像。可以使用 docker build 命令根据 Dockerfile 中的指令逐步构建镜像。

2. Image/镜像

一、概念

Docker 镜像可以看作是一个包含了运行特定软件所需的所有文件和配置的静态文件包。它就像是一个软件的安装包,但更加轻量级和灵活。

一个镜像通常由以下几个部分组成:

  1. 基础操作系统层:可以基于常见的 Linux 发行版,如 Ubuntu、CentOS 等。

  2. 应用程序及其依赖:包括应用程序的二进制文件、库文件、配置文件等。

  3. 元数据:描述镜像的信息,如作者、版本号、标签等。

二、原理:

  1. 分层存储

• Docker 镜像采用分层存储的方式,每个镜像都是由一系列的层组成。当构建一个镜像时,Docker 会按照一定的规则将每个变化的部分作为一个新的层进行存储。这样做的好处是可以重复利用已有的层,提高存储和传输效率。

• 例如,如果多个镜像都基于相同的基础操作系统,那么它们可以共享这个操作系统层,而不必在每个镜像中都重复存储。

  1. 联合文件系统(Union File System)

• Docker 使用联合文件系统将这些层组合成一个统一的文件系统,呈现给容器使用。当容器启动时,Docker 会将镜像的各个层挂载到一个联合挂载点上,形成一个完整的文件系统。

• 容器在运行过程中对文件系统的修改只会发生在最上层的可写层,而不会影响到镜像的其他层。这样可以保证镜像的不可变性,同时也方便了镜像的分发和版本管理。

  1. 镜像构建

• 可以通过两种主要方式构建 Docker 镜像:

Dockerfile:这是一个文本文件,包含了一系列的指令,用于描述如何构建一个镜像。可以使用 docker build 命令根据 Dockerfile 中的指令逐步构建镜像。

• 基于已有镜像进行修改:可以使用 docker commit 命令将一个正在运行的容器的状态保存为一个新的镜像。这种方式比较简单,但不太适合复杂的镜像构建场景。

  1. 镜像仓库

• Docker 镜像可以存储在镜像仓库中,方便分发和共享。常见的镜像仓库有 Docker Hub、私有仓库等。

• 用户可以从镜像仓库中拉取所需的镜像到本地,也可以将自己构建的镜像推送到镜像仓库中供其他人使用。

Docker 镜像包含可执行的应用源代码,以及在将应用代码作为容器运行时所需的所有工具、库和依赖项。 运行 Docker 镜像时,它会成为容器的一个(或多个)实例。 例如一个 Java APP必须在JDK环境中运行,所以 JDK 将作为构建 Java APP镜像的的基础镜像。

3. Container/容器

通过运行镜像而产生。一个镜像可以产生多个容器实例。容器是通过 Linux 内核中内置的过程隔离和虚拟化功能来实现的。容器技术可提供虚拟机的所有功能和优势,包括应用隔离、经济高效的可扩展性和可处置性,以及其他重要的优势:

  • 更轻巧:与虚拟机不同,容器不会承载整个操作系统实例和系统管理程序的有效负载。 它们仅包括执行代码所需的操作系统进程和依赖项。 容器大小以兆字节为单位(某些虚拟机则是以G 为单位)来衡量,因此它们可以更好地利用硬件容量,启动速度也更快。

  • 提高了开发人员的工作效率:容器化应用可以“一次编写,随处运行”。 与虚拟机相比,容器的部署、配置和重启过程更迅速且更简单。 这使得容器非常适合在持续集成持续交付 (CI/CD) 管道中使用,并且更适合采取敏捷和 DevOps 实践的开发团队。

  • 提高了资源利用率:开发人员使用容器在硬件上运行的应用副本数量是使用虚拟机的数倍。 这可以减少云支出。

Docker Hub

Docker Hub 是Docker 镜像的公共存储库,是“世界上最大的容器镜像库和社区”。 它存储超过 10 万个容器映像,来源于商业软件供应商、开源项目和开发者个人。

Docker Compose

开发人员可以使用 Docker Compose 来管理多容器应用,其中所有容器都在同一 Docker 主机上运行。 Docker Compose 会创建一个 YAML (.YML) 文件来指定应用中要包含的服务,并且可以使用单个命令来部署和运行容器。 由于 YAML 语法与语言无关,因此 YAML 文件可用于用 Java、Python、Ruby 和许多其他语言编写的程序。

开发人员还可以使用 Docker Compose 来定义用于存储的持久卷、指定基本节点,以及记录和配置服务依赖项。

一、docker命令

1.1 镜像相关命令

官方镜像仓库 Docker Hub: https://www.docker.com/products/docker-hub/

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
# 获取镜像 (下载)
docker pull IAMGE_NAME

# 官方pull
docker pull IAMGE_NAME:VERSION(没有指定版本,默认会下载最新版)

# 查看镜像列表
docker images
docker image ls

# 删除单个镜像,如:docker image rm mysql:latest
docker image rm IAMGE_NAME:VERSION
#
docker image rm 578c3(镜像 ID)

# 删除所有镜像
docker image rm ${docker images -q}

# 搜索镜像
docker search 镜像名字

# 创建镜像, 点号表示使用当前目录下的 Dockerfile 构建镜像,-t 指定镜像的tag
docker build -t <image-name> . *(点一定不能去掉)

# 显示一个镜像的历史
docker history image_name

# 导出镜像
docker image save centos > docker-centos6.9.tar.gz

# 导入镜像
docker image load -i docker-centos6.9.tar.gz

# 给源中镜像打标签
docker tag nginx:latest 10.0.0.11:80/nginx:latest

# 推送指定镜像到docker镜像源服务器
docker push 10.0.0.11:80/nginx:latest

1.2容器相关命令

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 查看版本
docker -v

# 查看docker信息
docker info

# 查看docker信息,如:docker search mysql
docker search IMAGE_NAME

# 运行容器,--name 指定容器名称
docker run --name 容器名 -d -p 3306:3306 mysql

# 运行容器
docker run -d -p 80:80 nginx:latest
# run(创建并运行一个容器)没有指定容器名时会自动分配容器名,
# --name可指定容器名
# -d 放在后台
# -p 端口映射,宿主机端口:docker容器端口
# -P (大写)随机分配端口
# -v 挂载目录卷,宿主机路径: 容器目标路径
# --rm 将会在容器停止时自动删除容器; 不能与 -d 选项一起使用

#运行容器后命令行窗口进入到容器的 bash 终端
docker run -it --name centos6 centos:6.9 /bin/bash
# -it 分配交互式的终端
# /bin/sh 覆盖容器的初始命令

# 修改容器名
docker rename OLD_CONTAINER_NAME NEW_CONTAINER_NAME

# 启动容器
docker run IMAGE_NAME

# 停止所有容器
docker stop $(docker ps -aq)

# 删除所有容器
docker rm $(docker ps -aq)
docker rm -f 'docker ps -a -q'

# 查看容器列表,-a查看所有容器; 加上-f status-exited查看停止的容器
docker ps (-a -l -q)
docker ps -a

# 进入容器bash终端,CONTAINER_ID 容器ID
docker exec -it CONTAINER_ID /bin/bash
# 进入容器后,在容器中安装 ping 命令来测试跟其它容器是否连通
>apt-get install -yqq inetutils-ping

# 开启|停止|重启|杀死 指定id的容器或者容器名称的容器
docker start|stop|restart|kill CONTAINER_ID|CONTAINER_NAME

# 运行容器,-v 为挂载的目录卷,宿主路径:容器路径
docker run -d -p 80:80 \
-v /opt/docker/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /opt/docker/nginx/conf.d:/etc/nginx/conf.d \
-v /opt/docker/nginx/logs:/var/log/nginx \
-v /opt/docker/nginx/html:/usr/share/nginx/html nginx:latest

# 查看容器日志
docker logs CONTAINER_ID||CONTAINER_NAME

# 查看容器状态
docker ps | grep ${CONTAINER_ID}

# 容器保存为镜像 (保存对容器的修改)
docker commit CONTAINER_ID NEW_IMAGE_NAME
docker commit -m="提交的描述信息" -a="作者" 容器id 新创建的目标镜像名:[标签名]
# 镜像备份为tar文件
docker save -o 备份后镜像名称.tar 原镜像名称

# 查看容器内部详情细节
docker inspect CONTAINER_ID|CONTAINER_NAME

# 查看容器文件的变化,显示表示 A:新建的文件,C:修改的文件,D:删除的文件, 如:docker diff nginx
docker diff CONTAINER_ID

# 登录
docker login

示例:

  1. 运行 microservice-eureka-server 镜像,版本 0.0.1
1
docker run -d -p 8761:8761 --name microservice-eureka-server --net staticnet  microservice-eureka-server:0.0.1
  • -p 8761:8761:宿主机端口:容器端口,将本地端口映射为容器指定的端口,可根据实际情修改。

  • –name microservice-eureka-server:为运行的容器指定名称。

  • –net staticnet:运行的容器使用 docker中自定义创建的固定 ip地址,默认 docker 容器使用的 bridge 桥接模式以宿主机连接,所以每次docker容器重启时会按照顺序获取对应ip地址,这就导致容器每次重启,ip都发生变化。

  1. 运行 redis 时指定密码:

    1
    docker run -d --name MyRedis -p 6379:6379 redis --requirepass "myredis"
  • –requirepass:redis的密码

1.3 网络管理

docker安装后,默认会创建三种网络类型,bridgehostnone,可通过如下命令查看

1
sudo docker network ls
  • bridge: 网络桥接
    默认情况下启动、创建容器都是用该模式,所以每次docker容器重启时会按照顺序获取对应ip地址,这就导致容器每次重启,ip都发生变化。

  • host:主机网络
    docker容器的网络会附属在主机上,两者是互通的。

  • none:无指定网络
    启动容器时,可以通过–network=none, docker容器不会分配局域网ip

创建固定ip容器

  1. 创建自定义网络类型,并且指定网段

    1
    sudo docker network create --subnet=192.168.0.0/16 staticnet

    通过docker network ls 可以查看到网络类型中多了一个staticnet

  2. 使用新的网络类型创建并启动容器

    1
    2
    3
    4
    5
    6
    docker run -d -p 9000:9000 \
    --restart=always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    --name portainer \
    --net staticnet \
    --ip 192.168.0.100 portainer/portainer

    通过docker inspect可以查看容器ip为192.168.0.2,关闭容器并重启,发现容器ip并未发生改变

二、容器化前端项目

为了方便管理 docker 减少命令行的使用,可以安装portainer 容器。

1
2
3
4
5
6
7
8
9
10
# 拉取镜像
docker pull portainer/portainer

# 创建数据卷
docker volume create portainer_data

# 运行 Portainer 容器
docker run -d -p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data portainer/portainer

Portainer 安装参考:https://cloud.tencent.com/developer/article/1866869

  1. 构建前端项目镜像

    先构建前端项目产生的dist目录,如果项目中使用到的图片等先复制到dist目录中。在项目根目录下新建 Dockerfile 文件,参考前端项目中引用的地址来放,Dockerfile 文件内容如下:

1
2
3
4
# 基于nginx镜像来构建
FROM nginx
# 复制dist目录中的所有文件和目录到nginx容器的的 html目录(Web根目录)
COPY ./dist/ /usr/share/nginx/html
  1. Dockerfile 文件所在目录下依次执行以下命令
1
2
3
4
5
# 构建镜像,镜像文件名:mynginx  版本:1.0
docker build -t my_nginx:1.0 .

# 运行容器,--name 指定容器名称,-d: 以后台方式运行镜像;-p: 端口映射
docker run --name my_nginx -d -p 8000:80 my_nginx:1.0

三、容器化后端项目

2.1 在 docker 中安装 Mysql

安装 Mysql 8.0

在命令行中执行以下命令:

1
2
3
4
5
6
# 1.下载最新的 mysql镜像
docker pull mysql

# 2.创建容器并运行
# -e 覆盖构建镜像是 Dockerfile 中的环境变量值;
docker run --name mysql8 -p 13306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:latest

然后使用navicat 连接 docker 中的 mysql 测试是否可用。

主机:localhost

端口:13306

springboot 应用yml 文件配置内容大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
spring:
# 配置jdbc数据源
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
# mysql8:13306 为容器名称:端口号;如果不行就改成 mysql容器网络IP:3306
url: jdbc:mysql://mysql8:3306/renting?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC
username: root
password: root
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 1
maximum-pool-size: 5
auto-commit: true
idle-timeout: 30000
pool-name: RentingHikariCP
max-lifetime: 1800000
connection-timeout: 30000
connection-test-query: SELECT 1
......

yml文件解析:

mysql:端口号前的 mysql8 是 mysql数据库 docker 容器名称: mysql8,此处注意,稍后使用命令启动 sp ringboot 应用容器时连接 到 mysql8容器名要和此处一致。启动 mysql 容器请参考 2.1 节部分。

安装 Mysql 5.7

  • 在本地创建 mysql 的映射目录 ( macOS ),不同系统路径自行修改
1
2
3
4
mkdir -p /Users/jamesmac/dev/docker/mysql5/data /Users/jamesmac/dev/docker/mysql5/logs /Users/jamesmac/dev/docker/mysql5/conf

#添加访问对目录的访问权限
chmod 777 /Users/jamesmac/dev/docker/mysql5
  • 下载镜像
1
2
# 下载镜像
docker pull mysql:5.7.39
  • 运行容器

    使用下载的镜像运行来创建容器。

1
2
3
4
5
6
7
# --name指定容器名字 -v挂载目录卷 -p指定端口映射  -e设置(覆盖)mysql参数 -d后台运行  \表示命令换行
sudo docker run -p 23306:3306 --name mysql5 \
-v /Users/jamesmac/dev/docker/mysql5/logs:/var/log/mysql \
-v /Users/jamesmac/dev/docker/mysql5/data:/var/lib/mysql \
-v /Users/jamesmac/dev/docker/mysql5/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7.39

2.2 Dockerfile 文件构建 docker 镜像

Dockerfile 命令

是一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像

常用命令

  • FROM 镜像名称:标签:定义了使用哪个基础镜像启动构建流程
  • MAINTAINER 名字:声明镜像的创建者
  • ENV key value:设置环境变量,使用*$VAR_NAME 或 ${VAR_NAME}* 的语法引用变量名。
  • ARG key=value: 也称为构建时变量。仅在构建Docker映像期间(RUN等)可用,而在创建映像(ENTRYPOINT,CMD)之后不可用。
  • RUN command:在创建镜像时使用;是Docker的核心部分(可以写多条)
  • ADD 宿主机文件 容器目录文件 :将宿主机的文件复制到容器中, 如果是一个压缩文件将会在复制后自动解压。
  • COPY 宿主机文件 容器目录文件:和ADD相似,但如果有压缩文件不能解
  • WORKDIR 目录名称:设置工作目录,此后的命令在此目录位置下执行
  • EXPOSE port :暴露的端口号
  • ENTRYPOINT [command…]: 容器启动时执行的命令
  • CMD [command…]: 与 ENTRYPOINT 相似

构建 docker 镜像

  1. 首先编译项目,在target目录中生成:spring-security-jwt-1.0.jar

  2. 在项目根目录下编写 Dockerfile 文件(无扩展名),与 pom.xml 位置相同,Dockerfile 内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 基础镜像
    FROM openjdk:8-jdk-alpine
    # 维护者
    MAINTAINER JAMESZHANG
    # 定义容器挂载的卷标
    VOLUME /tmp
    # 声明环境变量;ARG 也是声明环境变量
    # ARG JAR_FILE=target/spring-security-jwt-1.0.jar
    ENV JAR_FILE target/spring-security-jwt-1.0.jar
    # 复制 jar 文件到 docker 系统中
    COPY ${JAR_FILE} .
    # 在构建镜像过程中要运行的命令,格式:RUN <command>
    #RUN
    # 暴露的端口号
    EXPOSE 8080
    # 容器启动时执行的命令
    ENTRYPOINT ["java","-jar","/spring-security-jwt-1.0.jar"]
  3. 命令执行Dockerfile 构建docker 镜像

1
docker build -t spring-security-jwt-docker:1.0 .

​ 构建镜像时可以使用–build-arg 来设置 ARG 的值

2.3 通过 maven 插件方式构建docker 镜像

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
<properties>
<java.version>1.8</java.version>
<!-- 镜像前缀-->
<docker.image.prefix>spring-security-jwt</docker.image.prefix>
</properties>
......
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<!-- 镜像名称-->
<imageName>${docker.image.prefix}-docker:1.0</imageName>
<!-- maven内部变量,Dockerfile 文件所在位置 -->
<dockerDirectory>${project.basedir}</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<!-- maven内部变量,项目编译目录:target -->
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
  • 运行 docker 容器
1
2
3
4
5
docker run \
--rm --name spring-security-jwt \
--link mysql8:mysql8 \
-d -p 8888:8080 \
spring-security-jwt-docker:1.0

注意: 可以加多个--link 来链接多个容器,如:--link mysql8:mysql8 --link redisdb:redisdb

命令解析:

  • --rm (可选项)停止容器时自动删除容器实例。
  • -p 端口映射,宿主机的 8888 端口映射到容器的8080 端口,即访问宿主机的 8888端口就是访问容器的 8080 端口。
  • --name 运行时的容器名称。
  • --link 链接容器。mysql8:mysql8 第一个参数mysql 为 docker 镜像名称,第二个参数 mysql8 为别名,此处和yml文件中连接 mysql 的地址保持一致。spring-security-jwt-docker:1.0 这个为我们刚刚build的 docker 镜像名称。注意上面 yml 文件中连接数据库的 url 使用的就是这里的 mysql 名称。因为容器默认使用的网络模式是桥接方式,这样容器每次重启后ip地址会改变,不方便迁移,除非使用固定的ip,link机制方便了容器去发现其它的容器并且可以安全的传递一些连接信息给其它的容器。

2.4 nginx + springboot

以下两种方案两选一。

方案 1:镜像包含前端资源文件

这种方案需要把前端应用文件包含到新的 docker 镜像文件( nginx + 前端资源 )里

步骤:

(1)编写 Dockerfile

1
2
FROM nginx
COPY ./dist/ /usr/share/nginx/html

然后先把此容器临时运行起来,接着需要复制容器中的的 nginx 配置文件出来修改,目的是拿到nginx 的配置文件来用

1
2
3
4
5
# 构建 Image
docker build -t my_nginx:latest .

# 临时运行容器,--rm 表示停止容器自动删除容器实例
docker run --rm -itd -p 8000:80 --name my_nginx my_nginx:latest

(2)复制容器相关配置文件到宿主机目录

​ 首先在宿主机中创建 /Users/jamesmac/dev/docker/nginx 目录(位置自行更改),并且配置的时候要配置上绝对路径

1
2
3
4
5
6
7
8
# 新建目录 docker/nginx,位置自行更改
mkdir -p /Users/jamesmac/dev/docker/nginx

# 复制名称为my_nginx容器中/etc/nginx/nginx.conf文件到宿主机的~/dev/docker/nginx路径下
docker cp my_nginx:/etc/nginx/nginx.conf /Users/jamesmac/dev/docker/nginx

# 复制名称为my_nginx容器中/etc/nginx/conf.d 目录到宿主机的 ~/dev/docker/nginx 路径下
docker cp my_nginx:/etc/nginx/conf.d /Users/jamesmac/dev/docker/nginx

(3) 修改宿主机 /Users/jamesmac/dev/docker/nginx/conf.d/default.conf 配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
......

# 增加反向代理配置
location /qunar/ {
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE';
proxy_set_header Cookie $http_cookie;
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#反向代理至 springboot 容器 IP 地址:端口号
proxy_pass http://172.17.0.6:8088/;
}
}

前端页面请求如下:

1
2
#springboot控制器方法映射:@GetMapping("/api/recommends")
axios.get(`/qunar/api/recommends`)

(4)删除刚刚临时启动的 Nginx 容器

1
2
3
4
# 停止容器
docker stop my_nginx
# 删除容器
docker rm my_nginx

(5)修改改nginx配置后重新构建 docker 镜像 和 运行容器

1
2
3
4
5
6
7
8
9
# 构建 docker 镜像,注意最后的一个点号,表示 Dockerfile文件所在当前位置
docker build -t my_nginx:latest .

# 运行容器,-v 卷(volume)挂载,宿主机挂载目录:容器目录
docker run -itd -p 8000:80 --name my_nginx \
-v /Users/jamesmac/dev/docker/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /Users/jamesmac/dev/docker/nginx/conf.d:/etc/nginx/conf.d \
-v /Users/jamesmac/dev/docker/nginx/logs:/var/log/nginx \
--privileged=true my_nginx:latest

命令解析:

  • -p 8000:80:将容器的 80 端口映射到主机的 8000 端口;
  • -v /Users/jamesmac/dev/docker/nginx/nginx.conf:/etc/nginx/nginx.conf:将容器中的 /etc/nginx/nginx.conf 文件挂载到宿主机中的 /Users/jamesmac/dev/docker/nginx/nginx.conf 文件;
  • -v /Users/jamesmac/dev/docker/nginx/conf.d:/etc/nginx/conf.d:将容器中 /etc/nginx/conf.d 目录挂载到宿主机中的 /Users/jamesmac/dev/docker/nginx/conf.d 目录下;
  • -v /Users/jamesmac/dev/docker/nginx/logs:/var/log/nginx:将容器中的 /var/log/nginx 目录挂载到宿主机中的 /Users/jamesmac/dev/docker/nginx/logs 目录下, 用于方便查看 Nginx 日志;

方案 2(推荐): 把前端资源文件放到宿主机挂载的目录中

这种方案不需把前端应用的文件构建到新的 docker 镜像中,只需把文件放到宿主机挂载的目录中

步骤:

(1)下载 nginx 镜像 并运行容器

1
2
3
docker pull nginx
# 注意这里直接使用 nginx 镜像来运行容器
docker run --rm -itd -p 8000:80 --name my_nginx nginx:latest

(2)和方案 1 的步骤2、3相同,第 4 步容器停了会自动删除容器

(3)复制编译出来的前端文件,dist 目录下的所有文件到宿主机 /Users/jamesmac/dev/docker/nginx/html目录中

(4)运行容器,如下:

1
2
3
4
5
6
docker run -itd -p 8000:80 --name my_nginx \
-v /Users/jamesmac/dev/docker/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /Users/jamesmac/dev/docker/nginx/conf.d:/etc/nginx/conf.d \
-v /Users/jamesmac/dev/docker/nginx/logs:/var/log/nginx \
-v /Users/jamesmac/dev/docker/nginx/html:/usr/share/nginx/html \
--privileged=true my_nginx:latest

命令选项解析:

这里比前面多了一个容器卷挂载

  • -v /Users/jamesmac/dev/docker/nginx/html:/usr/share/nginx/html:将容器中的 /usr/share/nginx/html 目录挂载到宿主机中的 /Users/jamesmac/dev/docker/nginx/html 目录下;
  • -v /Users/jamesmac/dev/docker/nginx/logs:/var/log/nginx:将容器中的 /var/log/nginx 目录挂载到宿主机中的 /Users/jamesmac/dev/docker/nginx/logs 目录下, 用以方便查看 Nginx 日志;

浏览器访问容器中的nginx:http://localhost:8000/#/

四、安装可视化管理容器: portainer

portainer是一个可以通过网页来对 docker 中的镜像、容器、卷等进行管理的可视化工具。减少命令行的使用管理 docker 更加高效。

  • 下载镜像

    1
    docker pull portainer/portainer:latest
  • 运行

    1
    docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock --restart=always --name prtainer portainer/portainer

完成之后浏览器访问localhost:9000,登录默认用户名/密码: admin / portioner