Docker资源管理

每个Docker容器在运行时都需要CPU, 内存以及IO资源,而运行Docker容器的主机的资源是有限的,因此如何有效的管理和使用资源就非常的重要了,因此Docker也提供了一下机制可以限制容器使用的资源。

CPU

在使用 docker run 启动容器时,提供了参数-c int或者–cpu-shares int可以帮助我们限制容器对CPU的使用。参数值是一个整数类型,用于设置当前Docker容器使用cpu的权重值(默认为1024)。这是一个相对值,每个容器能够使用的cpu, 取决于它的cpu shares 占所有容器cpu share的比例: 例如:

docker run --name "container1" -c 1024 image
docker run --name "container2" -c 512 image

在上述情况下,如果二者都需要内存,那么 container1 分配到两倍于 container2 的CPU资源。

另外需要注意,这种按权重分配 CPU 只会发生在 CPU 资源紧张的情况下。当CPU还有足够的空闲资源时,是没有此限制的。

内存

我们知道内存包括 实际的物理内存 和 交换内存(swap), 因此 Docker也分别提供了参数来控制内存的使用。

物理内存

在使用 docker run 启动容器时,提供参数-m bytes或者–memory bytes可以帮助我们限制容器对内存的使用。

这里的 bytes 指的是以字节为单位的最大使用限额,指的是明确的限额,而不是一个相对值。

例如:

docker run -m 200M image

此时该容器在运行时可以使用的最大的内存值为 200M, 此时 swap 最大值是物理内存的两倍。

交换内存

在使用 docker run 启动容器时,提供参数–memory-swap bytes可以帮助我们限制容器对swap的使用。

与 -m 参数的使用方式相同,并且二者可以同时使用:

docker run -m 200M --memory-swap=300M image

创建的新镜像可以使用最多 200M 物理内存和 300M swap。

IO

IO资源同样也是操作系统的一种非常重要的资源,通常包含了对硬盘的读写,网络数据的交换等等,这里指关注对 Docker host的硬盘的读写(即block IO)。

控制容器读写硬盘的方法有以下几种:

  1. 设置容器读写硬盘资源的权重
  2. 限制bps和iops

设置权重

在使用 docker run 启动容器时,提供参数–blkio-weight int可以帮助我们控制容器读写磁盘(block IO)的优先级。

这个参数类似于使用 -c 对 cpu资源 的控制方式, 设置的是相对值,而不是绝对值。其含义和分配方式均与 -c 类似,这里就不细说了。

限制 bps 和 iops

  • bps: byte per second,每秒读写的字节数(即读写速率)
  • iops: io per second,每秒 IO 的次数

在使用 docker run 启动容器时, 提供了以下参数来加以控制:

  1. –device-read-bps,限制读某个设备时的 bps。
  2. –device-write-bps,限制写某个设备时的 bps。
  3. –device-read-iops,限制读某个设备时的 iops。
  4. –device-write-iops,限制写某个设备时的 iops。

这里的设置指的就是硬盘,磁盘等等,通过这些参数,可以严格的限制当前容器对某个存储设备的读写速度。

  • –device-read-bps和–device-write-bps参数值的格式为: :[]。device-path 指的就是设备的路径名,number是一个正整数,unit是单位,可以是kb, mb 或者gb

  • –device-read-iops和–device-write-iops参数值的格式为: :。注意这里是没有单位的,因为它表示的就是次数。

例如:

docker run -it --device-write-bps /dev/sda:30MB --device-write-iops /dev/sdb:10000 image

上述命令,限制了新容器对磁盘设备/dev/sda的每秒钟后读写的字节数(bps)为30MB, 以及对 /dev/sdb设备的读写最大次数为10000次.

docker搭建统一开发环境

背景说明:由于公司项目众多,nginx重写复杂,各种缓存等原因导致开发环境搭建很麻烦,开发效率低下。
无需本地安装docker环境。

软件清单

  • docker 服务器
  • rancher 容器管理平台
  • syncthing 文件同步

