这篇文章上次修改于 1992 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单。容器就像是轻量级的虚拟机,并且可以以毫秒级的速度来启动或停止。Docker 帮助系统管理员和程序员在容器中开发应用程序,并且可以扩展到成千上万的节点。

请输入图片描述

这是一只鲸鱼,它托着许多集装箱。我们可以把宿主机可当做这只鲸鱼,把相互隔离的容器可看成集装箱,每个集装箱中都包含自己的应用程序

Docker与传统虚拟区别

传统虚拟化技术的体系架构:

请输入图片描述

Docker技术的体系架构:

请输入图片描述

容器和 VM(虚拟机)的主要区别是:

  • 容器提供了基于进程的隔离,而虚拟机提供了资源的完全隔离。
  • 虚拟机可能需要一分钟来启动,而容器只需要一秒钟或更短。
  • 容器使用宿主操作系统的内核,而虚拟机使用独立的内核。

请输入图片描述

Docker 平台基本上由三部分组成:

  • 客户端:用户使用 Docker 提供的工具(CLI 以及 API 等)来构建,上传镜像并发布命令来创建和启动容器
  • Docker 主机:从 Docker registry 上下载镜像并启动容器
  • Docker registry:Docker 镜像仓库,用于保存镜像,并提供镜像上传和下载

Docker 的安装

查看Linux内核版本(内核版本必须是3.10或者以上):

cat /proc/version

uname -a

lsb_release -a

step 1: 安装必要的一些系统工具

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

Step 2: 添加软件源信息

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

Step 3: 更新并安装Docker-CE

sudo yum makecache fast
sudo yum -y install docker-ce

Step 4: 开启Docker服务

sudo service docker start

注意:
官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。

vim /etc/yum.repos.d/docker-ee.repo

将[docker-ce-test]下方的enabled=0修改为enabled=1

安装指定版本的Docker-CE:
Step 1: 查找Docker-CE的版本:

 yum list docker-ce.x86_64 --showduplicates | sort -r
  Loading mirror speeds from cached hostfile
   Loaded plugins: branch, fastestmirror, langpacks
  docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
  docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
  docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
  Available Packages

Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)

 sudo yum -y install docker-ce-[VERSION]

安装校验

$ docker version
$ docker info

Docker 是目前最热门的容器格式,Docker Compose 是用于管理包含多个 Docker 容器的应用的工具,借助 Docker 和 Docker Compose,我们可以轻松搭建可复现的开发环境。

Install Docker Compose
1.Run this command to download the current stable release of Docker Compose:

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

2.Apply executable permissions to the binary:

sudo chmod +x /usr/local/bin/docker-compose

$ docker-compose --version
docker-compose version 1.24.0, build 1110ad01

这篇教程展示如何从零开始用 Docker Compose 搭建 Rails/PostgreSQL 开发环境。

本文主要参考了 Quickstart: Compose and Rails。但原文有一点问题,于是我加上自己的见解写成这篇博客。

安装 Docker
首先,需要在自己的开发机上安装 Docker,你可以在 https://www.docker.com/ 找到适合自己操作系统的 Docker 安装方式。

安装完毕后,可以在命令行中使用 docker 命令:

$ docker --version
Docker version 17.03.1-ce, build c6d412e

创建项目
创建项目目录:

$ mkdir myapp
$ cd myapp

接着,创建一个 Gemfile 文件,包含以下内容:

source 'https://rubygems.org'
gem 'rails', '~>5'

然后,创建一个空的 Gemfile.lock 文件:

$ touch Gemfile.lock
之所以这么做,是因为不希望在主机环境安装 Ruby 和其它依赖,而是都放到镜像中。这两个文件用于在镜像中安装 Rails。

接着,创建一个 Dockerfile 文件,该文件用于定义如何构建 Rails 镜像:

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y curl apt-transport-https && \
  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update && apt-get install -y \
  build-essential \
  libpq-dev \
  nodejs \
  ruby \
  ruby-dev \
  tzdata \
  yarn \
  zlib1g-dev

WORKDIR /app

RUN gem install bundler
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app

这个 Dockerfile 基于 Ubuntu 16.04,安装了创建 Rails 项目所需要的基础包,并将项目目录设定在 /app。你可以阅读 https://docs.docker.com/ 学习怎么定制 Dockerfile。

