Docker从入门到实践

Docker

Docker是什么?

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

为什么使用Docker?

这里我们先思考一下传统的项目部署有什么痛点?

  • 项目更新发布及部署低效,过程繁琐且需要人工介入,每次加机器都需要再重新搭环境
  • 环境一致性难以保证,多个服务器环境有可能还有差异
  • 不同环境之间迁移成本太高,例如:Windows迁移到Linux又需要重新再搭建环境
  • 使用虚拟机部署的话又太笨重,资源消耗大,不够轻量

再看看使用docker的优势

  • 轻量级:Docker容器只包含应用程序及其依赖项,相对于传统的虚拟机来说更加轻量级,可以更快地启动和停止。

  • 可移植性:Docker容器可以在不同的环境中运行,包括开发、测试和生产环境,而不需要担心环境差异导致的问题。

  • 一致性:Docker容器可以确保应用程序及其依赖项在不同的环境中运行时具有相同的行为,这可以避免由于环境差异导致的问题。

  • 隔离性:Docker容器可以隔离应用程序及其依赖项,避免它们之间的冲突,这可以提高应用程序的稳定性和安全性。

  • 可扩展性:Docker容器可以很容易地扩展,可以根据需要启动多个容器来处理更多的请求。

  • 开放性:Docker容器是开放的,可以在不同的平台上运行,这可以提高应用程序的可移植性和互操作性。

所以有了Docker可以很大程度解决上面的问题。

Docker的三个概念

  • 镜像(Image):类似于虚拟机中的镜像,是一个包含有文件系统的面向Docker引擎的只读模板。任何应用程序运行都需要环境,而镜像就是用来提供这种运行环境的。例如一个Ubuntu镜像就是一个包含Ubuntu操作系统环境的模板。

  • 容器(Container):类似于一个轻量级的沙盒,可以将其看作一个极简的Linux系统环境。Docker引擎利用容器来运行、隔离各个应用。容器是镜像创建的应用实例,可以创建、启动、停止、删除容器,各个容器之间是是相互隔离的,互不影响。注意:镜像本身是只读的,容器从镜像启动时,Docker在镜像的上层创建一个可写层,镜像本身不变。

  • 仓库(Repository):类似于代码仓库,这里是镜像仓库,是Docker用来集中存放镜像文件的地方。一般每个仓库存放一类镜像,每个镜像利用tag进行区分,比如Ubuntu仓库存放有多个版本(20.04、22.04等)的Ubuntu镜像。

docker常用命令

docker build

使用Dockerfile创建镜像

常用参数如下:

-t				# 为镜像指定一个名称和标签
-f				# 指定Dockerfile的路径和文件名
--no-cache			# 不使用缓存构建镜像
--build-arg		# 设置构建时的参数
--squash			# 将多个镜像层压缩成一个层,减小镜像大小
-m                		# 设置内存最大值
--rm              		# 构建镜像成功后删除中间容器
[root@VM-16-4-centos search-blog-api]# docker build --rm -t search-blog-api:latest .

docker run

创建并启动一个新的容器

常用参数如下:

-d					# 以后台模式运行容器
-it				# 以交互模式运行容器
--name  				# 为容器指定一个名称
-p					# 将容器内部的端口映射到宿主机的端口
-v					# 将宿主机的目录或文件挂载到容器内部
--rm				# 容器停止后自动删除
-e					# 设置环境变量
--network 				# 指定容器所在的网络
--link				# 将容器连接到另一个容器
[root@VM-16-4-centos search-blog-api]# docker run -d --restart always --name redis6 -p 6378:6379 -v /data/docker/redis6/data:/data redis:6.2.12 --requirepass 123456 --appendonly yes
6153bf26bb092dd74464ec697fe6df4e8b74a9e386b9ea3907ced8fd3e7c7b8b




[root@VM-16-4-centos search-blog-api]# docker run -d --restart=always -p 8000:80 -p 4433:443 --name nginx2 -v /data/docker/nginx2/nginx.conf:/etc/nginx/nginx.conf -v /data/docker/nginx2/conf.d/:/etc/nginx/conf.d nginx
e1046a12a7584e2bd03816633f9446a24f31fd90d8b120fbc286200db7162312

docker start/stop/restart/kill

