《第一本Docker书》学习笔记

[toc]

待解决

1、p106内容
2、5.10 docker build 的指令
3、p115-p136 jenkins 内容
4、p147 javaweb tprov


公司Docker用处 by 何应生

看完 docker 和 docker-compose 就好了,我们公司用 k8s

我们公司主要用 k8s,你的项目目前是用 docker-compose 启动的,也没啥复杂度

只要知道怎么启动 docker,也就是那些常用的命令行参数。然后这些命令行参数如何转换成 docker-compose 中的 yaml 文件

常用的就是 端口映射,存储卷挂载,启动停命令


Docker 相关概念

容器

虚拟机的产生:windows和linux无法保证,在同一台服务器上能稳定安全的运行多个应用

虚拟机的不足:因为虚拟机铺在硬件资源上,是对硬件资源的抽象,需要付出额外的os开销。

容器是应用程序的沙盒式运行环境,具有轻量隔离的贴点。容器铺在宿主机os上,相同宿主机的不同容器共享os上的资源,相比于虚拟机减少了很多开销。

OCI : The Open Container Initiative 开放容器计划 ->旨在标准化镜像规范和容器规范

安装Docker

mac:

brew cask install docker

linux

wget -qO- https://get.docker.com/ | sh

Docker 的存储引擎

容器的所有读写操作,都发生在一层层镜像堆叠的最上层镜像,或者是挂载的文件系统。

纵观Docker

运维视角: 镜像通过实例化形成容器

开发视角: 容器=应用

Docker 是 CS架构,客户端和服务端通过/var/run/docker.sock 通信

镜像包含了基础的os系统、程序代码以及相关的依赖。

容器是实例化的镜像,一般只运行一个进程。

Ctrl-PQ 退出容器的时候,保持容器运行


守护进程

在一个多任务的电脑操作系统中,守护进程(英语:daemon,/ˈdiːmən/或/ˈdeɪmən/)是一种在后台执行的电脑程序。此类程序会被以进程的形式初始化。守护进程程序的名称通常以字母“d”结尾:例如,syslogd就是指管理系统日志的守护进程。

通常,守护进程没有任何存在的父进程(即PPID=1),且在UNIX系统进程层级中直接位于init之下。守护进程程序通常通过如下方法使自己成为守护进程:对一个子进程运行fork,然后使其父进程立即终止,使得这个子进程能在init下运行。这种方法通常被称为“脱壳”。

系统通常在启动时一同引导守护进程。守护进程为对网络请求,硬件活动等进行响应,或其他通过某些任务对其他应用程序的请求进行回应提供支持。守护进程也能够对硬件进行配置(如在某些Linux系统上的devfsd),运行计划任务(例如cron),以及运行其他任务


守护进程是在后台运行不受终端控制的进程(如输入、输出等),一般的网络服务都是以守护进程的方式运行。守护进程脱离终端的主要原因有两点:(1)用来启动守护进程的终端在启动守护进程之后,需要执行其他任务。(2)(如其他用户登录该终端后,以前的守护进程的错误信息不应出现)由终端上的一些键所产生的信号(如中断信号),不应对以前从该终端上启动的任何守护进程造成影响。要注意守护进程与后台运行程序(即加&启动的程序)的区别。


守护进程和后台进程的区别

(a)守护进程已经完全脱离终端控制台了,而后台程序并未完全脱离终端,在终端未关闭前还是会往终端输出结果
(b)守护进程在关闭终端控制台时不会受影响,而后台程序会随用户退出而停止,需要在以nohup command & 格式运行才能避免影响
(c)守护进程的会话组和当前目录,文件描述符都是独立的。后台运行只是终端进行了一次fork,让程序在后台执行,这些都没改变。


NFS

NFS 是Network File System的缩写,即网络文件系统。功能是通过网络让不同的机器、不同的操作系统能够彼此分享文件,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁盘文件共享的一种方法。

