使用Docker Compose构建Web应用程序的方法
请注意
由于本次主要解释docker-compose的使用方法,所以对Rails的解释不充分。
因此,请先接受我的道歉。
学习Docker的契机
我是一个刚开始从事机器学习工程师工作的一年级新人,我每天都在学习中努力前进。虽然我本来想通过Kubeflow等工具来建立机器学习基础,但我意识到首先需要扎实的Docker知识,所以我发帖询问了!
下列是我参考的教材。
这次我参考了这个学习材料。
从Dockerfile的编写方式到使用AWS的EC2实际创建深度学习环境,真的是非常好的教材。
请大家一定要购买并尝试。
1. DockerCompose是什么?
Docker Compose是一种使用Docker定义和运行多个容器的工具。使用Docker Compose,可以将多个Docker容器定义为一个单一的应用程序,并且可以轻松地构建和管理复杂的多容器环境。
在开发网络应用程序时,这将非常方便。以图表的方式展示的话就是这样的样子。
如果您打算在Web应用程序框架中使用Rails,那么您需要使用Ruby容器和数据库容器。如果您使用Postgresql作为数据库,那么您可以选择DB容器。通过使用这两个容器,我们可以创建一个实际的Web应用程序。
使用Docker-compose制作Web应用程序。
2.1 创建工作目录
首先,让我们创建一个工作目录。
我使用mkdir等命令在桌面上创建了一个名为project-register的工作目录。
2.2 创建Docker文件(概述)
首先,让我们从 Dockerfile 开始创建。我们稍后会进行详细解释。
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
postgresql-client \
yarn
WORKDIR /product-register
COPY Gemfile Gemfile.lock /product-register/
RUN bundle install
2.2.1 來自
根据基本图像进行决定。
在这种情况下,我们正在从Docker Hub获取Ruby 2.5的图像。
2.2.2 运行 apt-get update && apt-get install -y
进行apt-get更新并安装命令。
apt-get是Ubuntu的软件包管理工具。
这个命令会更新下面列出的每个软件包并安装它们,-y参数将强制安装这些软件包。
在使用Ruby时,我们安装了这些包因为它们是必需的。在实际工作中,我们需要不断尝试搜索这些依赖包等。而这次,我们知道了所需的包是什么,所以如此描述。
我会对RUN进行详细解释。
其实,上述的描述已经很好地总结了,不过也可以这样描述。
RUN apt-get update && apt-get install -y build-essential
RUN apt-get update && apt-get install -y libpq-dev
RUN apt-get update && apt-get install -y nodejs
RUN apt-get update && apt-get install -y postgresql-client
RUN apt-get update && apt-get install -y yarn
作为Docker镜像创建的最佳实践,
☑︎将Docker镜像的层数保持在最低限度。
这非常重要。
现金是重要的
举个例子,假设你有时候会想要添加hogehoge这个软件包。
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
postgresql-client \
yarn
RUN RUN apt-get update && apt-get install -y hogehoge
使用这个Docker镜像创建另一个镜像时,将使用缓存。由于上面的部分已经安装了,所以可以省去重新安装的麻烦。
若在反斜杠后添加新的hogehoge,就会创建一个新的图层,这是一个错误的例子。
换句话说,即使已经存在的软件包也会执行新的apt-get操作。如果有20个、30个软件包,创建镜像可能需要一整天的时间。
所以,如果要安装新的软件包,请使用cash进行安装。
2.2.3 工作目录
这仅仅是指定在Docker上进行操作的工作目录。
2.2.4 复制指令
这是一个将主机上的数据复制到Docker容器中的命令。
复制<要复制的内容>到<要放置的位置>。
2.2.5 运行捆绑包安装命令
使用Bundler这个管理工具,bundle install命令用于安装Ruby应用程序所需的Gem(Ruby库和包),该工具在Ruby程序中用于管理依赖关系。
读取Gemfile,并解决Gemfile中指定的依赖关系,确定所需Gem的版本。这个过程是为了确认指定Gem的版本是否在Gemfile所规定的范围内,并选择Gem的版本以满足依赖关系。
关于Web应用程序的构建,我不太了解,所以无法进一步详细解释,但大致是这样的感觉。
你看到了在WORKDIR和COPY命令中移动的目录是一致的。
由于有Gemfile,所以这些命令正常运行。
2.3 创建Gemfile
source 'https://rubygems.org'
gem 'rails' , '~>5.2'
来源:从哪获取Gem?
你要使用哪个版本的Rails呢?
これらを記載しています。
2.4 Docker 构建
用这个可以创建Dockerfile了。
Dockerのコンテナは、Imageを元に作成されるので、
まずはDocker fileを元に、Docker buildでImageを作っていきます。
docker build .
请指定当前目录,该目录应包含Dockerfile和Gemfile.lock文件。如果成功创建了该目录,
docker images
请使用它来确认图像的创建。
2.5 Docker集成
如果你学过Docker,可能会想:“哦,接下来只需运行`docker run`就可以了吧?”确实是这样。那么,让我们实际地来运行`docker run`吧。。。
docker run -v ~/Desctop/product-register:/product-register -p 3000:3000 <Image ID>
使用Docker运行 -v
这个工作的作用是连接宿主机上的目录和Docker上的目录来进行挂载操作。
docker run -p 8080:8080
ポート番号の指定です。
Railsのデフォルトのポートは3000なので、3000:3000としています
これでホストとコンテナがつながります。
不是很长吗?
对的,Docker run命令写起来挺长的,是吧?
而Docker Compose可以让其简化执行。
而且,接下来要介绍的是,最吸引人的地方是可以同时运行多个容器。
使用Docker Compose来运行和运行相同的事务。
docker-compose up
这就结束了。
“嗯?太轻松了吧?”
是的,确实是轻松的。
2.5.1 开始编写 Docker-compose 文件
那么就让我写下去吧。不过说实话,用docker-run写的和之前没太大区别。
version: '3'
services:
web:
build:
context: .
dockerfile: Dockerfile
ports:
- '3000:3000'
volumes:
- '.:/product-register'
tty: true
stdin_open: true
版本
这是docker-compose的版本。大概是3的样子。
请将其视为写docker-compose的宣言。
服务
yaml文件是以键值对的形式进行编写的。
因此,请将其视为父键。
我会在这个父键下面写下想要运行的内容。服务的名称我们加上了“web”。
建造
在运行docker-compose up命令时,实际上也会执行构建操作。
如果没有创建镜像,它会根据Dockerfile文件创建镜像。
港口
这个指定了想要发布的端口号。
卷册
请指定需要安装位置。
请将当前目录指定为相对路径。
因为为了让其他人更容易使用。请记住,自己绝对路径并不一定是别人使用的,这就是这样的情况。
终端设备,标准输入
这个是指示docker run -it中的it。
省略了细节,
stdin是输入通道,
tty则是用来漂亮地显示命令输出结果的角色。
因此,请将其视为一个咒语输入。
执行2.5.2 docker-compose up。
现在我要开始写了。
docker-compose up -d
对于Docker Compose命令,-d选项用于以后台模式在容器中运行的选项。
具体的には、docker-compose up -d コマンドを実行すると、Docker Compose は定義されたサービスのコンテナをデタッチモードで起動します。デタッチモードでは、コンテナはバックグラウンドで実行され、コンソールにログが表示されません。これにより、コンソールをブロックされることなく、バックグラウンドでサービスを実行することができます。
现在,我已经概述了docker-compose的使用方法,但是你只创建了Rails容器,还没有创建其他容器。
複数のコンテナを動かせるのが、最大のdocker-composeの利点なので、そこまで説明していきます。
首先,我们会进行Rails的配置。
3. Rails的配置
在进行此设置之前,首先需要进入容器。
我认为您刚刚已经创建了容器,所以进入容器的命令如下所示。
docker-compose exec web bash
我认为您已经指定了服务名称,因此我正在输入该网络地址并指定bash命令来执行它。
我们这次要使用Postgresql作为数据库,但在使用时,
rails new
使用这个指令,写下来就是这个样子。
rails new . --force --database=postgresql --skip-bundle
– 强制执行
这意味着它将覆盖一切。虽然这次没有特别的意义,但我会写下去。
– 数据库
设置使用哪个DB服务器。
通过编写这个,可以为Postgre创建应用程序,非常方便。
– 跳过绑定
Gemfileが新しくなれば、bundle installを行なわれますが
これはDocker file側でbundle installを設定しているので、ここではスキップしています。
由于Gemfile已经更新,因此需要再次运行docker-compose。
先ほど、–skip_bundleを行なったので、一度、コンテナから抜けて、再度docker-composeを行う必要があります。
ですが、先ほどdocker-composeを行なったので、先ほど作ったImageがそのまま使われることになってしまいます。
そのため、docker-compose upのオプションで–buildがあります。
それをすることによって、再度強制的にbuildを行なってくれます。
docker-compose up --build -d
重新创建了容器。
回到容器里,
rails s -b 0.0.0.0
当你执行这个命令时,你可以启动Rails服务器。
实际上,当你在浏览器中输入localhost:3000时,可以尝试访问。
由于错误,连接错误发生。
当然,因为没有创建数据库容器,所以很正常呀。
下一步, 我们将在docker-compose内创建用于数据库的容器。
创建DB容器并连接到Rails和DB容器。
首先,需要设置工作目录中的每个文件。
请按照以下描述进行设置。
本说明将被省略。
/config/database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db
user: postgres
port: 5432
password: <%= ENV.fetch("DATABASE_PASSWORD") %>
# For details on connection pooling, see Rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
/config/routes.rb
⇨用于在通过localhost:3000在浏览器中输入时更改页面显示的配置。
Rails.application.routes.draw do
root 'products#index'
resources :products
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
立即开始,我们将创建一个docker-compose。
version: '3'
volumes:
db-data:
services:
web:
build:
context: .
dockerfile: Dockerfile
ports:
- '3000:3000'
volumes:
- '.:/product-register'
environment:
- 'DATABASE_PASSWORD=postgres'
tty: true
stdin_open: true
depends_on:
- db
links:
- db
db:
image: postgres
volumes:
- 'db-data:/var/lib/postgresql/data'
environment:
- 'POSTGRES_USER=postgres'
- 'POSTGRES_PASSWORD=postgres'
dbのサービス名の部分について説明します。
图片
因为已经创建了一个名为”postgres”的镜像,所以直接指定该镜像。
请重新表达以下内容(只需要一种选项):
– volumes
ローカルの場所とコンテナの場所を接続しています。
コンテナにDBがあるとします。
何もしなければ、コンテナが消えたら当然DBも消えます。そのため、ローカル上の場所と接続することが大切です。
不过,db-data这个地方还没有建立在任何地方。
指定volumes后,将会创建目录。
环境
我想,如果您曾经使用过Postgresql,您会明白,需要指定用户名和密码并提供它们。
接下来让我们来看一下网络服务。有几个新添加的服务。
取决于:
これは先にdbのコンテナを作ってくれよと指定しています。
WebサービスはDBがないと作成されないので、順番を決める必要があります。
links:
这个角色是连接Web服务和数据库的。这将使得两个容器连接起来。
像这样,我们会修改docker-compose.yml文件。非常抱歉,我会尽量省略Rails的详细说明。
4.1 进行最终设置。
那么我们将进行最终的设置。
①由于docker-compose的更改,需要重新输入。
docker-compose up -d
在运行docker-compose exec web bash命令后进入容器。
在此时,DB容器已经连接好了。
docker-compose exec web bash
使用`rails db:create`命令创建了一个数据库服务器。
rails db:create
不会详细解释,只需简单地将其视为一种批量构建Web应用程序的方法。
rails g scaffold product name:string price:integer vendor:string
逐渐定义表格
rails db:migrate
启动Web应用程序
rails s -b 0.0.0.0
我成功地构建了一个如此简单的Web应用程序。
现在,我们可以使用docker-compose构建一个简易的Web应用程序了。
下一步将进行CICD的构建。
这次我们使用Docker来构建了一个Web应用程序,下一步我们想要使用这个应用程序来搭建CICD。
5.1 CICD的意思是什么。
CI/CD是”Continuous Integration and Continuous Deployment(持续集成和持续部署)”的缩写,指的是在Web应用开发过程中的自动化实践。通过这种方式,开发人员可以高效地集成代码变更、运行测试并自动化部署。
CICD由以下三个主要步骤构成。
持续集成(Continuous Integration):是指开发人员将代码更改集成到共享代码库的进程。这样,即使有多个开发人员同时操作,也可以及早发现代码冲突和兼容性问题。
Continuous Testing(継続的テスト):在代码合并之后,执行自动化测试套件来确认应用程序的质量。通过这样做,能够早期发现错误和缺陷,从而保证质量。
持续部署:指的是在代码修改经过测试合格后,自动部署到生产环境的流程。通过这个流程,可以快速发布新功能和修正,并提供给用户使用。
持续集成与持续交付(CICD)的优点包括提高开发过程的效率、提升质量、减少由人为错误引起的问题、实现快速发布等。这将有助于提升Web应用程序开发和部署的速度和可靠性。
下次的展望
下一步,我們希望自動化這個應用程式的開發流程。
再見。