然后,创建一个 docker-compose.yml 文件,该文件用于定义 docker-compose 如何启动应用:

version: '2'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b 0.0.0.0
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
  db:
    image: postgres

在这个文件里,我们定义了两个服务。web 服务用于运行 Rails,镜像将根据当前目录的 Dockerfile 构建;db 服务用于运行 PostgreSQL 进程,镜像使用 Docker 官方提供的 postgres。你可以在 https://docs.docker.com/compose/compose-file/ 找到其它配置的定义。

接下来,执行以下命令:

$ docker-compose run web rails new . --force --database=postgresql

该命令会在当前目录创建 Rails 项目:

$ ls -l
total 72
-rw-r--r--   1 rei  staff   522  4 25 22:59 Dockerfile
-rw-r--r--   1 rei  staff  1989  4 25 23:02 Gemfile
-rw-r--r--   1 rei  staff  4847  4 25 23:03 Gemfile.lock
-rw-r--r--   1 rei  staff   374  4 25 23:02 README.md
-rw-r--r--   1 rei  staff   227  4 25 23:02 Rakefile
drwxr-xr-x  10 rei  staff   340  4 25 23:02 app
drwxr-xr-x   9 rei  staff   306  4 25 23:03 bin
drwxr-xr-x  14 rei  staff   476  4 25 23:02 config
-rw-r--r--   1 rei  staff   130  4 25 23:02 config.ru
drwxr-xr-x   3 rei  staff   102  4 25 23:02 db
-rw-r--r--   1 rei  staff   206  4 25 22:59 docker-compose.yml
drwxr-xr-x   4 rei  staff   136  4 25 23:02 lib
drwxr-xr-x   3 rei  staff   102  4 25 23:02 log
-rw-r--r--   1 rei  staff    61  4 25 23:02 package.json
drwxr-xr-x   9 rei  staff   306  4 25 23:02 public
drwxr-xr-x  11 rei  staff   374  4 25 23:02 test
drwxr-xr-x   4 rei  staff   136  4 25 23:02 tmp
drwxr-xr-x   3 rei  staff   102  4 25 23:02 vendor

接着,重建 Docker 镜像:

$ docker-compose build

每当修改了 Dockerfile,你都需要重建镜像。如果修改了 Gemfile,还需要先在容器内运行 bundle,然后重建镜像:

$ docker-compose run web bundle
$ docker-compose build

连接数据库
现在我们已经可以让 Rails 跑起来,但还需要修改一些配置让 Rails 连上数据库。默认情况下,Rails 的 development 和 test 环境会连接 localhost 主机上的数据库,根据之前的 docker-compose.yml 配置,我们需要将数据库的主机名改为 db。另外,还需要修改 username 以适配 postgres 镜像的默认配置。修改后的 database.yml 配置如下:
Connect the database
The app is now bootable, but you’re not quite there yet. By default, Rails expects a database to be running on localhost - so you need to point it at the db container instead. You also need to change the database and username to align with the defaults set by the postgres image.

Replace the contents of config/database.yml 在config 文件里 with the following:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

现在可以启动 Rails 进程了:

$ docker-compose up

如果一切正常,你会看到一些 postgres 的日志,然后是 Rails 启动日志:

rails_db_1 is up-to-date
Creating rails_web_1 ... done
Attaching to rails_db_1, rails_web_1
db_1   | PostgreSQL init process complete; ready for start up.
db_1   |
db_1   | 2018-03-21 20:18:37.437 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1   | 2018-03-21 20:18:37.437 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1   | 2018-03-21 20:18:37.443 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1   | 2018-03-21 20:18:37.726 UTC [55] LOG:  database system was shut down at 2018-03-21 20:18:37 UTC
db_1   | 2018-03-21 20:18:37.772 UTC [1] LOG:  database system is ready to accept connections

如果你需要运行数据库迁移,可以打开另一个终端运行:

$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate

TIP: 以后运行 rails 命令,都需要在前面加上 docker-compose run web。

用浏览器访问 http://localhost:3000 ,你会看到 Rails 的欢迎信息:
2019-06-25_103421.png