启动/停止/重启/杀掉容器

[root@VM-16-4-centos search-blog-api]# docker start search-blog-api
search-blog-api

[root@VM-16-4-centos search-blog-api]# docker stop search-blog-api
search-blog-api
[root@VM-16-4-centos search-blog-api]# docker restart search-blog-api
search-blog-api
[root@VM-16-4-centos search-blog-api]# docker kill search-blog-api
search-blog-api

docker rm

删除容器,删除前必须先停止容器,可以一次性删除多个容器

[root@VM-16-4-centos search-blog-api]# docker stop nginx2 redis6
nginx2
redis6
[root@VM-16-4-centos search-blog-api]# docker rm nginx2 redis6
nginx2
redis6

docker exec

在运行的容器中执行命令

常用参数如下:

-i					# 以交互模式运行容器。
-t					# 为容器分配一个伪终端。
-d					# 在后台模式下运行容器。
--user				# 指定要执行命令的用户
[root@VM-16-4-centos search-blog-api]# docker exec -it search-blog-api /bin/sh -c "pwd && echo 'hello world'"
/var/www/search-blog-api
hello world
[root@VM-16-4-centos search-blog-api]# docker exec -it search-blog-api /bin/sh
/var/www/search-blog-api # pwd && echo 'hello world'
/var/www/search-blog-api
hello world
[root@VM-16-4-centos search-blog-api]# docker exec -it --user root  search-blog-api /bin/sh
/var/www/search-blog-api # whoami
root

docker ps

列出容器(正在运行)

常用参数如下:

-a				# 列出所有容器,包括已停止的容器。
-q				# 仅列出容器的 ID。
--filter			# 根据指定的条件过滤容器。
--format			# 指定输出格式。
[root@VM-16-4-centos search-blog-api]# docker ps -aq --no-trunc --format "{{.ID}} {{.Names}}"
2e99f53709204152466112e9d39289ae683fb51fae6579a2abc93f57fab920ae search-blog-api
0059d4f74e1fc7accf695e2686b812c9537a592b3decacd45cf4380de2c09279 chatgpt-next-web
75c26e4930f0b40c87f889d9bf26b9379ff191c3b02355f759926b67872256ff clash
2305014aa58247ff1e7f1d5cc6bc00a88a06fa80d998c485eed16f0cb0bc108b proxy-provider-converter
52cee28fb9f2ce5eb58480e8c71db670874ce062e6c6c48d518e082c8280a09b nginx
96accd461318a6f454fb2dc68ba0d028148f3042831738bfbedc632282fd1fa9 blog-springboot

docker logs

获取容器的日志

常用参数如下:

-f        		# 跟踪日志输出
-t        		# 显示时间戳
--tail    		# 只显示最新n条容器日志
--since   		# 显示某个开始时间的所有日志
[root@VM-16-4-centos search-blog-api]# docker logs -f search-blog-api 
Puma starting in single mode...
* Version 3.12.6 (ruby 2.6.3-p62), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: production
* Listening on tcp://0.0.0.0:8989
Use Ctrl-C to stop

docker cp

用于容器与物理主机之间拷贝文件

[root@VM-16-4-centos ~]# docker cp nginx:/etc/nginx/nginx.conf ./nginx.conf
[root@VM-16-4-centos ~]# ls nginx.conf 
nginx.conf

docker images

显示系统本地容器镜像文件

常用参数如下:

-a                	# 列出所有的镜像(含中间映像层,默认,过滤掉中间映像层);
--digests         	# 显示镜像的摘要信息;
-f                	# 显示满足条件的镜像;
--format          	# 指定返回值的模板文件;
--no-trunc        	# 显示完整的镜像信息;
-q                	# 只显示镜像ID。
[root@VM-16-4-centos ~]# docker images
REPOSITORY                                        TAG                IMAGE ID       CREATED             SIZE
search-blog-api                                   latest             fbb48dd23433   53 minutes ago      413MB
chatgpt-next-web                                  496                26df00c7c340   20 hours ago        244MB
chatgpt-next-web                                  493                57d3f1ac8673   2 days ago          244MB
node                                              18-alpine          9752a2a43933   6 days ago          175MB
redis                                             6.2.12             f2ed029e761a   2 weeks ago         113MB
dreamacro/clash-premium                           latest             914123588f21   5 weeks ago         32.7MB
ruby                                              2.6.3-alpine3.10   6ddb199f039f   3 years ago         51MB