NFS使用RPC协议进行通信,也就是说NFS系统只是一组RPC程序。RPC是远程过程调用 (Remote Procedure Call) 的英文缩写,它是能使客户端执行其他系统中程序的一种机制。NFS可以看作是一个RPC Server,主要功能是管理需要分享的目录和文件。它不负责通信和信息传输,而是把这部分工作交给RPC协议来完成。即NFS在文件传送或信息传送过程中依赖于RPC协议。所以只要用到NFS的地方都要启动RPC服务,不论是NFS SERVER或者NFS CLIENT。这样SERVER和CLIENT才能通过RPC来实现PROGRAM PORT的对应。可以这么理解RPC和NFS的关系:NFS是一个文件系统,而RPC是负责负责信息的传输。

NFS 的基本原则是“容许不同的客户端及服务端通过一组RPC分享相同的文件系统”,它是独立于操作系统,容许不同硬件及操作系统的系统共同进行文件的分享。


注意 示例用的ubuntu基础镜像,请选择18.04版本

源码地址:

https://github.com/turnbullpress/dockerbook-code.git

https://github.com/guanwei/dockerbook-code

https://github.com/guanwei/dockerbook-code.git

Docker 环境配置

Docker启动时,守护进程监听/var/run/docker.sock 的Unix套接字文件,来获取客户端的Docker请求。

可以通过设置Docker host 环境变量的方式来讲Docker 守护进程方式来指定服务器的地址。

export DOCKER_HOST=”tcp://0.0.0.0:2375”

或是在运行的时候指定

/usr/bindocker -d -H tcp://0.0.0.0:2375


Docker 常用命令

docker run

命令行参数:
– name 指定由该镜像产生的容器的名字

  • -i 保证容器中STDIN是开启的
  • -t为创建的容器非配一个伪tty终端,新创建的容器可以提供一个交互式shell
  • -d 指定以守护进程的方式运行
  • -p 指定Docker在运行的时候,公开哪些端口给宿主机。
  • -h 设置容器的主机名,覆盖默认行为(默认将主机名设置为容器id)

运行ubuntu镜像(没有的话去registry里拉取),同时提供一个/bin/bash的终端:

docker run -i -t ubuntu bash

基于ubuntu镜像,以守护进程的方式,开启一个demon_test镜像,并给镜像里的终端赋予指令,每秒打印一次hello world

docker run –name demon_test -d ubuntu /bin/bash -c “while true; do echo hello world ; sleep 1 ;done”

docker exec {container_name} 在容器中开启一个新进程

以一个后台进程的方式,在demon_test容器中,新建一个文件:

docker exec -d demon_test touch /etc/test_file

在demon_test容器中,开启一个新的终端:

docker exec -t -i demon_test /bin/bash

上述指令完成后,可使用docker logs {container_name}指令查看指定容器日志

如果容器因为某种错误停止运行,将自动重启

docker run –restart=always –name demon_test -d ubuntu /bin/bash -c “while true; do echo hello world ; sleep 1 ;done”

更新apt-get 并安装vim

apt-get update && apt-get install vim

docker ps 列出正在运行的容器

docker ps -a 列出所有容器,包括不在运行的

docker images 列出所有镜像

docker start {container_name} 启动一个容器

docker start 会延续docker run时的参数,通过 docker attach {container_name} 指令可以重新附着到容器的回话上。

docker stop {container_name} 关闭一个容器

docker rm 删除容器

docker rm {container_id/container_name}

docker 移除所欲容器列表,docker ps 列出容器,-a参数代表列出所有容器,-q参数代表只列出id,形成一个列表。
docker rm `docker ps -a -q`


Docker 镜像和仓库

Docker镜像是什么

  • docker 镜像是由文件系统叠加而成。
  • docker 文件系统是一层一层的,对源文件的修改,体现在复制一份源文件到他的上层,在上层对这份拷贝进行修改。所有初始的文件系统都是只读的。
  • docker所有的镜像,都要基于一个已有的基础镜像来构建,在这个基础镜像上构建一层又一层父镜像,知道最顶层的满足需求的镜像。
    50

51

Docker 镜像存在仓库里,仓库存在registry里,默认的registry是官方运营的registry,即docker hub。个人也可以运营自己私有的registry

Docker hub 中,个人的镜像以{个人标识符}/{镜像名}的方式标识,官方的镜像或是可信团体/机构的镜像,直接以{镜像名}的方式标识。