1. 准备docker环境

用一台配置还不错的服务器,安装好docker环境。

docker安装说明:https://docs.docker.com/engine/installation/

2. 安装rancher

使用rancher主要为了方便管理容器,可视化的界面可以让不会docker的人也能使用。

rancher安装说明:http://rancher.com/docs/rancher/v1.6/zh/

sudo docker run -d --restart=unless-stopped -p 8080:8080 rancher/server:stable

安装好rancher后 访问 http://:8080

3. 添加负载均衡服务

在应用添加负载均衡服务,主要为外部域名访问到不同容器。

4. 添加syncthing

刚开始本来用Samba, 但担心服务器挂掉后代码无法查看,所以才选用syncthing,就算磁盘坏掉都不用担心代码丢失。
在rancher页面上添加或直接run容器,注意需要将数据目录挂载出来

docker run --network=host 
    -v /wherever/st-cfg:/var/syncthing/config 
    -v /wherever/st-sync:/var/syncthing 
    syncthing/syncthing:latest

启动后,访问 http://:8384
使用说明:https://docs.syncthing.net/index.html

5. 本地安装syncthing

syncthing跨所有平台,下载自己系统相应的版本 https://syncthing.net/

下载实时同步插件 Syncthing-inotify https://github.com/syncthing/syncthing-inotify

启动syncthing客户端,web访问 http://127.0.0.1:8384

启动Syncthing-inotify,这样修改文件会实时同步。

添加远程设备,设置远程设备ID(操作->显示ID),服务器端和本地都需要相互添加。

6. 设置需要同步的代码

本地syncthing,添加文件夹,设名称和路径,并共享给服务端,保存。

注意:在同步文件路径根目录添加 .stignore 文件,忽略掉不需要同步的文件或文件夹。例如:

.svn
.git
.idea
down/
phperrorlog/
*.zip
testUnit/
temp/
FonDoc/
tests/
test/

客户端保存后,服务端syncthing,会自动提示有客户端共享文件,修改好服务端保存路径。

7. rancher添加web容器

启动web容器,注意代码挂载路径。也可将php和nginx配置文件挂载出来,便于实时修改。

version: '2'
services:
    dongxu-php56:
        image: dzer/php-meilele-dev:v1
        environment:
          DOCUMENT_ROOT: /app
        stdin_open: true
        volumes:
        - /data/syncthing/dongxu/meilele:/app:rw
        - /data/syncthing/meilele_nginx_conf:/usr/local/nginx/conf:rw
        - /data/syncthing/meilele_php_conf:/usr/local/php/etc:rw
        tty: true
        extra_hosts:
        - common.meilele.com:127.0.0.1
        - memcache.meilele.com:192.168.0.250
        - clubmemcache.meilele.com:192.168.0.250
        - codememc.meilele.com:192.168.0.250
        - zxmemcache.meilele.com:192.168.0.250
        - adminmemcache.meilele.com:192.168.0.250
        - wapmemc.meilele.com:192.168.0.250
        - rule.meilele.com:192.168.0.22
        - ip.meilele.com:192.169.0.250
        - ipadmemcache.meilele.com:192.168.0.250
        - imgmemcache.meilele.com:192.168.0.250
        - dcmemcache.meilele.com:192.168.0.250
        - factory.meilele.com:192.168.0.250
        - zxback.meilele.com:127.0.0.1
        - slave.meilele.com:192.168.0.23

8. rancher lb-service添加域名

在rancher lb中添加需要访问的域名,并指向相应的容器。

9. 修改本地hosts

将需要访问的域名和服务器ip 添加到 本地hosts

CentOS 7上安装Docker

脚本安装

1、使用root权限登陆系统。

2、更新系统包到最新。

yum -y update

3、执行Docker安装脚本

curl -sSL https://get.docker.com/ | sh
yum install -y docker-selinux

4、启动 Docker

systemctl start docker.service

5、验证 docker 已经正常安装

