Docker实践笔记三:用Docker搭建hg-server

版权声明:欢迎交流,欢迎转载,大家转载注明出处,禁止用于商业目的。 https://blog.csdn.net/Xiaotongbiji/article/details/81981739

一,可以使用 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
root@fe7fc4bd8fc9:/#

二,列出本地镜像

使用 docker images 显示本地已有的镜像。

[root@localhost ~]# 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
root@@512d79e0f46f:/#
注意:记住容器的 ID,稍后还会用到。
在容器中添加 json 和 gem 两个应用。
root@512d79e0f46f:/# gem install json

[root@localhost ~]# sudo docker run -t -i training/sinatra /bin/bash
root@512d79e0f46f:/# 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

[root@localhost ~]# sudo docker commit -m "Added json gem" -a "Docker Newbee" 512d79e0f46f ouruser/sinatra:v2
sha256:7f90a6936ad1c9a4df3a7439a2123235cdf9af39b63f0270d74f7a6fac2f5ff1
[root@localhost ~]# 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

[root@localhost ~]# 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
root@b0028c643781:/#

一、安装 用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 <[email protected]>
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 <[email protected]>
---> 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
root@8196968dac35:/#

还可以用 docker tag 命令来修改镜像的标签。

二、Dockerfile

它是用户创建自定义镜像的文件。它通常分为四部分:基础镜像信息,维护者信息,镜像操作指令和容器启动时的指令。

#基础系统信息,基于ubuntu 14.04构建的
FROM ubuntu:14.04
MAINTAINER Alex McLain <[email protected]>
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 $@
        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
root@beb178cd9335:~# ls
root@beb178cd9335:~# 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

猜你喜欢

转载自blog.csdn.net/Xiaotongbiji/article/details/81981739