构建第一个应用

要构建的第一个应用是Jekyll框架的自定义网站。我们会构建一下两个镜像。

  • 一个镜像安装Jekyll以及其他用于构建Jekyll网站的必要的软件包。
  • 一个镜像通过Apache来让Jekyll网站工作起来。

在启动容器时,通过创建一个新的Jekyll网站来实现自服务。工作流程如下:

  • 创建Jekyll基础镜像和Apache镜像(只需要构建一次)。
  • 从Jekyll镜像创建一个容器,这个容器存放通过卷挂载的网址源代码。
  • 从Apache镜像创建一个容器,这个容器利用包含编译后的网站的卷,并为其服务。
  • 在网站需要更新时,清理并重复上面的步骤。

可以把这个例子看做是创建一个多主机站点最简单的方法。

构建Jekyll镜像

创建Dockerfile:

  1. # mkdir /opt/jekyll
  2. # cd /opt/jekyll
  3. # vim Dockerfile
  4.  
  5. FROM ubuntu:latest
  6. MAINTAINER Bourbon Tian "bourbon@1mcloud.com"
  7. ENV REFRESHED_AT 2017-06-13
  8.  
  9. RUN apt-get -qq update
  10. RUN apt-get -qq install ruby ruby-dev build-essential nodejs
  11. RUN gem install --no-rdoc --no-ri jekyll -v 2.5.3
  12.  
  13. VOLUME /data
  14. VOLUME /var/www/html
  15. WORKDIR /data
  16.  
  17. ENTRYPOINT [ "jekyll", "build", "--destination=/var/www/html" ]

镜像基于Ubuntu:latest,并且安装ruby和用于支持Jekyll的包。然后通过VOLUME指令创建了以下两个卷。

  • /data 用来存放网站的源代码
  • /var/www/html 用来存放编译后的Jekyll网站码

然后将工作目录设置到/data/,并通过ENTRYPOINT指令指定自动构建的命令,这个命令会将工作目录/data/中所有的Jekyll网站代码构建到/var/www/html/目录中。

构建Jekyll基础镜像

通过Dockerfile,可以使用docker build命令构建出可以启动容器的镜像。

  1. # docker build -t test/jekyll .
  2. Sending build context to Docker daemon 1.691 MB
  3. Sending build context to Docker daemon
  4. Step 0 : FROM ubuntu:latest
  5. ---> db12a182ded0
  6. Step 1 : MAINTAINER Bourbon Tian "bourbon@1mcloud.com"
  7. ---> 6c517b49846f
  8. ...
  9. Successfully built c8ea1e6c398b

这里就构建了一个名为test/jekyll、ID为c8ea1e6c398b的新镜像。我们可以通过docker images命令来查看:

  1. # docker images
  2. REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
  3. test/jekyll latest c8ea1e6c398b About an hour ago 455.3 MB

构建Apache镜像

创建Dockerfile:

  1. # mkdir /opt/apache
  2. # cd /opt/apache
  3. # vim Dockerfile
  4.  
  5. FROM ubuntu:latest
  6. MAINTAINER Bourbon Tian "bourbon@1mcloud.com"
  7. ENV REFRESHED_AT 2017-06-13
  8.  
  9. RUN apt-get -qq update
  10. RUN apt-get -qq install apache2
  11.  
  12. VOLUME [ "/var/www/html" ]
  13. WORKDIR /var/www/html
  14.  
  15. ENV APACHE_RUN_USER www-data
  16. ENV APACHE_RUN_GROUP www-data
  17. ENV APACHE_LOG_DIR /var/log/apache2
  18. ENV APACHE_PID_FILE /var/run/apache2.pid
  19. ENV APACHE_RUN_DIR /var/run/apache2
  20. ENV APACHE_LOCK_DIR /var/lock/apache2
  21.  
  22. RUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIR
  23.  
  24. EXPOSE 80
  25.  
  26. ENTRYPOINT [ "/usr/sbin/apache2" ]
  27. CMD ["-D", "FOREGROUND"]

这个镜像也是基于Ubuntu:latest,并且安装了Apache。然后使用VOLUME指令创建了一个卷,即/var/www/html/,用来存放编译后的Jekyll网站。然后将/var/www/html设为工作目录。

使用ENV指令设置了一些必要的环境变量,创建了必要的目录,并且使用EXPOSE公开了80端口。最后指定了ENTRYPOINT和CMD指令组合赖在容器启动时默认运行Apache。

构建Apache镜像

  1. # docker build -t test/apache .
  2. Sending build context to Docker daemon 2.56 kB
  3. Sending build context to Docker daemon
  4. Step 0 : FROM ubuntu:latest
  5. ---> db12a182ded0
  6. ...
  7. Successfully built f97bb19ef81c

这里构建了一个名为test/apache、ID为f97bb19ef81c的新镜像。可以通过docker images查看:

  1. # docker images
  2. REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
  3. test/apache latest f97bb19ef81c About an hour ago 255.2 MB