docker run hello-world

yum 安装

1、添加 yum 仓库

cat >/etc/yum.repos.d/docker.repo <<-EOF
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

2、安装 Docker 包

yum install -y docker-engine

开机自启动

systemctl enable docker.service

docker 升级到最新版

步骤

1、卸载旧版 docker

> rpm -qa | grep docker # 也可以使用 yum list installed | grep docker 
docker-engine-1.13.0-1.el7.centos.x86_64
docker-engine-selinux-1.13.0-1.el7.centos.noarch
> yum remove docker-engine-1.13.0-1.el7.centos.x86_64
> yum remove docker-engine-selinux-1.13.0-1.el7.centos.noarch

2、升级至最新版

> curl -fsSL https://get.docker.com/ | sh

3、重启docker

> systemctl restart docker # centos 7
> service docker restart # centos 6

4、查看升级后的版本

> docker version # docker -v

【Docker】如何修复无法启动的容器

先说说这个问题的起因:

Docker容器后台运行,就必须有一个前台进程!

OK,有次手贱,把容器内的php-fpm配置文件中的daemon改为yes,导致了没有前台进程,因此,容器启动后就停止了。
那么问题变成,如何修改没有启动的容器内的文件?(PS:正常情况下可以通过 docker exec命令打开容器的一个shell终端进去修改)

解决方案:创建新镜像

把这个问题容器用docker commit提交到一个新的镜像,然后用docker run -it 基于新镜像运行一个新的容器进去改变(修复)配置文件。
再通过新的容器再提交一个新的镜像,然后在基于新的镜像重新启动容器(同最初的容器)。
这个方法是可行的,但问题是步骤多,而且提交了新的镜像,对于后续维护增加了复杂性。

#把要修复的容器提交为镜像
docker commit <container_id> <image_name>:<tag>
docker rm <container_id> #这个删除老的容器,反正也用不了
#查看刚建立的新镜像
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
zhibin/php5                              2018                c6532c5ece91        10 minutes ago      1.549 GB
#利用这个新镜像创建容器,进入容器,修复配置文件
docker run -it --name tmp-fixphp5 zhibin/php5:2018 /bin/bash
#重新提交镜像
docker commit <container_id> <image_name>:<tag>
#创建修复后的容器
docker run -d --volumes-from nginx_server --name php-fpm_server_2018 --dns=10.100.17.21 --cap-add SYS_PTRACE -p 9000:9000 zhibin/php5:201802

Shell 实现 docker 的健康检查及服务重启功能

最近配置一台 CentOS 7.1 的服务器, 安装了 docker-ce 版本为: Docker version 17.09.1-ce, 启用 docker swarm, 创建 stack 时,发现如下错误:

start container failed: subnet sandbox join failed for "10.255.0.0/16": overlay subnet 10.255.0.0/16 failed check with host route table: requested network overlaps with existing network

具体错误如图:

未分类

原因可能是上层网络占用了 10.255.0.0/16 的部分网段导致。 所以只有放弃 swarm 模式,由于应用比较简单,所以只需使用 docker-compose 就够啦, 只是docker 自带的健康检查失去了意义,只是标识是否健康,没有进程监控健康的状态及恢复服务的操作。
最后决定使用 SHELL 实现这一功能。

先写好自己的docker-compose.yml, 比如PHP+NGINX+REDIS的服务,具体如下:

version: '3.3'
services:
  redis:
    image: redis:3
    restart: always
    volumes:
      - /xmisp/redis/conf:/usr/local/etc/redis
      - /xmisp/redis/data:/var/lib/redis
      - /xmisp/redis/log:/var/log/redis
    ports:
      - 10.0.21.30:6379:6379/tcp
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  php:
    image: davinbao/php-fpm:latest
    restart: always
    volumes:
      - /xmisp/php/conf/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro
      - /xmisp/php/log:/var/log/php-fpm
      - /xmisp/www:/home/www
    ports:
      - 10.0.21.30:9000:9000/tcp
  nginx:
    image: davinbao/nginx:latest
    restart: always
    volumes:
      - /xmisp/nginx/conf:/etc/nginx/conf.d
      - /xmisp/nginx/log:/var/log/nginx
      - /xmisp/www:/home/www
    ports:
      - 80:80/tcp

