欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-03 10:02:03
...

一,可以使用 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

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

 四、与后台容器交互

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

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

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

 直接用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
相关标签: docker hg-server