docker rmi

删除镜像,可以一次性删除多个镜像

常用参数如下:

-f      	# 强制删除
[root@VM-16-4-centos ~]# docker rmi 4ce0e1527dc3 d357a69437f1 d357a69437f1
Deleted: sha256:4ce0e1527dc3deb927be29bc6467f262adc83a0b4786d7de5c41110fa7bc25f1
Deleted: sha256:847c1ad24118136696d4e9db3868c2edb8da31345ff6794a4c915411b8fb03f4
Deleted: sha256:eb0cee5fde822881866744ea907e1276695b956035ef343f67434549d056fe3d
Deleted: sha256:4e4feadd3db131a8a9d653d20d6cc6bd09455ee28d7469af4f14ba26fbdedb01
Deleted: sha256:875489dabca74ace35aaa4663e73b979400e9ddfcd36562606d19a80fac10bda
Deleted: sha256:f426caf54025e79fe35aac1ad2709ae2eaf23205ad4ef915916e9b965ad2839c
Deleted: sha256:5933523e0b7b2dc48e349bcfd411afded1782cb0d252fd7a05c8916186ac7538
Deleted: sha256:5fc1822846db2626e9ee686e7402bf889b972788f10457345b382efb72c43e22
Deleted: sha256:5eedf316a57768adc360fa32bf0d7f6f3d4184f6cd5c6af900128526a7d31cb2
Deleted: sha256:8e31a1f0276ef64656af038aa1f3c8adbe3b4315aa678c39fc0d6a80b4c49fc4
Deleted: sha256:a27895de8166be7c43f67b50163bfe0a92b9b9ece9e1ac42431d63a2eba37f6a
Deleted: sha256:d357a69437f1fff92f544dfec8ad0a088cfc40455b971533b214b90fe665359b
Deleted: sha256:2a58602bc572d084be3e9200ddd27deffbb94e4bf284e39d439b6b60aa244e1f
Deleted: sha256:2f3dd2d9ca0a7b6106ba281aedc109dbe3d401e36bec21602d3a1d16e33481cd
Deleted: sha256:5927c45e49500cbc58e900c620337a15960e8a2f471a322fd8b4e5f8328c034b
Deleted: sha256:63663f6d26cc538eb61cf48a250a98eaebc9f74bca0563daf23e66b47e929942

什么是Dockerfile?

Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。构建、运行一个container容器的过程可以粗略的分为三步:

  • 编写Dockerfile文件
  • 使用docker build命令以Dockerfile为基础构建image镜像
  • 使用docker run命令以image镜像为基础生成container容器

如图:

dockerfile.png

下面是一个Rails项目的Dockerfile文件,可以看看都做了什么

# 使用安装了最少的软件的镜像,也有使用 ruby:alpine
FROM ruby:2.6.3-alpine3.10






# 安装依赖
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update && apk add --no-cache vim tzdata mariadb-connector-c-dev
RUN apk add --no-cache --virtual .temp-build-libs \
    build-base gcc musl-dev

# 设置环境变量
ENV RAILS_ROOT /var/www/search-blog-api
ENV RAILS_ENV production
ENV HOST 0.0.0.0
ENV PORT 8989
ENV PIDFILE $RAILS_ROOT/tmp/pids/server.pid

# 设置容器里的工作目录
WORKDIR $RAILS_ROOT

# 创建 rails 程序目录和程序运行所需要的 pids 的目录
RUN mkdir -p $RAILS_ROOT/tmp/pids

# 将 Dockerfile 目录下所有内容复制到容器工作目录
# 包括 Gemfile 及 Gemfile.lock,当 Gemfile 没有改变时,省略下面的 bundle install
COPY . .

RUN pwd && ls -all

# 安装 Rails 环境
RUN bundle install

# 可执行权限
RUN chmod +x  $RAILS_ROOT/docker-entrypoint.sh

# 删除不需要的编译依赖
RUN apk del .temp-build-libs

# 暴露服务端口
EXPOSE 8989

# 运行 docker-entrypoint.sh
ENTRYPOINT ["./docker-entrypoint.sh"]