SHELL 实现健康检查及重启服务, 具体如下:

#!/bin/bash

ADDRESS=$1
COMPOSE_FILE=$2
STATE=0


while true ;do

    HTTP_CODE=`curl -I -m 10 -o /dev/null -s -w %{http_code}"n" ${ADDRESS}`
    if [ "${HTTP_CODE}" != 200 ];then
        let STATE=STATE+1
        echo `date +"%Y-%m-%d %H:%M:%S"` The ${STATE} time can not access
    else
        echo `date +"%Y-%m-%d %H:%M:%S"` Success
        break
    fi

    if [ $STATE -gt 2 ];then
        echo Can not access ${ADDRESS} ,service will reboot!
        docker-compose -f ${COMPOSE_FILE} down
        docker-compose -f ${COMPOSE_FILE} up -d
        break
    fi
    sleep 15

最后配置 crontab 每两分钟执行该脚本:

> crontab -e

*/2 * * * * /xmisp/www/redirect-system/health_check.sh http://localhost /xmisp/www/redirect-system/docker-compose.yml >> /xmisp/www/redirect-system/storage/logs/health_check.log

脚本的功能是每两分钟检查一次80端口,如果不通,将重启整个服务。

docker里的centos 安装sshd服务

1、 yum install openssh-server

2、启动sshd 报错 需要绝对路径

[root@0463226081ca src]# sshd     
sshd re-exec requires execution with an absolute path

3、用绝对路径 再次报错

[root@0463226081ca src]# /usr/sbin/sshd     
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
sshd: no hostkeys available -- exiting.

4、执行 少什么生成什么key

ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

5、再次执行 成功

[root@0463226081ca src]# /usr/sbin/sshd
[root@0463226081ca src]# 

6、外部连接还是失败 修改/etc/sshd/sshd_config配置文件 重启再连 成功

UsePAM no

CentOS 7 Docker 防火墙简单配置

禁用 firewalld 服务

systemctl disable firewalld
systemctl stop firewalld

安装 iptables 防火墙服务

yum install iptables-services

创建 iptables 配置脚本

cat >> /usr/local/bin/fired.sh <<'EOF'
#!/bin/bash

iptables -F
iptables -X
iptables -Z
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p icmp --icmp-type 8 -j ACCEPT
#iptables -A INPUT -p tcp --dport 80 -i eth0 -m state -state NEW -m recent -update -seconds 60  -hitcount 50 -j DROP
#iptables -A OUTPUT -o eth0 -m owner -uid-owner vivek -p tcp --dport 80 -m state -state NEW,ESTABLISHED  -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 1:1023 --dport 1:1023 --syn -j DROP
iptables -A INPUT -p tcp -i eth0 --dport 22     --sport 1024:65534 -j ACCEPT
iptables -A INPUT -p tcp --dport 80     --sport 1024:65534 -j ACCEPT
iptables -A INPUT -p tcp --dport 2376   --sport 1024:65534 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306   --sport 1024:65534 -j ACCEPT

# OpenVPN Configuration
# iptables -A POSTROUTING -t nat -s 10.8.0.0/24 -o eth0 -j MASQUERADE
# iptables -A FORWARD -i tun+ -j ACCEPT
# iptables -A INPUT -s 10.8.0.0/24 -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -p TCP -i eth0 --dport 10173 --sport 1024:65534 -j ACCEPT
# iptables -A INPUT -p UDP -i eth0 --dport 10173 --sport 1024:65534 -j ACCEPT
EOF

chmod +x /usr/local/bin/fired.sh

加入开机启动项

cat >> /etc/rc.d/rc.local <<EOF

