对于Docker Compose的大致理解【概述/编写yml文件/操作命令】

首先

最近,我开始在由山浦清透先生运营的自学工程师编程学习服务“独学エンジニア”上学习Docker,已经完成了最后一个部分,即Docker Compose的学习。因此,我想将我的笔记整理一下,并且附上自己的总结。

这篇文章是在理解Docker基本操作的前提下进行写作的,所以如果你是“虽然Docker好像很方便,但是我不太懂!”的话,请先轻松阅读我之前发布的文章,“Docker基本操作Part1”,“Docker基本操作Part2”和“Dockerfile的写作方法”。

docker-compose-tako.png

他们说章鱼正在考虑同时操作多个容器……
难道你是说它能够同时操作多个容器!?

章鱼:“就是那样。”

(他说了些什么,笑了笑)

1. Docker Compose是什么?

用于定义和执行多个容器的Docker应用程序的工具,通过使用YAML文件来配置应用程序的服务,只需执行一个命令,就可以生成和启动基于配置内容的所有服务。

来自「Docker官方文档」

换言之,通过使用Docker Compose,可以更容易地进行构建Docker镜像、启动和停止各个容器等操作,使得应用程序由多个容器组成的场景变得简单。

在实际的开发现场中,很少只使用一个容器进行开发。通常会使用多个容器进行开发,因此可以说Docker Compose是必需的。

2.Docker和Docker Compose的差别是什么?

Docker(Docker Engine)Docker Compose役割Dockerコンテナを運用するためのプラットフォーム複数のDockerコンテナを一度にできるツールコンテナ操作1度に1つずつしかDockerコンテナを操作できない1度に複数のDockerコンテナを操作可能

3. 启动容器的过程

    1. 创建DockerFile

 

    1. 如果在docker-compose.yml文件中直接指定镜像,就不需要Dockerfile来启动容器了。但是,如果要对现有镜像进行额外的配置或自定义,就需要创建Dockerfile,并在docker-compose.yml中引用它。

创建docker-compose.yml
docker-compose.yml是Docker Compose的配置文件,用于定义将要创建的容器的初始状态,例如“ports:”、“volumes:”等,使用YAML格式进行定义。此外,该文件通常放置在项目的根目录下。通过使用刚刚介绍的docker-compose.yml,可以一目了然地了解由多个容器组成的应用程序的整体结构,并且可以使用一个命令启动或停止所有容器。

使用docker-compose命令启动容器
在docker-compose.yml文件所在的目录中执行docker compose up命令,可以构建并启动docker-compose.yml文件中定义的所有服务(容器)。

image.png

写docker-compose.yml文件的方法

首先,我们来看一下docker-compose.yml文件的示例(用于Rails的环境构建),然后挑选出常用的部分,并逐个进行理解吧!

services: # (1)
  db:
    image: mysql:5.7 # (2)
    volumes: # (4)
      - db_data:/var/lib/mysql 
    restart: always
    environment: # (6)
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: your_database
      MYSQL_USER: user_name
      MYSQL_PASSWORD: user_password

  web:
    build: ./rails_project # (3)
    command: bundle exec rails s -p 3000 -b '0.0.0.0' # (9)
    volumes: # (4)
      - .:/myapp
    ports: # (7)
      - "3000:3000"
    depends_on: # (8)
      - db
      
volumes: # (5)
    db_data:

(1) 服务

在这里,我们列举要创建的服务(容器)。
在示例中,有两个容器,分别以“web”和“db”作为名称,它们的设置都有所描述。

services: 
  db: #サービス名
    
  web: #サービス名

可以给「web」或「db」以外的服务起其他名字吗?
因为服务名是任意的,所以可以起不同的名字。
但是,要注意以下两点:起一个容易理解该服务代表的名字
如果该服务被其他服务引用,如果要改变该服务名字,也要同时改变引用它的服务名字

※考虑到在环境配置时与团队成员共享的需求,基本上使用一般常用的服务名字如「web」或「db」会更为稳妥。

(2)图像

如果不需要对现有的图像进行额外的配置或定制,则可以通过在”image:”后面指定Docker图像来使用该图像进行构建。

  image: mysql:5.7 # イメージ名:タグ

(3)建立

如果要从准备好的Dockerfile而不是从图像中构建,可以在yml文件的build:字段中描述从目录(当前目录)中放置Dockerfile的目录到Dockerfile所在目录的相对路径。

  build: ./rails_project # Dockerfileがあるディレクトリへの相対パス

(4)在服务内的卷册

Volumes是一项用于将数据保存在容器之外的设置,同时也可以与主机共享数据,以实现数据的持久性。如果没有这个设置,当容器被删除时,容器内的所有数据将会消失,这将非常糟糕。

  # (dbコンテナ)
  volumes:
      - db_data:/var/lib/mysql  # ホストディレクトリ : コンテナ内ディレクトリ
  # (webコンテナ)
  volumes: 
      - .:/myapp  # ホストディレクトリ : コンテナ内ディレクトリ  

volumes用于将主机目录和容器内目录进行挂载,也就是连接它们。当在主机上修改代码时,这些更改将实时反映在容器内。

