Docker实践笔记三:用Docker搭建hg-server
一,可以使用 docker pull 命令来从仓库获取所需要的镜像。 下面的例子将从 Docker Hub 仓库下载一个 Ubuntu 12.04 操作系统的镜像。
$ sudo docker pull ubuntu:12.04
Pulling repository ubuntu
ab8e2728644c: Pulling dependent layers
511136ea3c5a: Download complete
5f0ffaa9455e: Download complete
a300658979be: Download complete
904483ae0c30: Download complete
ffdaafd1ca50: Download complete
d047ae21eeaf: Download complete
下载过程中,会输出获取镜像的每一层信息。
该命令实际上相当于 $ sudo docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服
务器 registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。
有时候官方仓库注册服务器下载较慢,可以从其他仓库下载。 从其它仓库下载时需要指定完整的仓库注册
服务器地址。例如
$ sudo docker pull dl.dockerpool.com:5000/ubuntu:12.04
Pulling dl.dockerpool.com:5000/ubuntu
ab8e2728644c: Pulling dependent layers
511136ea3c5a: Download complete
5f0ffaa9455e: Download complete
a300658979be: Download complete
904483ae0c30: Download complete
ffdaafd1ca50: Download complete
d047ae21eeaf: Download complete
完成后,即可随时使用该镜像了,例如创建一个容器,让其中运行 bash 应用。
$ sudo docker run -t -i ubuntu:12.04 /bin/bash
aaa@qq.com:/#
二,列出本地镜像
使用 docker images 显示本地已有的镜像。
[aaa@qq.com ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 12.04 5b117edd0b76 16 months ago 104MB
training/sinatra latest 49d952a36c58 4 years ago 447MB
在列出信息中,可以看到几个字段信息
来自于哪个仓库,比如 ubuntu
镜像的标记,比如 14.04
它的 ID 号(唯一)
创建时间
镜像大小
其中镜像的 ID 唯一标识了镜像,注意到 ubuntu:14.04 和 ubuntu:trusty 具有相同的镜像 ID ,说明
它们实际上是同一镜像。
TAG 信息用来标记来自同一个仓库的不同镜像。例如 ubuntu 仓库中有多个镜像,通过 TAG 信息来区分
发行版本,例如 10.04 、 12.04 、 12.10 、 13.04 、 14.04 等。例如下面的命令指定使用镜像
ubuntu:14.04 来启动一个容器。
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
如果不指定具体的标记,则默认使用 latest 标记信息。
三,创建镜像
创建镜像有很多方法,用户可以从 Docker Hub 获取已有镜像并更新,也可以利用本地文件系统创建一个。
先使用下载的镜像启动容器。
$ sudo docker run -t -i training/sinatra /bin/bash
aaa@qq.com@512d79e0f46f:/#
注意:记住容器的 ID,稍后还会用到。
在容器中添加 json 和 gem 两个应用。
aaa@qq.com:/# gem install json
[aaa@qq.com ~]# sudo docker run -t -i training/sinatra /bin/bash
aaa@qq.com:/# gem install json
Fetching: json-2.1.0.gem (100%)
Building native extensions. This could take a while...
Successfully installed json-2.1.0
1 gem installed
Installing ri documentation for json-2.1.0...
Installing RDoc documentation for json-2.1.0...
当结束后,我们使用 exit 来退出,现在我们的容器已经被我们改变了,使用 docker commit 命令来提交
更新后的副本。
$ sudo docker commit -m "Added json gem" -a "Docker Newbee" 512d79e0f46f ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
[aaa@qq.com ~]# sudo docker commit -m "Added json gem" -a "Docker Newbee" 512d79e0f46f ouruser/sinatra:v2
sha256:7f90a6936ad1c9a4df3a7439a2123235cdf9af39b63f0270d74f7a6fac2f5ff1
[aaa@qq.com ~]# 4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
其中, -m 来指定提交的说明信息,跟我们使用的版本控制工具一样; -a 可以指定更新的用户信息;之
后是用来创建镜像的容器的 ID;最后指定目标镜像的仓库名和 tag 信息。创建成功后会返回这个镜像的 ID
信息。
使用 docker images 来查看新创建的镜像。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
training/sinatra latest 5bc342fa0b91 10 hours ago 446.7 MB
ouruser/sinatra v2 3c59e02ddd1a 10 hours ago 446.7 MB
ouruser/sinatra latest 5db5f8471261 10 hours ago 446.7 MB
[aaa@qq.com ~]# sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ouruser/sinatra v2 7f90a6936ad1 About a minute ago 453MB
<none> <none> a1759e386948 About a minute ago 453MB
ubuntu 12.04 5b117edd0b76 16 months ago 104MB
training/sinatra latest 49d952a36c58 4 years ago 447MB
之后,可以使用新的镜像来启动容器
$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
aaa@qq.com:/#
一、安装 用Docker搭建hg-server
用hg为关键词搜索,得出以下结果:
$ docker search hg
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
hgomez/gatling 1 [OK]
v7soft/hgdns 0 [OK]
hg8496/gridvis-service 0 [OK]
hgomez/di-centos6-myjenkins-lts 0 [OK]
jrandall/hgi-project 0 [OK]
hgomez/di-centos6-myartifactory 0 [OK]
hgomez/di-centos6-myjenkins 0 [OK]
hgomez/di-centos6-mynexus 0 [OK]
hgomez/di-centos6-myarchiva 0 [OK]
hg8496/piwigo 0 [OK]
hg8496/apache 0 [OK]
hgomez/di-centos6-mygitblit 0 [OK]
hgomez/di-centos6-mygitbucket 0 [OK]
jyotisingh/ubuntu-hg 0
hg8496/dokuwiki 0 [OK]
hg8496/owncloud 0 [OK]
misshie/ucsc-blat-hg19 0 [OK]
ussie/hg-exec adds mercurial to ubuntu:14.04. 0
misshie/ucsc-blat-hg38 0 [OK]
hg8496/gridvis-pc 0 [OK]
Test. Automated builds for this repo are b... 0 [OK]
hg8496/rsync 0 [OK]
secondbit/hgbundler 0
uotbw/hgamer3d Docker image for hgamer3d, see www.hgamer3... 0
hgomez/di-centos6-base 0 [OK]
hgweb貌似不错的选择,在github上的主页是https://github.com/amclain/docker-hgweb 。
将其pull下来,在漫长的等待中我也在思考着如何启动它。
主页上提供了它的Dockerfile,通过它我们就可以了解这个image是如果构造的。先来说说什么是Dockerfile。
Dockerfile 中每一条指令都创建镜像的一层,例如:
# This is a comment
FROM ubuntu:14.04
MAINTAINER Docker Newbee <aaa@qq.com>
RUN apt-get -qq update
RUN apt-get -qqy install ruby ruby-dev
RUN gem install sinatra
Dockerfile 基本的语法是
使用 # 来注释
FROM 指令告诉 Docker 使用哪个镜像作为基础
接着是维护者的信息
RUN 开头的指令会在创建中运行,比如安装一个软件包,在这里使用 apt-get 来安装了一些软件
编写完成 Dockerfile 后可以使用 docker build 来生成镜像。
$ sudo docker build -t="ouruser/sinatra:v2" .
Uploading context 2.56 kB
Uploading context
Step 0 : FROM ubuntu:14.04
---> 99ec81b80c55
Step 1 : MAINTAINER Newbee <aaa@qq.com>
---> Running in 7c5664a8a0c1
---> 2fa8ca4e2a13
Removing intermediate container 7c5664a8a0c1
Step 2 : RUN apt-get -qq update
---> Running in b07cc3fb4256
---> 50d21070ec0c
Removing intermediate container b07cc3fb4256
Step 3 : RUN apt-get -qqy install ruby ruby-dev
---> Running in a5b038dd127e
Selecting previously unselected package libasan0:amd64.
(Reading database ... 11518 files and directories currently installed.)
Preparing to unpack .../libasan0_4.8.2-19ubuntu1_amd64.deb ...
Setting up ruby (1:1.9.3.4) ...
Setting up ruby1.9.1 (1.9.3.484-2ubuntu1) ...
Processing triggers for libc-bin (2.19-0ubuntu6) ...
---> 2acb20f17878
Removing intermediate container a5b038dd127e
Step 4 : RUN gem install sinatra
---> Running in 5e9d0065c1f7
其中 -t 标记来添加 tag,指定新的镜像的用户信息。 “.” 是 Dockerfile 所在的路径(当前目录),也可以
替换为一个具体的 Dockerfile 的路径。
可以看到 build 进程在执行操作。它要做的第一件事情就是上传这个 Dockerfile 内容,因为所有的操作都要
依据 Dockerfile 来进行。 然后,Dockfile 中的指令被一条一条的执行。每一步都创建了一个新的容器,在
容器中执行指令并提交修改(就跟之前介绍过的 docker commit 一样)。当所有的指令都执行完毕之
后,返回了最终的镜像 id。所有的中间步骤所产生的容器都被删除和清理了。
*注意一个镜像不能超过 127 层
此外,还可以利用 ADD 命令复制本地文件到镜像;用 EXPOSE 命令来向外部开放端口;用 CMD 命令来
描述容器启动后运行的程序等。例如
# put my local web site in myApp folder to /var/www
ADD myApp /var/www
# expose httpd port
EXPOSE 80
# the command to run
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
现在可以利用新创建的镜像来启动一个容器。
$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
aaa@qq.com:/#
还可以用 docker tag 命令来修改镜像的标签。
二、Dockerfile
它是用户创建自定义镜像的文件。它通常分为四部分:基础镜像信息,维护者信息,镜像操作指令和容器启动时的指令。
#基础系统信息,基于ubuntu 14.04构建的
FROM ubuntu:14.04
MAINTAINER Alex McLain <aaa@qq.com>
RUN apt-get -qq update
#安装apache、hg、php5
RUN apt-get -y install apache2 apache2-utils curl mercurial php5 php5-cli php5-mcrypt
# TODO: Remove
#是的,vim确实很大,不安装为好
RUN apt-get -y install vim
RUN echo "colorscheme delek" > ~/.vimrc
# Configure hgweb
ADD hg/add.php /etc/default/hgweb/hg/
ADD hg/hgweb.config /etc/default/hgweb/hg/
ADD hg/hgweb.cgi /etc/default/hgweb/hg/
ADD hg/hgusers /etc/default/hgweb/hg/
# Configure Apache
ADD apache/hg.conf /etc/default/hgweb/apache/
RUN rm /etc/apache2/sites-enabled/*
RUN a2enmod rewrite && a2enmod cgi
ADD load-default-scripts /bin/
RUN chmod u+x /bin/load-default-scripts
#创建一个挂载点,本机或其他容器可以将其挂载。启动时用-v参数进行挂载
VOLUME /var/hg
VOLUME /etc/apache2/sites-available
#暴露的端口号,启动时要通过-p参数指定
EXPOSE 80
#启动时执行的命令
CMD load-default-scripts && service apache2 start && /bin/bash
三、启动
有了上述的背景,我们知道启动时要做两件事:指定端口号、挂载本地目录。
比如还是使用端口号80,那么只需用 -p 80:80即可。
比如本机目录hg-repos用来做hg repo的放置目录,只需 -v /home/linc/hg-repos:/var/hg/repos 挂载即可。
另外,我们还要将其启动在后台(Daemonized),加上-d参数。
完整启动命令如下:
docker run -idt -p 80:80 -v /home/linc/hg-repos:/var/hg/repos amclain/hgweb
四、与后台容器交互
1.attach方法
docker 自带attach命令,但此命令的不方便之处在于,多个窗口(同时attach此容器)会同步显示操作,并且当一个窗口exit时,所有窗口都会退出,后台运行的容器也停止了。
2.nsenter
此工具需要从源码安装:
$ cd /tmp;
$ curl https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.32/util-linux-2.32.tar.gz | tar -zxf-;
$ cd util-linux-2.32;
# 这个是你的CentOS少了C语言的编译器,要先安装C语言的编译器,建议执行命令:
$ yum install gcc
#安装完 gcc,然后再安装你要安装的软件,试试。
$ ./configure --without-ncurses
$ make nsenter && sudo cp nsenter /usr/local/bin
直接用nsenter命令交互很繁琐,然后有人写了配置文件放到bashrc中,就可以方便的使用了。
在/home/usr下面 直接用vi创建.bashrc文件
#docker
export DOCKER_HOST=tcp://localhost:4243
alias docker-pid="sudo docker inspect --format '{{.State.Pid}}'"
alias docker-ip="sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}'"
#the implementation refs from https://github.com/jpetazzo/nsenter/blob/master/docker-enter
function docker-enter() {
if [ -e $(dirname "$0")/nsenter ]; then
# with boot2docker, nsenter is not in the PATH but it is in the same folder
NSENTER=$(dirname "$0")/nsenter
else
NSENTER=nsenter
fi
[ -z "$NSENTER" ] && echo "WARN Cannot find nsenter" && return
if [ -z "$1" ]; then
echo "Usage: `basename "$0"` CONTAINER [COMMAND [ARG]...]"
echo ""
echo "Enters the Docker CONTAINER and executes the specified COMMAND."
echo "If COMMAND is not specified, runs an interactive shell in CONTAINER."
else
PID=$(sudo docker inspect --format "{{.State.Pid}}" "$1")
if [ -z "$PID" ]; then
echo "WARN Cannot find the given container"
return
fi
shift
OPTS="--target $PID --mount --uts --ipc --net --pid"
if [ -z "$1" ]; then
# No command given.
# Use su to clear all host environment variables except for TERM,
# initialize the environment variables HOME, SHELL, USER, LOGNAME, PATH,
# and start a login shell.
#sudo $NSENTER "$OPTS" su - root
sudo $NSENTER --target $PID --mount --uts --ipc --net --pid su - root
else
# Use env to clear all host environment variables.
sudo $NSENTER --target $PID --mount --uts --ipc --net --pid env -i aaa@qq.com
fi
fi
}
其中有两个alias和一个function,使用docker-enter会很容易于容器交互并没有attach中的副作用。如下:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
beb178cd9335 amclain/hgweb:latest "/bin/sh -c 'load-de 11 seconds ago Up 10 seconds 0.0.0.0:80->80/tcp stoic_yonath
$ docker-enter beb178cd9335
aaa@qq.com:~# ls
aaa@qq.com:~# pwd
/root
五、快速启动hg-server
写个alias放子bashrc中,如下:
alias docker-load-hg-server="sudo docker run -idt -p 80:80 -v /home/linc/hg-repos:/var/hg/repos amclain/hgweb"
启动它:
$ docker-load-hg-server
[sudo] password for linc:
beb178cd933502970fd12d9a4babecef5475a52d85a207066c665b4a620c5a62
改进
对于文件的挂载,其实直接挂镜像的/var/hg更好,这样里面的几个配置文件如hgusers hgweb.cgi hgweb.config,我们可以直接进行配置。
sudo docker run -idt -p 80:80 -v /home/linc/hg-repos:/var/hg amclain/hgweb
上一篇: 多图上传图片地址存放有关问题