# Firewall & Docker
/usr/bin/systemctl start iptables.service
/usr/local/bin/fired.sh
/usr/bin/systemctl start docker
EOF

chmod +x /etc/rc.d/rc.local

禁用相关服务自启动

# 注: Docker 启动时会自动加入一些

systemctl disable iptables.service
systemctl disable docker

使用 Docker 搭建 Gitlab + Jenkins + SonarQube 的 PHP 持续集成环境

对于开源 PHP 项目,现在比较成熟的一套持续集成方案是使用 Github + TravisCI + StyleCI + Scrutinizer + coveralls,不过这套方案如果想要用于私有项目的话就抓狂了,个个要买套餐,其中很多还不便宜。而且对于公司内使用的项目来说,内部搭建的 Gitlab 方案更为常见,对于这种情况,我们可以使用 Gitlab + Jenkins + SonarQube 来进行代替。

安装 SonarQube

$ docker pull postgres

$ docker run --name db -e POSTGRES_USER=sonar -e POSTGRES_PASSWORD=sonar -d postgres

$ docker pull sonarqube

$ docker run --name sq --link db -e SONARQUBE_JDBC_URL=jdbc:postgresql://db:5432/sonar -p 9000:9000 -d sonarqube

执行完毕上面的命令后通过浏览器进入 SonarQube,默认用户名和密码都是 admin,进去后会有一段引导,里面会让你生成一个 access token,这个后面的配置 Jenkins 时会用到。

如果没有记下来的话,可以点右上角的用户头像里面的 My Account > Security 标签中可以生成一个新的。

配置 Jenkins

Jenkins 需要在全局的 系统设置 里面添加 SonarQube Server,填下对应的访问地址和上一步获取的 access token 即可。服务器地址填写 localhost 可能会有问题,填 ip 会比较好些。

然后需要在 系统管理 的 Global Tool Configuration 菜单中配置 SonarQube Scanner 安装,这个直接选择自动安装就好了,十分方便。

这两步配好之后就到对应的项目配置中添加构建步骤,下拉选择 Execute SonarQube Scanner,然后对于 2.1 版本以上的 SonarQube Scanner 就只需要配置 Analysis properties 这一项就可以了,比较常用的参数包括 sonar.projectKey (用来确定 该项目在 SonarQube 中叫什么名字) 和 sonar.sources=(用来指定需要扫描的目录)。

配完之后选择构建即可,可以去当前构建的 Console Output 里面查看有没有报错,正常执行完成的话,在 SonarQube 项目面板中就可以看到一个新增的命名为配置的 sonar.projectKey 的 项目了。

注意点

  • SonarPHP 自定义检查规则需要用 java 来写扩展,比较新的版本内置了 psr2 的规则基本够用,内置的 Quality Profiles 是可以复制一个出来进行自定义的
  • Sonar 嗅探出的一些问题可能实际上并没有什么影响,比如变量名中含有 ‘pwd’ 等,如果原本使用方式确实合理则可适当忽略

用 Docker Compose 搭建 Rails 开发环境

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

这篇教程展示如何从零开始用 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.1.0.rc2'

然后,创建一个空的 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 配置如下:

development:
  <<: *default
  database: app_development
  host: db
  username: postgres

test:
  <<: *default
  database: app_test
  host: db
  username: postgres

现在可以启动 Rails 进程了:

$ docker-compose up

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

web_1  | => Booting Puma
web_1  | => Rails 5.1.0.rc2 application starting in development on http://0.0.0.0:3000
web_1  | => Run `rails server -h` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 3.8.2 (ruby 2.3.1-p112), codename: Sassy Salamander
web_1  | * Min threads: 5, max threads: 5
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop

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

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

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

用浏览器访问 http://localhost:3000 ,你会看到 Rails 的欢迎信息:

未分类

将 Dockerfile docker-compose.yml 与项目文件一并提交到版本控制里,这样新开发者参与项目的时候就可以用 docker-compose up 一键启动开发环境。