(5)指定为最高级别的卷。

在这里的`volumes`指示Docker Compose创建一个卷。
并且在这里定义的卷可以在服务内的`volumes`中使用,就像在示例中的`db`容器中使用一样。

   volumes: 
      db_data:

使用卷,可以将数据与Docker容器的启动和停止周期独立保存和管理,因此,即使删除容器,保存在卷中的数据也会保留,因此将不想删除的数据放入卷中是安全的。

为什么在db容器中,挂载目标选择Docker卷而不是宿主机呢?
db服务将MySQL数据保存在/var/lib/mysql目录中,并将其挂载到Docker卷中。这主要有以下几个原因:1. 数据持久化:无论容器的处理周期如何,数据都可以进行持久化。

2. 性能考虑:Docker卷经过性能优化,对于频繁发生输入输出(I/O)操作,特别是数据库等应用来说至关重要。

3. 数据的独立性:与应用代码不同,开发人员不能直接操作数据库数据。因此,将它们挂载到主机特定目录的需求较低,而且如果在主机上进行挂载,可能会导致主机的目录结构复杂化。

4. 备份和恢复:Docker卷易于备份和恢复,非常适合管理重要的数据库数据。

基于以上原因,一般推荐使用Docker卷来实现数据库数据的持久化。然而,在特定情况和需求下,也可以使用宿主机的目录。

如果对于音量的问题“嗯〜,不太清楚!”的话,以下这篇文章可能会有所启发,我贴在这里给你参考。

 

(6)环境

环境变量用于在Docker容器内设置使用的变量。
由于Docker容器与主机环境完全隔离运行,因此需要在容器内设置环境变量。

  environment: 
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_DATABASE: your_database
      MYSQL_USER: user_name
      MYSQL_PASSWORD: user_password

(7)港口

在端口设置中,指定了主机和Docker容器之间的网络端口映射。请注意指定的格式应该是主机端口号:容器端口号,以免出现颠倒的情况。

    ports: 
      - "3000:3000" # ホストマシンのポート番号:コンテナのポート番号

ports的设置是Docker容器应用程序通过网络与外部通信所需的配置。因此,如果有与外部进行交互的情况,请务必记得进行设置。

(8)视乎

depends_on用于定义服务之间的依赖关系,并且能够告知Docker Compose所指定的服务依赖于其他一个或多个服务。
因此,Docker Compose会在启动该服务之前,确保所有它依赖的服务都已经启动。

   # (webコンテナ)
   depends_on: 
     - db

Docker Compose会确保在上述内容中,Web容器依赖于数据库容器,所以数据库容器会被首先启动。

(9)指令

指定command则会在服务容器启动时执行指定的命令。

    command: bundle exec rails s -p 3000 -b '0.0.0.0' 

这个设置选项还有很多,但是我认为常用的都在这里了,所以如果有出现不熟悉的选项的话,我觉得可以每次都去查一下也可以。

你常常看到yml文件里面写着”version”,那个一定要写吗?
总结起来,不需要写。
这是比Docker Compose规范更要求的”compose-spec”。Compose文件是一个YAML文件,定义了version(已过时),services(必需),networks,volumes,configs和secrets。

所以不管有没有”version”都能正常运行,请放心(^^)

用Docker Compose命令进行操作。

一旦你创建了docker-compose.yml文件,接下来我们就可以使用Docker Compose命令进行操作。

(1)启动【容器创建和启动】

$ docker compose up  # イメージが存在しないときはビルドする

以下两个选项在选项中经常被使用。

–build イメージをビルドした上でコンテナを作成・起動する

-d コンテナをバッググラウンドで起動させる(detach)

$ docker compose up --build 
$ docker compose up -d

如果想要修改Dockerfile或docker-compose.yml文件,并重新启动容器,可以使用–build选项来构建镜像。

(2)显示ps容器列表

如果想要显示包括停车中的容器的列表,请添加-a选项。

$ docker compose ps      # コンテナの一覧を表示
$ docker compose ps -a   #停止中を含めたコンテナの一覧を表示

(3)显示日志

通过在”logs”命令后指定服务名称,可以显示日志。

$ docker compose logs web   # サービス名を指定

(4)运行【容器创建后,执行命令】。

通过在“run”命令后指定服务名称和命令,可以创建容器并仅执行一次命令。

$ docker compose run web ruby app.rb   # サービスとコマンドを指定

(5)执行【命令执行】

在正在运行的容器中,通过在执行命令的后面指定服务名和命令来执行命令。

$ docker compose exec web /bin/sh  # サービスとコマンドを指定

(6)停止并删除容器。

只需添加一个down命令,即可停止并删除使用up命令创建的容器。

$ docker compose down

最后

感谢您一直看到最后!虽然有点长,但我认为这样一来就能基本理解Docker Compose了。接下来就是实践了。我希望能够利用我之前学到的知识,努力实现在Docker上搭建Rails环境。

如果有任何错误,请毫不犹豫地指出来。

文献引用

 

广告
将在 10 秒后关闭
bannerAds