让我们尝试将网络应用程序docker化
首先
我将解释如何使用Docker、Dockerfile和docker-compose来将在主机上创建的Rails应用程序容器化。
关于Docker
仮想化ツールの一つで、昨今で最も聞く名前ではないでしょうか。
なぜここまでDockerと聞くように(デファクトスタンダードに)なったかというと、自分が使ってみての所感だとやはり、
-
- 軽い
-
- 早い
- 環境を人に渡しやすい
在这一带吧。
実務はオフライン環境下でして…
どちらも使用するのですが、zip等に圧縮して渡すにしても全くもってサイズが違うので取られる時間が段違いです。
当被问及「为什么存在这些差异?」时,我认为其中最主要的是是否包含核心组件。
好的,本文只是为了解释Docker化的步骤,简要介绍到这里,现在我们立即进入步骤。
Dockerfileを書こう
dockerを使おうという人は、既に耳にしているだろう単語ですが、実際のところ何が書かれているのでしょうか?
ざっくり一言でまとめると、「コンテナの中で何をするのか」が書かれていると言えると思います。
ひとまず、作成したDockerfileを例に見てみましょう。
# 初めに元となるDocker Imageを指定しています
FROM ruby:3.2.2
# コンテナ内でコマンドを実行して諸々インストールしています
RUN apt-get update && \
apt-get install -y \
build-essential \
libpq-dev \
nodejs \
postgresql-client
# 今回はすでに手元にあるアプリをDocker化するので、コンテナ内に全てコピーします
COPY . /rails-docker
# 環境変数を設定しています
ENV APP_HOME /rails-docker
# 作業ディレクトリを指定しています
WORKDIR $APP_HOME
# 作業ディレクトリでコマンド実行されます
RUN bundle install
我們在每一行的註釋中簡單地描述了各個行業的操作內容。
每個指令前都有一個固定的大寫命令呢。
讓我們挑幾個來看看。
常出现在Dockerfile中的指令
请注意,我们不提供其他指令的支持,请自行查询如有兴趣。
需要注意的重点
基本的にDockerfileの先頭にはFROMを記述する。
RUN、COPY、ADDは新しいレイヤーを作成する。
悪戯にレイヤーが作成されていくと、イメージの肥大化やビルド時間の増加などの不都合が起きる。
最終的にはコマンドをまとめるなどして、これらの命令は少なく記述できると良い。
Dockerfileの作成で試行錯誤の間はCacheを上手く使う。
1回目のビルド
RUN hoge
2回目のビルド
RUN hoge # 1回目のビルド済み
RUN fuga
レイヤーが増えることになりますが、このように書くことで2回目のビルド時はRUN hogeはcacheが使用されるので短い時間で済みます。
最終的には一行にまとめる
RUN hoge && fuga
ENVでの環境変数設定は、元々存在する環境変数と同名を使うと意図せず上書きされてしまう可能性があることを頭に入れておく。
WORKDIRで最後に指定した場所がコンテナに入った時の初期位置になる。
我认为,牢记这个范围,然后编写Dockerfile会很有帮助。
让我们从创建的Dockerfile文件中生成镜像吧。
我认为通过学习到目前为止所提供的Dockerfile示例以及各个命令的含义,我们应该能够尝试制作一些简单的东西。
那么我们创建的Dockerfile应该如何使用呢?
我们要开始解释要使用的命令。先前的命令概述简单提到了构建(build)一词。
docker build 命令
docker build {-t [image_name] { : [tag_name] }} {-f [Dockerfile path]} [Dockerfile Directory]
{}は省略可、[]は必須として見てください。
{}の中に[]があるのは、省略部を書くならこれは必須ですよということですね。
-tから始まるオプション部分を省略すると、イメージ名、タグ名は付けられずNoneとなります。
さて、よく見るとDockerfileのあるディレクトリを書くだけで、どれをビルドしろと言った記述はないですね。
このコマンドは、指定したディレクトリ内でDockerfileというファイル名を探してビルドします。
ちょっと管理しにくいですよね。
-f [Dockerfile Path]のオプションを付けることで、DockerfileのあるディレクトリのどのDockerfileを使うか指定できます。
これで、Dockerfileという名前の縛りからも解放されるわけですね。
我还有一些必须知道的事情。
了解建立背景
COPYやADDなどを行う際のファイルやディレクトリはBuild Contextに含まれている必要があります。(不足しているとエラーになります)
Build Contextとは、先ほど解説したdocker buildコマンドを実行した際のカレントディレクトリになります。

