Docker安装
卸载旧的版本:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装所需软件包:
yum install -y yum-utils
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
有多个 Docker 仓库吗?
如果启用了多个 Docker 仓库,则在未在 yum install 或 yum update 命令中指定版本的情况下,进行的安装或更新将始终安装最高版本,这可能不适合您的稳定性需求。
安装Docker Engine-Community:
yum install docker-ce docker-ce-cli containerd.io
要安装特定版本的 Docker Engine-Community,请在存储库中列出可用版本,然后选择并安装:
# 列出并排序可用版本
yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
通过其完整的软件包名称安装特定版本,该软件包名称是软件包名称(docker-ce)加上版本字符串(第二列),从第一个冒号(:)一直到第一个连字符,并用连字符(-)分隔。例如:docker-ce-18.09.1。
# 指定版本安装
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
启动Docker:
systemctl start docker
运行hello-world:
docker run hello-world
设置国内阿里云镜像地址:
-
进入/etc/docker/,执行:
-
tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://【你的专属ID】.mirror.aliyuncs.com"] } EOF
-
重启服务:
-
systemctl daemon-reload systemctl restart docker
卸载:
# 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
# 删除资源
rm -rf /var/lib/docker
hello-world运行流程:
Docker为什么比VM快:
1、 Docker有这比虚拟机更少的抽象层。
2、 Docker利用宿主机的内核,而VM需要是Guest OS。
Docker常用命令
帮助命令:
$ docker version # 显示docker版本信息
$ docker info # 显示docker系统信息,包括镜像和容器数量
$ docker --help # docker帮助命令
地址: https://docs.docker.com/reference/
镜像命令:
docker images 查看本机镜像
$ docker images # 查看所有本机镜像
# 可选项
-a # 列出所有镜像
-q # 只显示id
docker search 搜索镜像
$ docker search (name) # 搜索镜像
# 可选项
-f # 根据条件过滤 -f=STARS=3000
docker pull 拉取镜像
$ docker pull (name) # 拉取镜像
$ docker pull mysql:5.7 # 指定版本
# docker pull 镜像名[:tag] ,可选tag,不写默认latest
docker rmi 删除镜像
$ docker rmi -f id/name # 根据镜像id或名称删除
$ docker rmi -f id/name id/name id/name # 根据镜像id或名称删除多个
$ docker rmi -f $(docker images -aq) # 删除全部镜像
容器命令:
下载镜像
docker pull centos
镜像启动后就是容器了;通过docker ps查看容器,之后如果启动没有删除的容器,通过docker start 启动即可。
新建并启动容器
docker run [可选参数] image
# 参数说明
--name name # 容器名字
-d # 后台启动方式
-i # 使用交互方式运行,进入容器查看内容
-t # 使用交互方式运行,进入容器查看内容
-p # 指定容器端口
-p 主机端口:容器端口
-p 容器端口
容器端口
-P # 随机指定端口
-v 主机目录:容器目录 # 容器卷挂载
-e # 配置环境
# 启动 并进入容器centos
docker run -it centos /bin/bash
# 后台启动,给容器命名并映射端口启动
docker run -d -name name -p 主机端口:容器端口 要启动的容器名
查看运行的容器
docker ps # 列出正在运行的容器
-a # 列车曾经运行过的容器
-n=? # 最近运行过的容器
-q # 只显示容器编号
退出容器
exit #退出容器并停止
ctrl+p+q # 退出容器不停止
删除容器
docker rm 容器id # 删除指定id的容器
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm # 删除所有容器
启动和停止容器
docker start 容器id # 启动容器
docker stop 容器id # 停止容器
docker restart 容器id # 重启容器
docker kill 容器id # 杀死容器
常用其他命令
后台启动命令
docker run -d name
查看日志
docker logs 参数
-t, --timestamps # 显示时间戳
-f, -follow # 跟踪日志输出
-n, --tail number # 显示日志条数
查看容器中进程信息
docker top 容器id
查看镜像源数据
docker inspect 容器id
进入当前正在运行的容器
docker exec -it 容器id /bin/bash # 打开新的终端
docker attach 容器id # 进入当前正在运行的终端
将容器内文件拷贝到主机
docker cp 容器id:容器内路径 目标主机路径
给镜像设置tag
docker tag 镜像id 信息[作者/镜像名:版本号]
小结
Docker镜像
docker 是一层一层的;
commit镜像
打包自己的镜像,类似于Linux快照操作。
docker commit #提交容器成为一个新的镜像
docker commit -m="信息" -a="作者" 容器id 目标镜像名:[TAG版本号]
容器数据卷
什么是容器数据卷
docker 理念是将应用和环境打包成为一个镜像;
那么数据在哪里呢?如果将数据也存储在容器中很容易造成数据丢失,例如数据库。
所以需要容器之间有一个数据共享的技术;容器卷就是将docker产生的数据同步到本地,本质就是目录挂载。
使用数据卷
docker run -it -v 主机目录:容器内目录 镜像名/id /bin/bash
指定路径挂载;将容器内指定目录挂载到本地指定目录。
具名和匿名挂载
匿名挂载
当
-v
没有指定本地目录时,而是只指定了容器内目录,则匿名挂载。他会生成一个随机字符串名称作为本地目录名;
# 匿名挂载
[root@node1 /]# docker run -d -P --name nginx01 -v /etc/nginx nginx
# 启动之后查看挂载信息,可以看到生成了一个很长的名字
[root@node1 /]# docker volume ls
DRIVER VOLUME NAME
local 65b1f54c7f22614ed5920b623e208bfefc0a6b0bef2b721559bb2e2ce284b851
# 根据生成的名字查看具体挂载到本地位置目录
[root@node1 /]# docker inspect 65b1f54c7f22614ed5920b623e208bfefc0a6b0bef2b721559bb2e2ce284b851
[
{
"CreatedAt": "2021-03-19T22:50:49+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/65b1f54c7f22614ed5920b623e208bfefc0a6b0bef2b721559bb2e2ce284b851/_data",
"Name": "65b1f54c7f22614ed5920b623e208bfefc0a6b0bef2b721559bb2e2ce284b851",
"Options": null,
"Scope": "local"
}
]
# "Mountpoint" 值就是挂载本地目录。
具名挂载
挂载时指定名称
# 指定名称为 juming-guazai
[root@node1 /]# docker run -d -P --name nginx02 -v juming-guazai:/etc/nginx nginx
# 查看挂载
[root@node1 /]# docker volume ls
DRIVER VOLUME NAME
local 65b1f54c7f22614ed5920b623e208bfefc0a6b0bef2b721559bb2e2ce284b851
local juming-guazai
# 通过挂载名查看本地具体位置目录
[root@node1 /]# docker inspect juming-guazai
[
{
"CreatedAt": "2021-03-19T22:58:44+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-guazai/_data",
"Name": "juming-guazai",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定目录的情况下挂载位置在:/var/lib/docker/volumes/挂载名/_data
扩展: 通过在 -v 容器内路径:ro/rw
改变容器内路径读写权限!
ro readonly
rw readwrite
docker run -d -P --name nginx02 -v juming-guazai:/etc/nginx:ro nginx
数据卷容器
容器之间数据共享
--volumes-from 父容器
Dockerfile
什么是Dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
步骤:
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像
官网centos镜像 也是由dockerfile 构建生成的。
Dockerfile构建过程
认识:
- 每个关键字命令都必须大写;
- 命令是从上到下执行的;
#
表示注释;- 每一个指令都会创建提交一个新的镜像层;
Dockerfile 是面向开发的,项目的发布就需要做镜像,就需要编写dockerfile文件;
Dockerfile指令
FROM # 基础镜像,镜像从这里开始
MAINTAINER # 镜像是谁写的
RUN # docker镜像构建的时候运行的命令
ADD # 给镜像添加内容,添加组件,如果是tar包可以自动解压
WORKDIR # 镜像的工作目录
VOLUME # 挂载卷目录
EXPOSE # 暴露端口配置
CMD # 指定容器启动的时候运行的命令,不可以追加命令 会被替换
ENTRYPOINT # 指定容器启动的时候运行的命令,可以追加命令,不会替换
ONBUILD # 当构建一个被继承的dockerfile时就会触发
COPY # 将文件拷贝到目录中
ENV # 构建的时候设置环境变量
LABEL # 设置镜像的标签
练习创建自定义镜像
指令
# 编写构建镜像文件
[root@node1 dockerfile]# cat mycentos-dockerfile
FROM centos
MAINTAINER ylb<123@11.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 81
CMD echo $MYPATH
CMD echo "---end---"
CMD ["/bin/bash"]
[root@node1 dockerfile]#
# 构建镜像
docker build -f 镜像文件 -t 镜像名 .
列出本地镜像变更历史 ,构建信息
docker history 镜像id
自定义tomcat环境镜像centos
编写dockerfile构建文件
FROM centos
MAINTAINER ylb<11>
ADD jdk-8u251-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.41.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local/
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_251
ENV CLASSPATH $JAVA_HOME/lib/
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.41
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.41
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$CATALINA_HOME/lib
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.41/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.41/logs/catalina.out
构建镜像;如果构建文件名为Dockerfile,则构建镜像时不需要写构建文件位置
[root@node1 tomcat]# docker build -t mycentos .
构建镜像成功!
查看本地镜像是否有构建成功的镜像
[root@node1 jdk1.8.0_251]# docker images
运行镜像,同时挂载项目目录和日志目录;
[root@node1 tomcat]# docker run -d -p 9090:8080 --name myostomcat -v /home/dockerfile/dockerimages/tomcat/test:/usr/local/apache-tomcat-9.0.41/webapps/test -v /home/dockerfile/dockerimages/tomcat/testlogs:/usr/local/apache-tomcat-9.0.41/logs mycentos
此时可以在挂载目录test项目下放入相关web页面;
发布镜像
发布到Docker Hub
- 注册账号
- 登录
[root@node1 test]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username
- 提交镜像
docker push
发布到阿里云镜像
- 登录阿里云
- 打开容器镜像服务
- 创建命名空间
- 创建容器镜像
- 推送
总结
Docker网络
Docker网络ip
查看本地网络信息
可见有三个网卡信息,lo:本地 ;ens:虚拟机或阿里云服务器地址;docker0:docker网络地址。
查看docker容器启动时的内部网络;分别启动两个容器;
[root@node1 ~]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@node1 ~]#
[root@node1 ~]# docker exec -it tomcat02 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@node1 ~]#
容器与容器之间,容器与docker0之间是可以连接的;
[root@node1 ~]# docker exec -it tomcat01 ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.845 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.139 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.130 ms
64 bytes from 172.17.0.1: icmp_seq=4 ttl=64 time=0.134 ms
64 bytes from 172.17.0.1: icmp_seq=5 ttl=64 time=0.119 ms
64 bytes from 172.17.0.1: icmp_seq=6 ttl=64 time=0.082 ms
docker每启动一个容器,就会分配一个ip,只要安装了docker,就会有一个网卡docker0,桥接模式,使用的时veth-pair技术。
启动容器后再次测试ip addr;
可以看到容器内ip与本机ip成对出现,这就是veth-pair技术。
docker0相当于一个路由器,各个容器都与docker0相连,容器之间的通信通过路由器来转发。
Docker中的所有网络接口都是虚拟的,相当于内网传递;
只要删除容器,对应网络就会删除。
–link
需求,每次重启容器或Linux,ip就会变化,固定的ip互联网络就会失效,如何使用服务名来连接,而不考虑ip?
测试使用容器名来ping
[root@node1 ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known
[root@node1 ~]#
容器之间无法通过容器名来连接;
如何解决?
[root@node1 ~]# docker run -d -P --name tomcat02 --link tomcat01 tomcat
81d38e78eea0756c654af6b51ac626ad7c086a7fe56589303ddb108fd0091f8d
[root@node1 ~]# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.120 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.184 ms
^C
--- tomcat01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.120/0.152/0.184/0.032 ms
# 但是反向却无法链接通!!!
tomcat02能够通过容器名链接tomcat01,原理是–link 是通过tomcat02在自己容器hosts文件中配置了tomcat01 ip信息!
[root@node1 ~]# docker exec -it tomcat02 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 tomcat01 e0559dd36be0
172.17.0.3 81d38e78eea0
本质就是修改host映射,–link已经摒弃;建议实现使用自定义网络实现!
自定义网络
查看本地docker网络信息
[root@node1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8d5e54eaae69 bridge bridge local
3452d41b8d68 host host local
c98ef8bfc64b none null local
- bridge : 桥接(默认,自己创建也使用bridge)
- host : 和宿主即共享
- none : 不配置网络
# 在我们启动容器的时候默认会有一个网络设置
docker run -d -P --net bridge --name tomcat01 tomcat
# 所以我们可以指定自定义的网络
# 通过docker network --help
[root@node1 ~]# docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
创建自定义的网络
docker create
[root@node1 ~]# docker network create -d bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
30d7111860cf9c3aa2739ff90a75e309980f0e59b71447318982bbeef0d37442
-d --driver 网络模式
--subnet 子网
--gateway 网关
---------------------------------------------
# 命令参数详解
[root@node1 ~]# docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
--config-from string The network from which to copy the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment
查看我们创建的网络
[root@node1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8d5e54eaae69 bridge bridge local
3452d41b8d68 host host local
30d7111860cf mynet bridge local
c98ef8bfc64b none null local
[root@node1 ~]#
自定义网络创建完成!
之后容器启动可以将网络配置在自定义网络下,解决了–link的不足!
docker run -d -P -net mynet --name tomcat01 tomcat
# 不同容器同处于同一网络下mynet,维护好了容器间的关系。
[root@node1 ~]# docker exec -it tomcat01-net ping tomcat02-net
PING tomcat02-net (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02-net.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.187 ms
64 bytes from tomcat02-net.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.147 ms
^C
--- tomcat02-net ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 0.147/0.167/0.187/0.020 ms
[root@node1 ~]#
查看mynet网络信息
[root@node1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8d5e54eaae69 bridge bridge local
3452d41b8d68 host host local
30d7111860cf mynet bridge local
c98ef8bfc64b none null local
[root@node1 ~]# docker network inspect 30d7111860cf
可以实现不同集群使用不同的网络,保证集群网络的安全和健康;
如Redis集群在192.160.0.0/16网段下,mysql集群在192.161.0.0/16网段下。
网络连通
场景:
解决: 使用
docker network connect
实现。
测试连通:
[root@node1 ~]# docker network connect mynet tomcat01
# 查看mynet网络信息
[root@node1 ~]# docker network inspect 30d7111860cf
可以看到mynet将tomcat01容器添加到自己网络中;
这就是一个容器两个ip;
查看tomcat01容器网络信息
[root@node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e653420cdecd tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:49159->8080/tcp tomcat01
0ebe12ac83db tomcat "catalina.sh run" 6 minutes ago Up 6 minutes 0.0.0.0:49158->8080/tcp tomcat02-net
33d8bc6a2bea tomcat "catalina.sh run" 6 minutes ago Up 6 minutes 0.0.0.0:49157->8080/tcp tomcat01-net
[root@node1 ~]# docker inspect e653420cdecd
原本属于docker0网段的容器,添加了mynet网络;
测试连通:
[root@node1 ~]# docker exec -it tomcat01 ping tomcat01-net
PING tomcat01-net (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01-net.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.121 ms
64 bytes from tomcat01-net.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.064 ms
^C
--- tomcat01-net ping statistics ---
## bingo!!
Docker Compose
简介 官网
Docker Compose用来管理容器,定义运行多个容器。
官方介绍
Compose is a tool for defining and running multi-container Docker applications.With Compose, you use a YAML file to configure your application’s services.Then, with a single command, you create and start all the servicesfrom your configuration. To learn more about all the features of Compose,see the list of features.
Compose works in all environments: production, staging, development, testing, aswell as CI workflows. You can learn more about each case in Common UseCases.
三步骤:
Using Compose is basically a three-step process:
- Define your app’s environment with a
Dockerfile
so it can be reproducedanywhere. - Define the services that make up your app in
docker-compose.yml
so they can be run together in an isolated environment. - Run
docker compose up
and the Docker compose command starts and runs your entire app. You can alternatively rundocker-compose up
using the docker-compose binary.
Compose yaml配置(一组关联的容器)
version: "3.9" # optional since v1.27.0
services: # 容器 服务应用:yaml中配置多个服务,如web、redis、mysql...
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Compose安装
- 下载
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 官方下载很慢
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
- 授权
chmod +x /usr/local/bin/docker-compose
查看版本
安装完成!
Compose卸载
如果使用curl安装
rm /usr/local/bin/docker-compose
如果使用pip安装
pip uninstall docker-compose
使用体验
On this page you build a simple Python web application running on Docker
Compose. The application uses the Flask framework and maintains a hit counter in
Redis. While the sample uses Python, the concepts demonstrated here should be
understandable even if you’re not familiar with it.
通过官网提供的应用程序来体验。
第一步:
- 创建项目目录
mkdir composetest
cd composetest
- 创建一个app.py文件
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
redis 是应用容器中redis容器的主机名,在同一网络下可以通过服务名访问,端口默认6379;
- 创建一个
requirements.txt
文件并写入:
flask
redis
第二步:
创建一个Dockerfile
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
第三步:
创建一个docker-compose.yml
配置文件
version: "3.3"
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
这个文件定义了两个服务web和redis。
第四步:
Build and run这个应用
在你的项目目录中,运行docker-compose up来启动你的应用程序。
docker-compose up
启动成功;可以看到容器命名都带有数字,是因为集群下副本数量
查看容器docker ps
,并且可以成功访问;
自动下载镜像
自动创建网络(项目中的内容都在同个网络下)
停止:
# 停止服务
docker-compose stop
# 停止服务 同时删除容器
docker-compose down
yaml规范
https://docs.docker.com/compose/compose-file/compose-file-v3/#compose-file-structure-and-examples
version: "3.9"
services:
redis:
image: redis:alpine
ports:
- "6379"
networks:
- frontend
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
deploy:
placement:
max_replicas_per_node: 1
constraints:
- "node.role==manager"
vote:
image: dockersamples/examplevotingapp_vote:before
ports:
- "5000:80"
networks:
- frontend
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
restart_policy:
condition: on-failure
result:
image: dockersamples/examplevotingapp_result:before
ports:
- "5001:80"
networks:
- backend
depends_on:
- db
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 1
labels: [APP=VOTING]
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 120s
placement:
constraints:
- "node.role==manager"
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints:
- "node.role==manager"
networks:
frontend:
backend:
volumes:
db-data:
depends_on: 依赖关系,如下web依赖redis和db,所以通过depends_on表明关系
version: "3.9"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
更多配置见:https://docs.docker.com/compose/compose-file/compose-file-v3/#compose-file-structure-and-examples