镜像操作

docker pull 拉取镜像

拉取14.04版本的ubuntu镜像:

docker pull ubuntu:14.04

其中ubuntu:后面的14.04为该镜像的tag,即同一个镜像标识符下可能有多个tag(版本)`如果不指定pull的tag,默认拉取最新版。

如何指定一个镜像版本:

  • ubuntu:14.04
  • ubuntu:{tag_name}
  • ubuntu:latest

docker search {image_name} 查找镜像

docker rmi {image} 移除镜像


构建docker镜像

1、通过commit 方式构建

2、通过dockerfile方式构建

Dockerfile 所在的文件夹,被称为Dockerfile的上下文(context)或是构建上下文,Docker会在构建镜像的时候,将该文件夹下的目录和文件上传到Docker的守护进程,这个Docker进程可以访问这个文件夹里的任何资源。

63

Dcokerfile内容:

1
2
3
4
5
6
7
# Version: 0.0.1
FROM ubuntu:14.04
MAINTAINER my "my@exemple.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'hello world'>/usr/share/nginx/html/index.html
EXPOSE 80

Dockerfile的构建过程,每一步都会将上一步的镜像视作缓存,如果构建过程中,某一步骤发生了异常退出,再次构建时,将会从上一次成功的那一层镜像(缓存)中起始。如果需要忽视缓存,命令:--no-cache

在Dockerfile目录下,通过Dockerfile构建一个镜像:

mayuan@mayuandeMacBook-Pro:~/workspace/dockerTest/static_web|⇒ docker build -t=”my/static_web” .

注意上线命令中最后的.,意思是在当前目录下查找Dockerfile,也可以指定一个Git仓库的地址来指定Dockerfile的位置,(docker假设路径下会有Dockerfile)例:

docker build -t=”my/static_web:v1.0.0” git@github.com:jamtur01/docker-static_web

Dockerfile构建环境中可以使用.dockerignore : .dockerignore 文件类似于 .gitignore,文件里的每一行是一条文件过滤匹配模式,用来设置哪些文件不会传到构建上下文里去。

基于该镜像启动一个一个新容器:

docker run -d -p 80 –name static_web my/static_web nginx -g “daemon off;”

Dockerfile中 EXPOSE关键字和docker run 参数-p -P的区别:
EXPOSE关键字是镜像开发者和镜像使用者(容器运行者)之间的一份说明书,表述哪些端口适合暴露给外界,-p 参数实际暴露端口,-P暴露所有端口。

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.

上面的命令,会从宿主机端口中随机绑定一个到docker容器的80端口。其他的绑定方式:

  • -p 80:80 将宿主机80端口和容器80端口绑定,不具备灵活性
  • -p 127.0.0.1:80:80 将本宿主机127.0.0.1:80 与容器80端口绑定
  • -P 暴露Dockerfile中,EXPOSE字段设置的所有端口。

docker history {container_name} 查看镜像的构建过程

docker history my/static_web

docker port {container_name}查看容器端口绑定情况

Dockerfile指令

将自己的镜像推送到docker hub

docker push {userId}(docker hub注册过的)/{image_name}

docker push my/static_web

其中“my”为用户id,必须在docker hub 上注册过才能推送成功。

自动构建

在github中,可以设置,当你向一个存在Dockerfile的库推送代码后,会自动更新一个镜像,推送到docker hub

运行自己的Docker Registry

可以维护docker hub上自己的私有库,或者自己运行一个库

  • 1、从容器运行registry

    docker run -p 5000:5000 registry
    运行一个registry容器,并绑定到主机的5000端口

  • 2、Docker iamges 列出该镜像的id

    docker images my/static_web

  • 3、使用新的Registry给该镜像打上标签,新的Registry打标签时需要制定Registry主机名+端口,因为是运行在本地,所以主机名是localhost。

    docker tag fee851a5072f localhost:5000/my/static_web

  • 4、推送到私有库

    docker push localhost:5000/my/static_web


Docker 编排应用

含义: 对多容器应用进行方便的部署和管理

1、Docker-compose 单引擎模式

通过声明式的配置文件,描述整个应用,组织、部署并管理应用

Docker-compase 前身是Fig

docker-compose.yml

示例:

cd counter-app

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: "3.5" //版本,服务,网络,卷为4个一级标签
services:
web-fe: //这里定义了一个服务的名称
build: . //build命令指定通过当前目录下Dockerfile构建镜像(文件名会叫/
// 做{当前所在的目录名字}_{服务的名字}) 例如 counter-web_web-fe
command: python app.py //指定了命令行指令
ports:
- target: 5000 //等同于-p
published: 5000
networks:
- counter-net //指定到networks里的一个网络,这里web-fe服务和redis服务共同引用
//一个counter-net网络,他们互相可以通过名称解析到对方的地址
volumes:
# - type: volume //注释掉的,是直接定义一个挂载卷(不挂宿主机)
# source: counter-vol
# target: /code
- $PWD:/code //直接将当前目录挂载到/code下
redis:
image: "redis:alpine"
networks:
counter-net:

networks:
counter-net:

volumes:
counter-vol: 多个服务可以挂在同一个卷,实现数据互通。

对应的Dockerfile:

1
2
3
4
5
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"

如需参考:

Docker-compose.yml 文件详解:包括指定容器名等等

https://www.jianshu.com/p/2217cfed29d7

挂载卷可能遇到的问题(我目前没遇到)

https://segmentfault.com/q/1010000015769131

命令

执行docker-compose大多数命令式,默认在docker-compose.yml目录下

docker-compose 启动命令(如果后面跟一个-&参数,表示启动后开启终端,此处为-d,守护进程运行)

docker-compose up -d

localhost:5000 测试有无成功

在counter-app目录下,修改app.py里的内容,如果是上文的docker-compose配置,指定了挂载卷,同时app.py在挂载卷里,name对app.py的修改会实时生效。

docker-compose down 停止和关闭应用

docker-compose ps

docker-compose top

docker-compose stop 停止命令,但不删除资源

docker-compose restart

2、Swarm模式

开发和测试中使用Docker

1、Docker测试一个静态网站

参考sample 文件夹

docker 构建nginx镜像的时候,要在Docker中,添加file share,且添加时指定了一个绝对路径之后,docker run时,-v 参数也要指定一个绝对路径

示例网站采用nginx作为服务器

  • 1、创建Dockerfile

mkdir sample && cd sample

mkdir Dockerfile

1
2
3
4
5
6
7
8
9
10
11
FROM ubuntu:14.04
LABEL maintainer="james@example.com"
ENV REFRESHED_AT 2014-06-01

RUN apt-get update && apt-get -y -q install nginx

RUN mkdir -p /var/www/html/website
ADD nginx/global.conf /etc/nginx/conf.d/
ADD nginx/nginx.conf /etc/nginx/

EXPOSE 80

ADD 命令将宿主机文件添加到容器的指定位置

  • 2、进行nginx 配置

    mkdir nginx && cd nginx

创建global.conf 以及 nginx.conf

  • 3、构建示例网站镜像

    docker build -t jamtur01/nginx .

  • 4、获取html文件

cd sample

mkdir website && cd website

vim index.html

  • 5、启动容器

docker run -d -p 8082:80 –name website -v /Users/mayuan/workspace/dockerTest/sample/website:/var/www/html/website jamtur01/nginx nginx

-p参数指定了宿主机的8082端口绑定到容器的80端口,-v参数将宿主机的website目录挂载到容器的website目录下。

Docker 中的卷

Docker 中的卷,是在一个或者多个容器中被选中的目录,卷会绕过分层文件系统,直接给容器提供持久化、共享的数据。对卷的修改会立即生效,并绕过镜像。提交或者创建镜像时,不会包括卷。

卷的作用:

  • 希望在多个容器中共享数据
  • 希望同时对程序进行开发和测试
  • 卷内代码、数据改动频繁,不希望频繁重启容器
  • 6、测试
    浏览器访问localhost:8082

2、Docker构建测试web应用程序

目的:掌握两个容器之间的链接(link参数),构建webapp-redis的应用程序到数据库的程序栈

重命名Docker 镜像 :

docker tag {image_id} {registry}:{tag}
docker tag a9a1ce04bf5a jamtur01/sinatra

p116内容暂时没看懂

是Docker容器链接相关。属于老旧方案,作对照,下面给出Docker的简单方案:

mkdir sinatra && cd sinatra

mkdir webapp && cd webapp

vim Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
FROM ubuntu:18.04
LABEL maintainer="james@example.com"
ENV REFRESHED_AT 2014-06-01

RUN apt-get -qq update && apt-get -qq install ruby ruby-dev build-essential redis-tools
RUN gem install --no-rdoc --no-ri sinatra json redis

RUN mkdir -p /opt/webapp

EXPOSE 4567

CMD [ "/opt/webapp/bin/webapp" ]

该镜像启动的容器,会创建一个/opt/webapp目录,里面会放外节通过-v参数挂载的可执行文件。CMD命令会执行这个可执行文件

获取webapp(参考附带文件夹)
包括/sinatra/webapp/bin/webapp 的可执行文件以及/sinatra/webapp/lib/app.rb

构建不链接redis的webapp镜像并启动容器:注意:前两个镜像并不涉及到容器互联,第三部分会告知怎么用webapp连接到redis容器

docker build -t jamtur01/sinatra .

构建webapp镜像并启动容器

docker run -d -p 4567:4567 –name webapp -v $PWD/webapp:/opt/webapp jamtur01/sinatra

curl -i -H ‘Accept:application/json’ -d ‘name=sss&status=Bar’ http://localhost:4567/json

构建redis镜像并启动容器:

Dockerfile:

FROM ubuntu:18.04
LABEL maintainer=”james@example.com
ENV REFRESHED_AT 2014-06-01

RUN apt-get -qq update && apt-get -qq install redis-server redis-tools

EXPOSE 6379

ENTRYPOINT [“/usr/bin/redis-server” ]
CMD []

docker build -t jamtur01/redis .

docker run -d -p 6379 –name redis jamtur01/redis

至此,不进行连接的webapp和redis已经构建完成

webapp连接redis

如果docker中某个名字已经有了对应的容器,需要先用docker rm {container_name} 删除掉对应的容器

启动redis容器:

docker run -d –name redis jamtur01/redis

注意此处redis没有暴露出任何端口,而是别的容器直接通过“redis”这个容器名连接,通过–link,父容器连接到子容器,父容器可以直接访问到子容器的任意端口

docker run -p 4567:4567 –name webapp –link redis:db -t -i -v $PWD/webapp:/opt/webapp jamtur01/sinatra /bin/bash

–link参数指定了webapp容器连接到redis容器的同时,为redis容器指定了一个“db”的别名,父容器中可以直接通过db 访问子容器,例如ping db

ping命令不存在

apt-get update

apt install iputils-ping

apt install net-tools

在父容器中可以查看/etc/hosts看到子容器的信息

1
2
3
4
5
6
7
8
9
root@1508b745189a:/# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 db 6a59a6b98406 redis
172.17.0.3 1508b745189a

ping db

启动webapp程序:

/opt/webapp/bin/webapp

访问

curl -i -H ‘Accept: application/json’ -d ‘param=”test’ http://127.0.0.1/json

Redis::CommandError at /json

DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command ‘CONFIG SET protected-mode no’ from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to ‘no’, and then restarting the server. 3) If you started the server manually just for testing, restart it with the ‘–protected-mode no’ option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.

解决办法:
进入到redis容器里,redis-cli CONFIG SET protected-mode no

在redis容器中开启一个控制台:

docker exec -t -i redis /bin/bash

进入redis命令行界面

redis-cli

查看所有key

keys *

获取key对应的数据

get param


3、Docker集成测试环境搭建

集成测试:

集成测试(也叫组装测试,联合测试)是单元测试的逻辑扩展。它最简单的形式是:把两个已经测试过的单元组合成一个组件,测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合为程序的更大部分。方法是测试片段的组合,并最终扩展成进程,将模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。此外,如果程序由多个进程组成,应该成对测试它们,而不是同时测试所有进程。


使用Docker构建服务

jekyll 搭建日志服务

jekyll

jekyll是一个简单的免费的Blog生成工具,类似WordPress。但是和WordPress又有很大的不同,原因是jekyll只是一个生成静态网页的工具,不需要数据库支持。但是可以配合第三方服务,例如Disqus。最关键的是jekyll可以免费部署在Github上,而且可以绑定自己的域名。

1、构建jekyll镜像
Dockerfile:

1
2
3
4
5
6
7
8
9
10
11
12
FROM ubuntu:16.04
MAINTAINER James Turnbull <james@example.com>
ENV REFRESHED_AT 2016-06-01

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

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

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

指定了/data 以及 /var/www/html 作为宿主机下所有容器可通用的挂载卷。(可通过docker run时 -v参数指定宿主机上,也可以不指定挂载宿主机上的卷,只用于容器间的共享)

docker build -t jamtur01/jekyll .

2、构建apache镜像

Dockfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM ubuntu:16.04
MAINTAINER James Turnbull <james@example.com>

RUN apt-get -qq update
RUN apt-get -qq 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_LOG_DIR $APACHE_RUN_DIR $APACHE_LOCK_DIR

EXPOSE 80

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

docker build -t jamtur01/apache .

3、启动容器

获取james_blog内容(参考源码文件夹)

以jamtur01/jekyll镜像为基础,构建一个james_blog镜像,并且把本地的james_blog文件夹挂载到容器的/data/下。(因为jekyll镜像的Dockerfile里指定了,将/data/作为Volume,所以所有容器都可以访问这个卷)

docker run -v …/james_blog:/data/ –name james_blog jamtur01/jekyll

启动apache容器,同时指定挂载卷为james_blog中指定的所有挂载卷

docker run -d -P –name apache –volumes-from james_blog jametur01/apache

docker port apache -> {port}

浏览器打开localhost:{port}

4、修改博客内容

vim …/james_blog/_config.yml

修改内容后,需要重启james_blog容器

ctrl+c -> docker start james_blog

可对卷内容进行备份:

sudo docker run –rm –volumes-from james_blog -v $(pwd):/backup ubuntu tar zcvf /backup/james_blog_backup.tar.gz /var/www/html

上述命令对james_blog 里的volumes内容进行了备份。备份到了新开的容器ubuntu的/backup目录下。

–rm标志表示只用一次的容器,带有这个标志的容器,会在容器的进程运行完毕后,自动删除容器


Docker搭建一个javaweb

1、war文件获取器
Dockerfile :

1
2
3
4
5
6
7
8
9
10
11
12
FROM ubuntu:16.04
MAINTAINER James Turnbull <james@example.com>
ENV REFRESHED_AT 2016-06-01

RUN apt-get -qq update
RUN apt-get -qq install wget

VOLUME [ "/var/lib/tomcat8/webapps" ]
WORKDIR /var/lib/tomcat8/webapps

ENTRYPOINT [ "wget" ]
CMD [ "--help" ]

docker build -t jamtur01/fetcher .

获取tomcat8示例文件

docker run -t -i –name sample jamtur01/fetcher https://tomcat.apache.org/tomcat-8.0-doc/appdev/sample/sample.war

2、tomcat8应用服务器
Dockfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FROM ubuntu:16.04
MAINTAINER James Turnbull <james@example.com>
ENV REFRESHED_AT 2016-06-01

RUN apt-get -qq update
RUN apt-get -qq install tomcat8 default-jdk

ENV CATALINA_HOME /usr/share/tomcat8
ENV CATALINA_BASE /var/lib/tomcat8
ENV CATALINA_PID /var/run/tomcat8.pid
ENV CATALINA_SH /usr/share/tomcat8/bin/catalina.sh
ENV CATALINA_TMPDIR /tmp/tomcat8-tomcat8-tmp

RUN mkdir -p $CATALINA_TMPDIR

VOLUME [ "/var/lib/tomcat8/webapps" ]

EXPOSE 8080

ENTRYPOINT [ "/usr/share/tomcat8/bin/catalina.sh", "run" ]

docker build -t jamtur01/tomcat8 .

docker run –name sample_app –volumes-from sample -d -P jamtur01/tomcat8

docker port sample_app

浏览器访问测试