启动Jekyll网站

现在有了以下两个镜像。

  • Jekyll:安装了Ruby及其他必备软件包的Jekyll镜像。
  • Apache:通过Apache Web服务器来让Jekyll网站工作起来的镜像。

我们从使用docker run命令来创建一个新的Jekyll容器开始我们的网站。我们将启动容器,并构建我们的网站。我们将启动容器,并构建我们的网站。

  1. # cd /opt/jekyll
  2. # git clone https://github.com/turnbullpress/james_blog.git
  3. # docker run -v /opt/jekyll/james_blog:/data/ --name james_blog test/jekyll
  4. Configuration file: /data/_config.yml
  5. Source: /data
  6. Destination: /var/www/html
  7. Generating...
  8. done.

这里启动了一个叫james_blog的新容器,把本地的james_blog目录作为/data/卷挂载到容器里。容器已经拿到网站的源代码,并将其构建到已编译的网站,存放到/var/www/html/目录。

卷是在一个或多个容器中特殊指定的目录,卷会绕过联合文件系统,为持久化数据提和共享数据提供几个有用的特性:

  • 卷可以在容器间共享和重用。
  • 共享卷时不一定要运行相应的容器。
  • 对卷的修改会直接在卷上反映出来。
  • 更新镜像时不会包含对卷的修改。
  • 卷会一直存在,直到没有容器使用它们。

利用卷,可以在不用提交镜像修改的情况下,向镜像里加入数据(如源代码、数据或者其他内容),并且可以在容器间共享这些数据。卷在Docker宿主机的/var/lib/docker/volumes目录中。可以通过docker inspect命令查看某个卷的具体位置。

  1. # docker inspect -f "{{ .Volumes}}" james_blog
  2. map[/data:/opt/jekyll/james_blog /var/www/html:/var/lib/docker/volumes/6bf6fbf5ef4017c7aaab6f681b396f32f0f3878a3958f833e02973e0826ccafd/_data]

如果想在另一个容器里使用/var/www/html/卷里编译好的网站,可以创建一个新的连接到这个卷的容器:

  1. # docker run -d -P --volumes-from james_blog test/apache
  • --volumes-from把指定容器里的所有卷都加入新创建的容器里。

这意味着,Apache容器可以访问之前创建的james_blog容器里/var/www/html卷中存放的编译后的Jekyll网站。即便james_blog容器没有运行,Apache容器也可以访问这个卷。

不过,容器本身必须存在。如果用docker rm命令删除了james_blog容器,那么这个卷和卷里的内容也就不存在了。

现在在宿主机上浏览该网站,首先查看容器公开的80端口映射到了宿主机的哪个端口:

  1. # docker port f39825fd8f61 80
  2. 0.0.0.0:32782

更新Jekyll网站

如果需要更新网站的数据,假设要修改Jekyll网站的博客名字,我们只需要通过编辑宿主机上 james_blog/_config.yml文件

  1. # pwd
  2. /opt/jekyll/james_blog
  3.  
  4. # vi _config.yml

并将title域改为Bourbon Blog。

然后通过使用docker start命令启动Docker容器即可:

  1. # docker start james_blog
  2. james_blog
  3.  
  4. ## 看上去什么都没有发生。我们来查看一下日志
  5. # docker logs james_blog
  6. Configuration file: /data/_config.yml
  7. Source: /data
  8. Destination: /var/www/html
  9. Generating...
  10. done.
  11. Auto-regeneration: disabled. Use --watch to enable.
  12. Configuration file: /data/_config.yml
  13. Source: /data
  14. Destination: /var/www/html
  15. Generating...
  16. done.
  17. Auto-regeneration: disabled. Use --watch to enable.

可以看到,Jekyll编译过程第二次被运行,并且往网站已经被更新。这次更新已经写入了对应的卷。现在浏览Jekyll网站,就能看到变化了。

由于共享的卷会自动更新,这一切都不要更新或者重启Apache容器。这个流程非常简单,可以将其扩展到更复杂的部署环境。

备份Jekyll卷

