在Mac OS X下使用Docker 0.8安装Ruby环境

前不久(2014年2月4日)Docker 0.8发布了,对OS X的支持也更好了。由于Docker基于LXC技术,所以非Linux内核的系统很难使用Docker,如果想用的话,必须要装虚拟机软件来模拟运行Linux。不过OS X怎么说也是基于BSD的,跟Linux即使算不上兄弟,也算近亲吧。下面我们就按照官方文档来试着在Mac 下用一下Docker吧。

(实际上还是用到了虚拟机:-()

在本文里我们将完成两部分工作:

  1.  在最新版的Mac OS X下安装Docker 0.8
  2.  创建一个安装了Ruby 2.1的镜像,并且发布到官网仓库(index服务)

本文将不会涉及到docker各命令的具体说明。

1. 安装VirtualBox

这是前提条件,请到
https://www.virtualbox.org/wiki/Downloads 下载并安装VirtualBox,这里就不多说了。

2. 安装 boot2docker

一个非常精简的Linux发布版本。

$ curl https://raw.github.com/steeve/boot2docker/master/boot2docker > boot2docker
$ chmod +x boot2docker
$ sudo cp boot2docker /usr/local/bin

或者随便放到哪里。如果不加到PATH里,运行的时候要记得写全路径。

$ which boot2docker
/usr/local/bin/boot2docker

3. 安装docker

非常简单,按照官方指南,只需要简单的几步

下载软件:

$ curl -o docker http://get.docker.io/builds/Darwin/x86_64/docker-latest

Docker客户端软件有12M左右,需要一点时间。

下载后,修改权限,并且拷贝到哪里,或者加到PATH里。

$ chmod +x docker
$ sudo cp docker /usr/local/bin/

另外记得把这个加到~/.profile里去:

export DOCKER_HOST=tcp://

拷贝之后,确认一下。

$ docker version
Client version: 0.8.0
Go version (client): go1.2
Git commit (client): cc3a8c8

4. 初始化VM

下面来初始化boot2docker自带的虚拟机。这通过执行boot2docker init命令。

这条命令首先会从网上下载虚拟机镜像文件boot2docker.iso,并保存到~/.boot2docker下。下载后,将会创建VBOX虚拟机。

$ boot2docker init

[2014-02-12 16:42:10] Creating VM boot2docker-vm
Virtual machine ‘boot2docker-vm’ is created and registered.
UUID: 45d4b96e-54f1-4783-82d8-024d45c0407c
Settings file: ‘/Users/liubin/VirtualBox VMs/boot2docker-vm/boot2docker-vm.vbox’
[2014-02-12 16:42:10] Setting VM settings
[2014-02-12 16:42:11] Setting VM networking
[2014-02-12 16:42:11] boot2docker.iso not found.
[2014-02-12 16:42:16] Latest version is v0.5.4, downloading…
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 346 100 346 0 0 147 0 0:00:02 0:00:02 –:–:– 147
100 27.0M 100 27.0M 0 0 14355 0 0:32:52 0:32:52 –:–:– 20296
[2014-02-12 17:15:09] Done
[2014-02-12 17:15:09] Setting VM disks
[2014-02-12 17:15:10] Creating 40000 Meg hard drive…
0%…10%…20%…30%…40%…50%…60%…70%…80%…90%…100%
Disk image created. UUID: 75eee446-3842-4cb5-a9f8-0360bbf6ed3b
Converting from raw image file=”format-flag.txt” to file=”format-flag.vmdk”…
Creating dynamic image with size 5242880 bytes (5MB)…
0%…10%…20%…30%…40%…50%…60%…70%…80%…90%…100%
Clone hard disk created in format ‘VMDK’. UUID: 75eee446-3842-4cb5-a9f8-0360bbf6ed3b
[2014-02-12 17:15:11] Done.
[2014-02-12 17:15:11] You can now type boot2docker up and wait for the VM to start.

虚拟机创建之后,我们就可以启动它了。

$ boot2docker up
[2014-02-12 17:16:26] Starting boot2docker-vm…
[2014-02-12 17:16:45] Started.

我们也可以通过执行boot2docker命令不加任何参数来获得它可接受的参数列表。

当然,我们也可以SSH进去。用户密码分别是docker/tcuser

SSH进去之后,我们可以确认在虚拟机里,Docker的守护进程正在运行。

$ ps -ef | grep docker

541 root /usr/local/bin/docker -d -D -g /mnt/sda1/var/lib/docker -H unix:// -H tcp://

5. 在Mac里使用Docker客户端

Docker可以认为是一个C/S结构的实现,客户端和守护进程通过API来交互。客户端操作都在Mac端进行。

从刚才的虚拟机里退出到Mac下,试试常用的几个命令,比如docker images,当然,结果是什么都没有。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

下面我们需要取得Docker镜像。你也可以认为Docker镜像是一个虚拟机镜像,不过它更轻量,与宿主机器共享内核空间。执行一个镜像之后,这个镜像就变成了一个容器,并且容器处于运行状态。这时候的容器里所有发生的从启动它的镜像的变更,可以像git一样commit。一旦commit,这个容器又变成了一个镜像。可以认为容器和镜像是一动一静的关系,并且相互转化。

$ docker pull ubuntu

这将从远程仓库下载ubuntu镜像下来。过程很漫长,网络要足够好,且要有足够耐心。

注:如果你不手动下载镜像,当你通过docker run ubuntu bash的时候,Docker也会自动下载这个镜像的。

下载后我们可以看到如下结果。

$ docker images REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE ubuntu              13.10               9f676bd305a4        10 days ago         178 MB ubuntu              saucy               9f676bd305a4        10 days ago         178 MB ubuntu              raring              eb601b8965b8        10 days ago         166.5 MB ubuntu              13.04               eb601b8965b8        10 days ago         166.5 MB ubuntu              12.10               5ac751e8d623        10 days ago         161 MB ubuntu              quantal             5ac751e8d623        10 days ago         161 MB ubuntu              10.04               9cc9ea5ea540        10 days ago         180.8 MB ubuntu              lucid               9cc9ea5ea540        10 days ago         180.8 MB ubuntu              12.04               9cd978db300e        10 days ago         204.4 MB ubuntu              latest              9cd978db300e        10 days ago         204.4 MB ubuntu              precise             9cd978db300e        10 days ago         204.4 MB

简单使用。

启动一个容器,只需要docker run命令,后面跟一个镜像(仓库或标签)的名字和要执行的命令。比如这里我们执行3次下面的命令

$ docker run ubuntu /bin/echo hello world
hello world
$ docker run ubuntu /bin/echo hello world
hello world
$ docker run ubuntu /bin/echo hello world
hello world

docker ps 是用来查看容器列表,-a表示常看所有容器。

$ docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
67bdbcd9fe92 ubuntu:12.04 /bin/echo hello worl 5 seconds ago Exit 0 stoic_mclean
fd61245a221a ubuntu:12.04 /bin/echo hello worl 7 seconds ago Exit 0 kickass_davinci
c4a2aefb7cab ubuntu:12.04 /bin/echo hello worl 11 seconds ago Exit 0 kickass_morse

可以看出,每次执行(docker run)一次,都会生成一个新的容器。

我们可以通过shell登录进容器(实际上是运行bash命令)

$ docker run -t -i ubuntu bash
root@70aa22ed4fa6:/# uname -a
Linux 70aa22ed4fa6 3.12.1-tinycore64 #1 SMP Fri Jan 10 13:04:04 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

连Ruby也没装,真简洁。我们可以选择其它的已经预装了可信的镜像,也可以自己安装。由于是初学,这里我们来自己安装。可以自己在这个shell里安装,再保存此容器(通过docker commit命令)。不过我们这里将以Dockerfile为例进行说明。

6. 创建Docker镜像

创建一个镜像文件有大概三种方法:

  1. 启动一个作为base的镜像,直接通过shell做些操作,之后commit这个容器。
  2. 通过官方的可信构建(Trusted Builds)
  3. 基于Dockerfile

这里我们通过Dockerfile来创建一个镜像。Dockerfile不是文件类型的名字,而是文件名。

首先创建一个ruby2.1的目录,并在这下面创建一个名为Dockerfile的文件,其内容如下:

# 基于ubuntu仓库的镜像
FROM ubuntu

# 维护者信息,供别人参考
MAINTAINER bin liu “liubin0329@gmail.com”

# 每次RUN都可以执行一条命令
RUN apt-get update
RUN apt-get install -y –force-yes build-essential curl git
RUN apt-get install -y –force-yes zlib1g-dev libssl-dev libreadline-dev libyaml-dev libxml2-dev libxslt-dev
RUN apt-get clean

# Install rbenv and ruby-build
RUN git clone https://github.com/sstephenson/rbenv.git /.rbenv
RUN git clone https://github.com/sstephenson/ruby-build.git /.rbenv/plugins/ruby-build
RUN /.rbenv/plugins/ruby-build/install.sh

# 设置启动后的环境变量
ENV PATH /.rbenv/bin:/.rbenv/shims:$PATH

# Install multiple versions of ruby
ENV CONFIGURE_OPTS –disable-install-doc

RUN rbenv install 2.1.0-rc1

# make it as default Ruby
RUN rbenv global 2.1.0-rc1

# Install Bundler for each version of ruby
RUN echo ‘gem: –no-rdoc –no-ri’ >> /.gemrc

RUN gem install bundler && rbenv rehash

Dockerfile里每行大写字母开头的单词称为指令(INSTRUCTION),其后面的称为参数。注释以#开头。其余的就不解释了,如果有Linux基础的,且英语单词也认识几个的话,应该都能猜个八九不离十吧。

然后,执行构建工作,这通过docker build命令完成。

注意命令最后面的点,它表示当前目录,即去哪里找Dockerfile文件,不要忘了。另外,构建成功后,这个目录下也不会多出来什么东西。具体都是在Docker daemon来负责的。

$ docker build -t liubin/ruby2.1.0 .
Uploading context 3.072 kB
Uploading context
Step 0 : FROM ubuntu
—> 9cd978db300e
Step 1 : MAINTAINER bin liu “liubin0329@gmail.com”
—> Using cache
—> c3db92e4d985
Step 2 : RUN apt-get update
—> Using cache
—> a281f7c61e6a
Step 3 : RUN apt-get install -y –force-yes build-essential curl git
—> Using cache
—> 2ce22aa32145
Step 4 : RUN apt-get install -y –force-yes zlib1g-dev libssl-dev libreadline-dev libyaml-dev libxml2-dev libxslt-dev
—> Using cache
—> 81804c2281a2
Step 5 : RUN apt-get clean
—> Using cache
—> 25ccf3e52f63
Step 6 : RUN git clone https://github.com/sstephenson/rbenv.git /.rbenv
—> Using cache
—> a6a1fc096368
Step 7 : RUN git clone https://github.com/sstephenson/ruby-build.git /.rbenv/plugins/ruby-build
—> Using cache
—> d83e658c52ca
Step 8 : RUN /.rbenv/plugins/ruby-build/install.sh
—> Using cache
—> d0ba0a069014
Step 9 : ENV PATH /.rbenv/bin:/.rbenv/shims:$PATH
—> Using cache
—> 15622ffffa55
Step 10 : ENV CONFIGURE_OPTS –disable-install-doc
—> Using cache
—> 14b8dd49c3fb
Step 11 : RUN rbenv install 2.1.0-rc1
—> Using cache
—> 18e255aefa3c
Step 12 : RUN rbenv global 2.1.0-rc1
—> Using cache
—> 751e43f46e13
Step 13 : RUN echo ‘gem: –no-rdoc –no-ri’ >> /.gemrc
—> Using cache
—> 57360db5a732
Step 14 : RUN gem install bundler && rbenv rehash
—> Using cache
—> 7776d1c8a87e
Successfully built 7776d1c8a87e

我在这个例子里执行构建镜像的时候,中间出过几次错误,上面的输出是我最后执行的结果,所以你看到的都是类似:

—> Using cache
—> 57360db5a732

这样的东西。Dockerfile的每步操作都会执行一个提交,即上面的57360db5a732这样的ID。当Dockerfile里的命令之前执行过的时候,就会使用cache,而不必每次都去真的再执行一遍了。

我们可以通过docker images命令来看看构建结果:

$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
liubin/ruby2.1.0 latest 7776d1c8a87e 32 minutes ago 529.4 MB

看看它的大小,有500多M,看起来也不怎么轻量。

镜像创建后,我们再来看看Ruby2.1是否正常安装了。

$ docker run liubin/ruby2.1.0 ruby -e “3.times do puts ‘hello ruby in docker’ end”
hello ruby in docker
hello ruby in docker
hello ruby in docker

恩,看来Ruby已经安装好了。

7. 发布Docker镜像

OK!既然Ruby正常安装了,下面我们准备发布这个镜像吧。(实际上这个镜像也许没有什么用处,这里只是作为例子讲解一下。)

首先,你要有官方索引仓库网站(https://index.docker.io/)的账号。如果没有,可以先从这里(https://www.docker.io/account/signup/)申请一个。

账号注册好之后,就可以准备发布这个镜像了。发布自己的镜像需要使用docker push命令。

首先需要login到官方仓库的索引(index)服务。

$ docker login
Username: liubin
Password:
Email: XXXX@gmail.com
Login Succeeded

然后执行docker push命令即可。

psuh过程也很费时,有几个镜像的大小超过了100M,见下图

全部过程如下:

$ docker push liubin/ruby2.1.0
The push refers to a repository [liubin/ruby2.1.0] (len: 1)
Sending image list
Pushing repository liubin/ruby2.1.0 (1 tags)
511136ea3c5a: Image already pushed, skipping
Image 6170bb7b0ad1 already pushed, skipping
Image 9cd978db300e already pushed, skipping
c3db92e4d985: Image successfully pushed
a281f7c61e6a: Image successfully pushed
2ce22aa32145: Image successfully pushed
81804c2281a2: Image successfully pushed
25ccf3e52f63: Image successfully pushed
a6a1fc096368: Image successfully pushed
d83e658c52ca: Image successfully pushed
d0ba0a069014: Image successfully pushed
15622ffffa55: Image successfully pushed
14b8dd49c3fb: Image successfully pushed
18e255aefa3c: Image successfully pushed
751e43f46e13: Image successfully pushed
57360db5a732: Image successfully pushed
7776d1c8a87e: Image successfully pushed
Pushing tag for rev [7776d1c8a87e] on {https://registry-1.docker.io/v1/repositories/liubin/ruby2.1.0/tags/latest}

这个过程也很漫长,因为镜像文件总大小估计也要500M左右。

docker push执行成功之后,我们就可以在官网上看到这个镜像了,如下图所示。



上传到官方网站的镜像都是公开的,别人可以通过右上角显示的命令(docker pull liubin/ruby2.1.0)下载这个镜像来使用了。

–全文完–

参考资料:

1. 官方安装说明 http://docs.docker.io/en/latest/installation/mac/
2. boot2docker主页 https://github.com/steeve/boot2docker
3 Docker image installed multiple versions of ruby https://coderwall.com/p/s0dstw
4 Dockerfile Reference http://docs.docker.io/en/latest/reference/builder/



Posted in go, Tech Tagged with: , , , , , , ,

无觅相关文章插件,快速提升流量