Dockerfile RUN,CMD,ENTRYPOINT命令区别

  • RUN 命令执行命令并创建新的镜像层,通常用于安装软件包,
  • CMD 命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换
  • ENTRYPOINT 配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)
CMD

CMD 指令允许用户指定容器的默认执行的命令。此命令会在容器启动且 docker run 没有指定其他命令时运行。下面是一个例子:

# Dockerfile

FROM ruby:2.6.3-alpine3.10






RUN echo "RUN hello world"


CMD echo "CMD hello world"
# 先build镜像,此时RUN命令会被执行:

[root@VM-16-4-centos search-blog-api]# docker build -f Dockerfile.cmd -t demo-cmd:lastest .
Sending build context to Docker daemon  269.8kB

Step 1/3 : FROM ruby:2.6.3-alpine3.10
 ---> 6ddb199f039f

Step 2/3 : RUN echo "RUN hello world"
 ---> Running in 6e797bb88ed1
RUN hello world
Removing intermediate container 6e797bb88ed1
 ---> 4ea84493be2d
Step 3/3 : CMD echo "CMD hello world"
 ---> Running in 27cc9c449cba
Removing intermediate container 27cc9c449cba
 ---> e44ba4e0de81
Successfully built e44ba4e0de81
Successfully tagged demo-cmd:lastest

# 运行容器 docker run -it [image] 将输出:
[root@VM-16-4-centos search-blog-api]# docker run -it demo-cmd:lastest 
CMD hello world


# 但当后面加上一个命令,比如 docker run -it [image] echo 'hello world' ,CMD 会被忽略掉,命令 echo 'hello world' 将被执行:
[root@VM-16-4-centos search-blog-api]# docker run -it demo-cmd:lastest echo 'hello world'
hello world

ENTRYPOINT

ENTRYPOINT 用于设置容器启动时要执行的命令及其参数,同时可通过CMD命令或者命令行参数提供额外的参数。ENTRYPOINT 中的参数始终会被使用,这是与CMD命令不同的一点。下面是一个例子:

# Dockerfile

FROM ruby:2.6.3-alpine3.10






RUN echo "hello world"


ENTRYPOINT ["/bin/echo", "hello"]

CMD ["world"]
# 先build镜像,此时RUN命令会被执行:

[root@VM-16-4-centos search-blog-api]# docker build -f Dockerfile.ent -t demo-ent:latest .
Sending build context to Docker daemon  269.8kB

Step 1/4 : FROM ruby:2.6.3-alpine3.10
 ---> 6ddb199f039f

Step 2/4 : RUN echo "hello world"
 ---> Running in 52a61e601c05
hello world
Removing intermediate container 52a61e601c05
 ---> 950e6b92abda
Step 3/4 : ENTRYPOINT ["/bin/echo", "hello"]
 ---> Running in 676cd9ee4f0a
Removing intermediate container 676cd9ee4f0a
 ---> 31b83657f33f
Step 4/4 : CMD ["world"]
 ---> Running in 100b533e37db
Removing intermediate container 100b533e37db
 ---> 5f3dac6c020d
Successfully built 5f3dac6c020d
Successfully tagged demo-ent:latest


# 当容器通过 docker run -it [image] 启动时,输出为:
[root@VM-16-4-centos search-blog-api]# docker run -it demo-ent:latest 
hello world


# 而如果通过 docker run -it [image] RCC 启动,则输出为:
[root@VM-16-4-centos search-blog-api]# docker run -it demo-ent:latest RCC
hello RCC

docker 网络模式

当安装Docker时,它会自动创建三个网络。我们可以使用以下docker network ls命令列出这些网络:

[root@VM-16-4-centos search-blog-api]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
0a183d7a6cda   bridge    bridge    local
79394185106a   host      host      local
0398973f575d   none      null      local

Docker内置这三个网络,运行容器时,我们可以使用该–network标志来指定容器应连接到哪些网络。

Docker有以下4种网络模式:

网络模式 简介
bridge 为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥,默认为该模式。
host 容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。
none 容器有独立的 Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,IP 等。
container 新创建的容器不会创建自己的网卡和配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。

