Rails on Docker:Docker 入门

Rei

💡 Rails on Docker 系列文章是面向 Rails 程序员的 Docker 教程,描述了如何从开发环境到部署环境中应用 Docker。这是系列文章的第一篇。

什么是 Docker

Docker 是一种容器格式。容器是一种虚拟化技术,可以给应用提供一个相互隔离的运行环境。容器有点像虚拟机,但是比虚拟机更轻量,启动时间和占用空间都比虚拟机要小。

截屏2021-07-05 19.12.25.png
图片来源:https://www.docker.com/resources/what-container

相比于虚拟机,容器更好扩容,并且配置方式更标准化。目前云服务商大多提供了容器化部署方式或托管容器集群的服务。

Docker 用于开发环境也能提供不少好处,例如隔离不同应用的系统需求,让开发环境与线上环境等价。在开发时熟悉 Docker 的操作方式,可以减少部署到容器平台时的摩擦。

安装 Docker

Docker 提供了多种操作系统的安装包,可以在 https://www.docker.com/products/docker-desktop 找到适合自己操作系统的安装方式。

安装完毕后,在命令行中执行 docker 命令:

$ docker --version
Docker version 20.10.6, build 370c289

启动一个容器

现在我们来启动一个容器,在命令行输入以下命令:

$ docker run -it ruby:3.0 bash

这个命令会基于 ruby:3.0 镜像启动一个容器,在容器内打开 bash shell。-it 参数表示需要一个可交互的命令行,不然容器在打开 bash shell 之后因为没有输入就会关闭进程。

首次使用 ruby:3.0 镜像需要一些时间下载,启动完成后会看到以下命令提示:

root@970472afca4a:/#

现在终端就已经进入了容器内的 shell,类似于用 ssh 连接到另一台 Linux 主机。容器内的文件、系统应用都是跟宿主机隔离的,我们可以在容器内部安装应用和修改文件而不影响宿主机。

要注意的是目前因为没有设置持久化的方式,在关闭容器后所有更改都会消失。

输入 exit 或者按 ctrl-d 可以退出容器,容器会在发现没有输入后会关闭:

root@970472afca4a:/# exit
exit

挂载 Volume

上面提到,容器跟宿主机环境是隔离的,如果需要在宿主机和容器间共享文件怎么办呢?这时可以通过 Volume 解决。

用以下命令启动一个容器:

$ docker run -it -v $(pwd):/app -w /app ruby:3.0 bash

这里新增了两个参数,我们逐个理解。

  • -v $(pwd):/app 把宿主机当前目录(通过 pwd 命令获取)挂载到容器内的 /app 目录。
  • -w /app 把工作目录设到 /app,这样一启动容器初始路径就在 /app 里。

启动后查看 /app 目录,会显示宿主机当前目录的文件:

root@970472afca4a:/# ls
# ...host files

要注意现在这个目录里的修改都会同步到宿主机上。

小技巧

我经常启动一次性容器做测试,于是在 ~/.bash_profile 内设置了以下函数:

sandbox() {
  docker run -it -v $(pwd):/app -w /app $1 bash
}

这样我只要输入 sandbox ruby:3.0 就能打开一个已挂载 volume 的临时容器。

用 Dockerfile 定制镜像

前面我们都使用了 ruby:3.0 镜像,这个镜像内只有基础的 Ruby 运行环境,如果需要个别工具,我们在容器内另外安装:

root@2ad3490c73d1:/app# gem install nokogiri
Fetching nokogiri-1.11.7-x86_64-linux.gem
Successfully installed nokogiri-1.11.7-x86_64-linux
1 gem installed

但在退出容器后,容器内的修改都会消失,下次启动的时候又是一个干净的环境。有没有办法保存这些修改呢?其中一个办法是用 docker commit 把运行中的容器保存成镜像,但实际中很少用这个命令,因为有更好的选择——Dockerfile。

Dockerfile 可用于构建 Docker 镜像,现在直接看一个例子。新建一个命名为 Dockerfile 的文件,内容为:

FROM ruby:3.0

RUN gem install nokogiri

WORKDIR /app

然后在同目录下运行命令:

docker build . -t myimage

Docker 就会开始构建镜像,构建完成后,用以下命令查看镜像列表:

$ docker images
REPOSITORY  TAG     IMAGE ID      CREATED        SIZE
myimage     latest  f248af249511  5 seconds ago  863MB

可以看到,本地镜像中已经多了一个 myimage 镜像。

接着用这个镜像启动一个容器:

$ docker run -it myimage bash
root@879af3165a43:/app# nokogiri -v
# Nokogiri (1.11.7)
# ...

可以看到镜像内已经按照构建配置安装了 nokogiri。

Dockerfile 的命令很多,这里只解释几个常用的:

  • FROM 指定构建的基础镜像。
  • RUN 构建过程执行命令。
  • COPY 从构建目录复制文件到镜像内。
  • WORKDIR 指定工作目录。
  • ENV 设置环境变量。
  • CMD 设置默认的启动命令。

完整的命令列表可以查看 Dockerfile reference,另外关于镜像的优化也需要查看 Best practices for writing Dockerfiles。这里不重复叙述。

总结

这一节介绍了 Docker 是什么,如何用 Docker 启动一次性容器,以及如何用 Dockerfile 构建自己的镜像。

下一节我们将了解如何用 Docker 搭建 Rails 开发环境


Ruby 程序员,Ruby China 管理员,GeekNote 创建者。

评论 (0)

Sign in to comment