另外还有
-fオプションを利用することでコンテキスト外のDockerfileを参照することが可能
この時、指定したDockerfileに記述する相対パスは、そのDockerfileのディレクトリが基準
絶対パスで指定することでBuild Context外のファイルへアクセスすることも可能
我认为了解这一点会很有益。
请尝试使用已创建的映像来创建容器。
到目前为止,我已经完成了一个想法。
接下来,让我们根据这个想法创建一个容器。
我会使用docker run命令。
我将介绍一些常用选项。
在实际操作时,根据您想要实现的目标,还有许多其他选项。请查找并了解相关信息。
例如,以下是使用的一个示例。
docker run {-it} {--rm} {--name [コンテナ名]} {-v [host dir:container dir]} ¥
{-p [host port:container port]} [image]
当你使用docker run命令创建容器后,为了确认,请使用docker ps命令来查看当前容器列表。
由于使用的命令选项和镜像不同,有时可能会启动并执行容器,然后立即停止,所以请加上-a选项,无论容器的状态如何都将其显示在列表中。
创建了一个 Dockerfile,并利用它构建了一个镜像,然后从这个镜像中创建了一个容器。
然而,你可能会对这个docker run命令有所感觉。
「每次都加上选项然后输入指令,会很长,也容易出错,而且很麻烦不是吗?」
Docker最初本来是一个方便部署环境的工具,但如果步骤过于复杂,那就会失去这一优势了。
为了方便使用,写一个docker-compose.yml文件。
假设我们已经确定了创建的镜像的用途,并且通过容器启动选项确定了各种设置。我们希望将这些设置写在某个地方,并通过简短的命令使任何人都能轻松地创建相同的状态。
要做到这一点,我们需要创建一个docker-compose.yml文件,并在其中写入内容。
现在,我将立即解释并展示我这次创建的内容。
# 当ファイルの形式はdocker-composeのversion3に準拠するという意味です
version: '3'
# コンテナのPostgresDBデータの永続性を確保する為
volumes:
postgres-data:
# サービスを定義
services:
# webという名前でコンテナサービスを定義
web:
# docker build . と同じ
build: .
# docker runに -v .:rails-docker を付けたのと同義
volumes:
- .:/rails-docker
# コンテナ起動時にコンテナで実行するコマンドを指定
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
# docker runに --env POSTGRES_PASSWORD=postgres を付けたのと同義
environment:
- 'POSTGRES_PASSWORD=postgres'
# docker runに -p 3000:3000 を付けたのと同義
ports:
- "3000:3000"
# dbサービスが先に起動されるように記述しています
depends_on:
- db
# dbという名前でコンテナサービスを定義
db:
# postgres version12のイメージを指定
image: postgres:12
# docker runに -v postgres-data:/var/lib/postgresql/data を付けたのと同義
volumes:
- 'postgres-data:/var/lib/postgresql/data'
# docker runに --env POSTGRES_USER=postgres --env POSTGRES_PASSWORD=postgres を付けたのと同義
environment:
- 'POSTGRES_USER=postgres'
- 'POSTGRES_PASSWORD=postgres'
在这个评论中描述了一种意义,但我们还应更详细地了解应该涉及的方面。
然后,在services > db > volumes中将主机上创建的postgres-data与容器的/var/lib/postgres/data关联起来。
/var/lib/postgres/data是postgres数据的默认存储位置。
如果不这样做,可能会导致数据丢失或难以进行备份等不良情况,例如容器删除等操作。
服务 > 网络 > 存储卷
我们通过将主机的当前目录与容器的rails-docker目录关联起来,实现了这个功能。
这样一来,当在主机端编辑代码时,也可以同时编辑容器内的代码。
这意味着我们不再需要进入容器进行修复或更改等操作。
指定了数据库。
正如我在注释中所写的,这是为了先启动Postgres。
原因是在从网站容器连接到数据库容器时,如果数据库没有先启动,就会发生错误。
我认为重要的部分应该在这里附近。
只是为了确认,关于web我们是从dockerfile创建镜像,但是关于数据库只是写了image: postgres:12。如果主机上没有这个镜像,它会从DockerHub拉取镜像。
用docker-compose命令创建容器的集合
由于之前的操作,我能够轻松地启动docker-compose.yml。
使用docker-compose命令而不是docker命令。
首先,使用docker-compose up指令可以从yml文件创建和启动容器。
这个命令的功能包括创建镜像和启动容器。
两者都会根据yml文件中的配置进行操作。
在这种情况下,它会同时处理web容器(rails)和db容器(postgres)。
进行这些步骤以前需要执行docker build .,docker run –name … –env … -v … postgres:12和docker run –name … –env … -v … -p … web command…,但现在只需要一个命令,而且非常简洁!
如果编辑了Dockerfile或docker-compose.yml文件,则可以使用–build选项进行重新构建,并以最新状态重新构建。
还可以使用-d选项将其后台运行。
可以考虑记住一些命令,比如使用docker-compose down来停止所有容器,使用docker-compose ps来显示容器列表。
同时,如果可以同时启动多个容器,那么我们可能会考虑不从DockerHub拉取,而是提前准备好多个dockerfile来创建镜像和容器。
在这种情况下,docker build命令中的-f选项就会发挥作用。
这两个容器是如何连接的?
在Dockerfile和docker-compose.yml中都没有关于网络的特殊描述,但是它们是如何连接的?如果它们是连接的,为什么?
在执行 docker-compose up 命令时,Docker会自动创建网络,并将web和db连接起来。

可以看到,在底部添加了一个创建的网络。
当您使用docker inspect命令并指定网络的ID或名称时,您可以看到更详细的信息。
-
- ネットワーク
-
- webコンテナ
- dbコンテナ
我认为,当看到每个检查的内容时,可以看出它们是相互关联的。
你可以通过运行docker-compose exec web bash命令进入web容器,然后通过psql -U postgres -h <db容器的IP> -p <db容器的端口>命令访问db容器中的postgres数据库来验证一下。
補充
在我将环境Docker化后,并非所有步骤都已完成。
但是, 因为这是关于Rails的讨论, 所以不会提及太多, 但是在使用docker-compose up命令后, 需要使用以下命令来创建数据库并更新应用程序的数据模型:
docker-compose run web rails db:create
docker-compose run web rails db:migrate
最后
通过准备Dockerfile和docker-compose.yml文件,将它们与源代码一起放入仓库中,可以通过git等工具将其置于README等文件中,并附有简单的命令说明,以便容易地进行部署。
如果对Docker和Docker Compose的理解能有一点帮助,那就很高兴了。
非常感谢您花时间阅读到这里!