docker优化镜像体积的技巧

  • 使用多阶段构建:使用多个 FROM 指令来构建镜像,每个阶段都可以使用不同的基础镜像和构建步骤。这样可以减少镜像的大小,因为最终镜像只包含必要的文件和依赖项。例子:gitlab.explorexd.com/devs/chatgp…

  • 删除不必要的文件:在构建镜像时,删除不必要的文件和目录,例如缓存文件、日志文件和临时文件等。

  • 使用 Alpine 镜像:Alpine 是一个轻量级的 Linux 发行版,它的镜像非常小,通常只有几十 MB。使用 Alpine 镜像可以减少镜像的大小。

  • 合并多个 RUN 指令:在 Dockerfile 中,每个 RUN 指令都会创建一个新的镜像层。因此,将多个 RUN 指令合并成一个可以减少镜像的大小。

  • 使用 .dockerignore 文件:在构建镜像时,使用 .dockerignore 文件来排除不必要的文件和目录,这样可以减少构建上下文的大小。

Docker-Compose

Docker-Compose是什么?

要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等,这些需要多个容器相互配合来完成。

Docker Compose 允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

为什么使用docker-compose?

使用 Docker Compose 有以下几个好处:

  • 简化应用程序的部署:使用 Docker Compose,我们可以轻松地定义和运行多个容器,而不必手动启动和配置每个容器。

  • 管理多个容器:Docker Compose 可以管理多个容器,并且可以在单个命令中启动、停止和重建整个应用程序。

  • 容器之间的链接和共享数据卷:Docker Compose 支持容器之间的链接和共享数据卷,使得容器之间的通信和数据共享变得更加容易。

  • 简化开发环境:使用 Docker Compose,我们可以轻松地在本地创建一个与生产环境相同的开发环境,从而简化了开发和测试过程。

详解docker-compose.yml

version: '3.9'
services:
  search-blog-api:
    container_name: search-blog-api # 容器名称
    image: search-blog-api:latest  # 镜像名称
    build: # 指定构建 Docker 镜像的配置
      context: ./ # 指定构建上下文的路径
      dockerfile: Dockerfile # 指定 Dockerfile 的路径
    networks: # 设置服务之间的网络连接
      - nginx
    restart: always # 定义服务的重启策略,no:不重启服务。always:服务总是重启;on-failure:只有在服务退出代码非零时才重启服务;unless-stopped:除非手动停止服务,否则服务总是重启。
    expose: # expose 只是将容器内部的端口暴露出来,而不会将它们映射到主机上。这意味着其他容器可以通过容器名称和端口号访问该容器的服务,但是外部主机无法直接访问该服务
      - 8989
    environment: # 用于设置容器的环境变量
      TZ: 'Asia/Shanghai'
    volumes: # 将主机上的目录或文件挂载到容器中
      - '/data/docker/search-blog-api/log:/var/www/search-blog-api/log'
  mysql:
    image: mysql:latest
    container_name: mysql
    networks:
      - nginx
    ports: # 将容器内部的端口映射到主机上的端口,以便外部可以访问容器中运行的应用程序
      - '3306:3306'
    restart: always
    env_file: # 从文件中读取环境变量并将其传递给容器
      - .env.mysql.db
  redis:
    image: redis:latest
    container_name: redis
    networks:
      - nginx
    ports:
      - '6379:6379'
    restart: always
networks: # 定义一个名为 nginx 的网络,并指定了其驱动为 bridge 。
  nginx:
    name: nginx
    driver: bridge

docker-compose常用命令

docker-compose up

启动所有或者某个容器

常用参数如下:

-d					# 在后台运行容器。
--build				# 构建镜像并启动容器。
--force-recreate			# 强制重新创建容器。
--no-recreate			# 不重新创建已经存在的容器。
--no-build				# 不构建镜像,直接启动容器。
--abort-on-container-exit		# 当容器退出时,停止所有容器。
--remove-orphans			# 删除孤立的容器。
--scale				# 指定服务的容器数量。
[root@VM-16-4-centos search-blog-api]# docker-compose up --build -d

[root@VM-16-4-centos search-blog-api]# docker-compose up  redis

docker-compose down

停止并删除所有或者某个容器

常用参数如下:

-v				# 删除容器相关的所有卷。
--rmi			# 删除所有相关的镜像。
--remove-orphans		# 删除孤立的容器。
--timeout			# 指定停止容器的超时时间。
[root@VM-16-4-centos search-blog-api]# docker-compose down --rmi all
Stopping search-blog-api ... done
Stopping mysql           ... done
Stopping redis           ... done
Removing search-blog-api ... done
Removing mysql           ... done
Removing redis           ... done

docker-compose ps

列出所有容器的状态

常用参数如下:

-q					# 只显示容器 ID。
--services				# 只显示服务名称。
--filter				# 根据条件过滤显示的容器。
[root@VM-16-4-centos search-blog-api]# docker-compose ps --services
search-blog-api

mysql
redis

docker-compose logs

查看所有容器或者某个容器的日志

常用参数如下:

-f					# 实时跟踪日志输出。
--tail				# 仅显示最后指定数量的日志行。
--timestamps			# 显示日志输出的时间戳。
--no-color				# 禁用日志输出的颜色。
[root@VM-16-4-centos search-blog-api]# docker-compose logs -f search-blog-api
Attaching to search-blog-api
search-blog-api    | Puma starting in single mode...
search-blog-api    | * Version 3.12.6 (ruby 2.6.3-p62), codename: Llamas in Pajamas
search-blog-api    | * Min threads: 5, max threads: 5
search-blog-api    | * Environment: production
search-blog-api    | * Listening on tcp://0.0.0.0:8989
search-blog-api    | Use Ctrl-C to stop

docker-compose build

构建所有容器的镜像

--no-cache				# 禁用缓存,强制重新构建镜像。
--pull				# 在构建镜像之前,先拉取最新的基础镜像。
--parallel				# 并行构建多个服务镜像。
[root@VM-16-4-centos search-blog-api]# docker-compose build
mysql uses an image, skipping
redis uses an image, skipping
Building search-blog-api
Sending build context to Docker daemon  286.7kB

Step 1/18 : FROM ruby:2.6.3-alpine3.10
 ---> 6ddb199f039f
Step 2/18 : RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
 ---> Using cache
 ---> 7a2ce267c778
Step 3/18 : RUN apk update && apk add --no-cache vim tzdata mariadb-connector-c-dev
 ---> Using cache
 ---> a4a59cceffcd
Step 4/18 : RUN apk add --no-cache --virtual .temp-build-libs     build-base gcc musl-dev
 ---> Using cache
 ---> e8f19a4d741a
Step 5/18 : ENV RAILS_ROOT /var/www/search-blog-api
 ---> Using cache
 ---> 3b64cdef2323
Step 6/18 : ENV RAILS_ENV production
 ---> Using cache
 ---> 284c1d71c30c
Step 7/18 : ENV HOST 0.0.0.0
 ---> Using cache
 ---> fe4e69d8969a
Step 8/18 : ENV PORT 8989
 ---> Using cache
 ---> 7f0f0e955d07
Step 9/18 : ENV PIDFILE $RAILS_ROOT/tmp/pids/server.pid
 ---> Using cache
 ---> af5835d359f0
Step 10/18 : WORKDIR $RAILS_ROOT
 ---> Using cache
 ---> e3c69a6905cd
Step 11/18 : RUN mkdir -p $RAILS_ROOT/tmp/pids
 ---> Using cache
 ---> 26b4fff07caa
Step 12/18 : COPY . .
 ---> Using cache
 ---> 88a83516af1b
Step 13/18 : RUN pwd && ls -all
 ---> Using cache
 ---> 9c82786f9417
Step 14/18 : RUN bundle install
 ---> Using cache
 ---> 98ba1ed02626
Step 15/18 : RUN chmod +x  $RAILS_ROOT/docker-entrypoint.sh
 ---> Using cache
 ---> 147463a21366
Step 16/18 : RUN apk del .temp-build-libs
 ---> Using cache
 ---> 61b82717b5c3
Step 17/18 : EXPOSE 8989
 ---> Using cache
 ---> 4db764d0f6ba
Step 18/18 : ENTRYPOINT ["./docker-entrypoint.sh"]
 ---> Using cache
 ---> 12c9d131856f
Successfully built 12c9d131856f
Successfully tagged search-blog-api:latest

分享一下自己积累的docker-compose配置

github.com/jiaxudonggi…

参考文档

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYISnPkx' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片