如果担心一不小心删除卷。由于卷的优点之一就是可以挂载到任意的容器,因此可以轻松备份它们。现在创建一个新容器,用来备份/var/www/html卷

  1. # docker run --rm --volumes-from james_blog -v $(pwd):/backup ubuntu tar cvf /backup/james_blog_backup.tar /var/www/html
  2. tar: Removing leading `/' from member names
  3. /var/www/html/
  4. /var/www/html/History.markdown
  5. /var/www/html/atom.xml
  6. /var/www/html/pages.html
  7. ...
  8.  
  9. # ls james_blog_backup.tar
  10. james_blog_backup.tar

这里我们运行了一个已有的Ubuntu容器,并把james_blog的卷挂载到该容器。这会在该容器里创建/var/www/html目录。然后我们使用一个-v标志把当前目录(通过$(pwd)命令获得)挂载到容器的/backup 目录。最后我们的容器运行这一备份命令。

  • --rm 标志,这个标志对于只用一次的容器,或者说用完即扔的容器,很有用。这个标志在容器的进程运行完毕后,自动删除容器。对于只用一次的容器来说,这是一种很方便的清理方法。

docker实战——构建Jekyll的更多相关文章

  1. Docker 实战—使用 Dockerfile 构建镜像

    Dockerfile 指令详解请访问:https://www.cnblogs.com/cloudfloating/p/11737447.html 使用 Alpine Linux 作为基础镜像 Alpi ...

  2. 使用Docker构建Jekyll框架网站

    使用Docker构建Jekyll框架网站 使用dockerfile构建apache + jekyll 目录 Jekyll基础镜像 构建Jekyll基础镜像 Apache镜像 构建Jekyll Apac ...

  3. Docker学习6:使用docker构建Jekyll服务和java服务

    写在前面 ## 文章Dockerfile中涉及apt-get 等操作需更换镜像 在Dockerfile中添加下列 Dockerfile源码,见下面作者githubhttps://github.com/ ...

  4. ASP.NET Core & Docker 实战经验分享

    一.前言 最近一直在研究和实践ASP.NET Core.Docker.持续集成.在ASP.NET Core 和 Dcoker结合下遇到了一些坑,在此记录和分享,希望对大家有一些帮助. 二.中间镜像 我 ...

  5. Docker03 Docker基础知识、Docker实战

    1 Docker基础知识 1.1 什么是Docker Docker是一个可以装应用的容器,就像杯子可以装水.书包可以装书一样:docker官网 Docker是Docker公司开发的,并开源到GitHu ...

  6. docker,构建nginx反向代理tomcat

    Nginx实现负载均衡是通过配置nginx.conf来实现的,nginx.conf的全部内容如下: user nginx; worker_processes 1; error_log /var/log ...

  7. [置顶] Docker学习总结(1)——Docker实战之入门以及Dockerfile(一)

    一.Docker是什么? 首先Docker是软件工业上的集装箱技术 回顾,在没有集装箱出现以前,传统运输行业中,会存在这些问题: 在运输过程中,货物损坏 装卸.运输货物,效率低下 运输手续繁多及运输环 ...

  8. Docker实战总结

    >>> 目录 <<< Docker简介 Docker优势 Docker基本概念 Docker安装使用 Docker常用命令 Docker镜像构建 Docker本地仓 ...

  9. 【新】Docker实战总结

    >>> 目录 <<< Docker简介 Docker优势 Docker基本概念 Docker安装使用 Docker常用命令 Docker镜像构建 Docker本地仓 ...

随机推荐

  1. Git-ssh登录github

    生成你的ssh-key $ ssh-keygen -t rsa -b 4096 -C  "SaphhireCastle@163.com" 默认目录为:/Users/you/id_r ...

  2. 【转】Spring Bean属性解析

    转载自:http://wenku.baidu.com/view/30c7672cb4daa58da0114ae2.html Bean所以属性一览: <bean id="beanId&q ...

  3. selenium 常用浏览器操作API

    package test; import org.openqa.selenium.By;import org.openqa.selenium.Dimension;import org.openqa.s ...

  4. docker从零开始 存储(一)存储概述

    管理Docker中的数据 默认情况下,在容器内创建的所有文件都存储在可写容器层中.这意味着: 当该容器不再运行时,数据不会持久存在,如果另一个进程需要,则可能很难从容器中获取数据. 容器的可写层紧密耦 ...

  5. PHP serialize 和 JSON 解析与区别

    PHP serialize 和 JSON 解析与区别 对于JSON(JavaScript Object Notation)大家应该不陌生,它是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器 ...

  6. win7 安全模式开启声音

    下载运行这个reg文件 http://files.cnblogs.com/files/bushe/Activate_Sound_in_SafeMode.rar

  7. linux 批量替换所有文件中包含的字符串

    sed -i "s/原来字符串/新字符串/g" `grep 原来字符串 -rl .` 格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 ...

  8. CF 612C. Replace To Make Regular Bracket Sequence【括号匹配】

    [链接]:CF [题意]:给你一个只含有括号的字符串,你可以将一种类型的左括号改成另外一种类型,右括号改成另外一种右括号 问你最少修改多少次,才能使得这个字符串匹配,输出次数 [分析]: 本题用到了栈 ...

  9. 24、Django实战第24天:讲师列表页

    1.复制teracher-list.html到templates目录下 2.编辑teacher-list.html,继承base模板 3.编辑organization.views.py ... fro ...

  10. websocket、文件上传

    支持情况: 浏览器实现了websocket的浏览器:Chrome Supported in version 4+ Firefox Supported in version 4+ Internet Ex ...