2016年11月23日星期三

Docker_012:构建使用 Jekyll 框架的网站

环境: MAC OS X 10.12.1 + Docker 1.12.3

该应用包括两个镜像:
(1)一个镜像安装了 Jekyll 及其用于构建 Jekyll 网站的必要的软件包。
(2)一个镜像安装了 Apache 来让 Jekyll 网站运行起来。
启动容器时
(1)从 Jekyll 镜像创建一个容器,通过卷挂载网站的源代码。
(2)从 Apache 镜像创建了一个容器,利用包含网站的编译后的源代码的卷。 

1. 构建 Jekyll 镜像
$ cd /Users/maping/mygit/dockerbook-code/code/6/jekyll/
$ cd jekyll
$ cat Dockerfile
FROM ubuntu:16.04
MAINTAINER James Turnbull
ENV REFRESHED_AT 2016-06-01

RUN apt-get -yqq update
RUN apt-get -yqq install ruby ruby-dev build-essential nodejs
RUN gem install --no-rdoc --no-ri jekyll -v 2.5.3

VOLUME /data
VOLUME /var/www/html
WORKDIR /data

ENTRYPOINT [ "jekyll", "build", "--destination=/var/www/html" ]

说明:
(1)使用 VOLUME 建立卷:/data,用来存放网站的源代码。
(2)使用 VOLUME 建立卷:/var/www/html,用来存放编译后的代码。
(3)设置工作目录为 /data
(4)ENTRYPOINT 指令执行编译。

$ docker build -t jamtur01/jekyll .
$ docker images

2. 构建 Apache 镜像
$ cd /Users/maping/mygit/dockerbook-code/code/6/jekyll/
$ cd apache
$ cat Dockerfile
FROM ubuntu:16.04
MAINTAINER James Turnbull

RUN apt-get -yqq update
RUN apt-get -yqq install apache2

VOLUME [ "/var/www/html" ]
WORKDIR /var/www/html

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2

RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIR

EXPOSE 80

ENTRYPOINT [ "/usr/sbin/apache2" ]
CMD ["-D", "FOREGROUND"]

说明:
(1)使用 VOLUME 建立卷:/var/www/html,用来存放编译后的代码。
(2)设置工作目录为 /var/www/html,用来存放编译后的代码。
(3)使用 ENV 设置必要的环境变量
(4)公开 80 端口
(5)ENTRYPOINT 指令启动 Apache

$ docker build -t jamtur01/apache .
$ docker images

3. 启动 Jekyll
$ cd /Users/maping/mygit
$ git clone https://github.com/jamtur01/james_blog.git
$ docker run  -v /Users/maping/mygit/james_blog:/data/ --name james_blog jamtur01/jekyll

输出如下:
Configuration file: /data/_config.yml
            Source: /data
       Destination: /var/www/html
      Generating...
                    done.
 Auto-regeneration: disabled. Use --watch to enable.


说明:把宿主机的 james_blog 目录作为源代码 /data/卷挂载到容器里。容器拿到源代码后,编译,然后存放到 /var/www/html/ 目录,然后容器停止。
卷在 Docker 宿主机的 /var/lib/docker/volumes 目录中,我是 MAC,没有此目录,应该被“转义”了。
要查看某个卷的具体位置,可以使用如下命令:

$ docker inspect -f "{{ .Config.Volumes }}" james_blog
map[/data:{} /var/www/html:{}]

4. 启动 Apache
$ docker run -d -P --volumes-from james_blog jamtur01/apache
5d55d8dc426ff94bbdd610dcbcbe0a65733df224fd5a9856ed1224ba44829853
说明:--volumes-from 把指定容器里的所有卷都加入新创建的容器里。
这意味着,Apache 容器可以访问之前创建的 james_blog 容器里的 /var/www/html 卷中的编译后的代码。
前提是 james_blog 容器必须存在,可以不运行,但必须存在。

$ docker port 80
$ docker port 5d55d8dc426ff94bbdd610dcbcbe0a65733df224fd5a9856ed1224ba44829853 80
0.0.0.0:32768
访问 http://localhost:32768


现在 Jekyll 网站终于运行起来了。

5. 更新代码
$ cd /Users/maping/mygit/james_blog
$ vim _config.yml
修改 title 域为 James' Dynamic Docker-driven Blog。

那么如何才能更新博客网站呢?只需要再次启动 james_blog 网站。
$ docker start james_blog

看上去什么都没发生,查看一下容器日志
$ docker logs james_blog
输出如下:
Configuration file: /data/_config.yml
            Source: /data
       Destination: /var/www/html
      Generating...
                    done.
 Auto-regeneration: disabled. Use --watch to enable.
Configuration file: /data/_config.yml
            Source: /data
       Destination: /var/www/html
      Generating...
                    done.
 Auto-regeneration: disabled. Use --watch to enable.
可以看到进行了第 2 次编译,并且将更新写入了对应的卷。

不用重启 Apache 容器,直接刷新访问 http://localhost:32768

6. 备份 Jekyll 应用卷
$ docker run --rm --volumes-from james_blog \
-v $(pwd):/backup ubuntu \
tar cvf /backup/james_blog_backup.tar /var/www/html
说明:--rm 参数表示只用一次的容器,用完即扔的容器。
该方法很简单,只要把卷挂载到新容器,完成备份,然后废弃这个用于备份的容器就可以了。

7. 进一步扩展 Jekyll 应用
(1)运行多个 Apache 容器,这些容器都使用来自 james_blog 容器的卷,组成一个 Web 集群。
(2)构建一个新镜像,该镜像把用户提供的源代码复制(比如 git clone)到卷里,再把这个卷挂载到 JekyII 镜像创建的容器,这样宿主机上就不需要包含任何源代码。
(3)构建一个 Web 前端,该服务从指定的源自动构建和部署网站。

没有评论: