Docker实战

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Docker实战

         

968c3cf2e99b4e9b99da7f768958a4f7.png

一、FROM 语法

scratch -- 从头开始

尽量来使用官方提供的image


FROM 指定基础镜像,最好挑一些apline,slim之类的基础小镜像. scratch镜像是一个空镜像,常用于多阶段构建 如何确定我需要什么要的基础镜像? Java应用当然是java基础镜像(SpringBoot应用)或者Tomcat基础镜像(War应用) JS模块化应用一般用nodejs基础镜像 其他各种语言用自己的服务器或者基础环境镜像,如python、golang、java、php等e19acc465c7e4728bdc6115d90f2582b.png

编辑

二、label语法

meta信息,类似于代码的注释。

LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"

三、run语法

没run一次image上会有新的一层。因此有必要使用&&合并执行,避免layer 过多看起来很混乱。

编辑

四、workdir 语法

使用workdir不要使用run cd来替代

workdir尽量使用绝对路径。增强dockerfile的可移植性。

编辑

五、add 和copy 语法

  • 区别:add 还具有解压缩的功能,例如add test.tat.gz / 会直接将test.tar.gz解压出来

下面以reids源代码为例进行演示

Dockerfile如下

FROM alpine
ADD ./redis-7.0.8.tar.gz /redis/
RUN ls -l
RUN cd /redis && ls -l

结果

  • workdir 和add的结合
  • 添加远程文件/目录使用curl 或者 wget

编辑

copy文件夹时候的坑

https://www.jianshu.com/p/9b7da9aacd8a

六、ENV语法

定义常量,增加可维护性,和shell中定义变量一个意思。

编辑

七、volume 和expose 语法

八、run、cmd 和entrypoint

编辑2df0130c75be48cab5fb12251970f6e9.png例子:

shell 格式的docker file build的image

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-shell .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Running in 00b2f71e6d9f
Removing intermediate container 00b2f71e6d9f
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT echo "hello $name"
 ---> Running in cfc67b613f7a
Removing intermediate container cfc67b613f7a
 ---> 865aaaacd1ee
Successfully built 865aaaacd1ee
Successfully tagged ninesun0318/centos-entrypoint-shell:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker image ls
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
ninesun0318/centos-entrypoint-shell   latest              865aaaacd1ee        17 seconds ago      215MB
centos                                latest              0d120b6ccaa8        2 months ago        215MB
hello-world                           latest              bf756fb1ae65        10 months ago       13.3kB
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run 865aaaacd1ee
hello Docker

很完美这个dockerfile没有问题。

exec格式的docker file build的image

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo", "hello $name"]
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-exec .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Using cache
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT ["/bin/echo", "hello $name"]
 ---> Running in 61c84954936b
Removing intermediate container 61c84954936b
 ---> 2292313abbf0
Successfully built 2292313abbf0
Successfully tagged ninesun0318/centos-entrypoint-exec:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker image ls
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
ninesun0318/centos-entrypoint-exec    latest              2292313abbf0        5 seconds ago       215MB
ninesun0318/centos-entrypoint-shell   latest              865aaaacd1ee        8 minutes ago       215MB
centos                                latest              0d120b6ccaa8        2 months ago        215MB
hello-world                           latest              bf756fb1ae65        10 months ago       13.3kB
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run ninesun0318/centos-entrypoint-exec
hello $name
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 

奇怪exec 并没有把name 这个ENV打印出来。为何?

只有shell 中才会执行name才会被解释为变量,exec 就是简单的执行。

如何修改呢?

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 

重新build 然后run

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-exec-new .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Using cache
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
 ---> Running in 5ee34add9195
Removing intermediate container 5ee34add9195
 ---> cf961663ddc1
Successfully built cf961663ddc1
Successfully tagged ninesun0318/centos-entrypoint-exec-new:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run ninesun0318/centos-entrypoint-exec-new
hello Docker
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Ddo
more: stat of Ddo failed: No such file or directory

这个问题得到了解决。

cmd推荐写法

6da701c7304a46da8a41c4abcaa70687.pngDockerfile 测试

CMD为ENTRYPOINT提供默认参数

FROM alpine
LABEL mantainer=ninesun
CMD ["testvm"]
CMD ["uuuidd"]
ENTRYPOINT ["echo"]
docker build -t demo:test -f Dockerfile3 .
docker run  --rm --name test demo:test
uuuidd
# 指定其他命令 
docker run  --rm --name test demo:test 22222
22222

9f10321e373b4064b73b7ae3188e9175.pngentrypoint推荐写法

例子说明:entrypoint 一定会被执行,cmd 会被覆盖。

Dockerfile列子

1. FROM alpine
2. LABEL mantainer=ninesun
3. CMD ["testvm"]
4. CMD ["uuuidd"]
5. ENTRYPOINT ["echo","hahhahah"]
# docker run指定参数 覆盖cmd,但是entrypoint一定被执行
docker run  --rm --name test demo:test 222
hahhahah 222
# docker run 不覆盖cmd,但是entrypoint一定被执行
docker run  --rm --name test demo:test
hahhahah uuuidd

CMD和ENTRYPOINT两者都可以作为容器的入口

Dockerfile中只能有一条CMD指令。 如果列出多个CMD,则只有最后一个CMD才会生效。

CMD的主要目的是为执行中的容器提供默认值。 这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定ENTRYPOINT指令。

ARG和ENV的区别

  • ARG 是构建时变量
  • ENV是运行时变量

1、ARG

ARG指令定义了一个变量,用户可以在构建时使用--build-arg = 传递,docker build命令会将其传递给构建器。--build-arg 指定参数会覆盖Dockerfile 中指定的同名参数

如果用户指定了 未在Dockerfile中定义的构建参数 ,则构建会输出 警告 。

ARG只在构建期有效,运行期无效

不建议使用构建时变量来传递诸如github密钥,用户凭据等机密。因为构建时变量值使用docker

history是可见的

ARG变量定义从Dockerfile中定义的行开始生效。

2、ENV

  • 在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。
  • 引号和反斜杠可用于在值中包含空格。
  • ENV 可以使用key value的写法,但是这种不建议使用了,后续版本可能会删除
ENV MY_MSG hello
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
#多行写法如下
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
MY_CAT=fluffy
  • docker run --env 可以修改这些值
  • 容器运行时ENV值可以生效
  • ENV在image阶段就会被解析并持久化(docker inspect image查看),参照下面示例
FROM alpine
ENV arg=1111111
ENV runcmd=$arg
RUN echo$runcmd
CMD echo$runcmd  #ENV的固化问题: 改变arg,会不会改变 echo的值,会改变哪些值,如何修改这些值?

测试案例

FROM alpine
ARG arg1=22222
ENV arg2=1111111
ENV runcmd=$arg1
RUN echo$arg1$arg2$runcmd
CMD echo$arg1$arg2$runcmd

实战

java-springboot 镜像

# syntax=docker/dockerfile:1
FROM 10.50.10.185/qms/openjdk:8-jdk-alpine
LABEL maintainer="ninesun@126.com"
WORKDIR /opt/app
COPY target/*.jar ./
#Alpine Linux 下的包管理工具
#RUN apk   add mysql-client
# 设定时区UTC -> CST
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone && touch EDA_ETL-0.0.51-SNAPSHOT.jar
ENV JAVA_OPTS=""
ENV PARAMS=""
ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar EDA_ETL-0.0.51-SNAPSHOT.jar $PARAMS" ]

python 程序镜像

FROM submitty/python:3.7
COPY ./redis_key_mig /app
WORKDIR /app
RUN /bin/bash -c 'pwd;ls -l /app'
#RUN  /usr/local/bin/python -m pip install --upgrade pip
RUN pip3 install redis==3.5.3
cmd ["python", "/app/redisMigrate.py"]
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
21天前
|
关系型数据库 应用服务中间件 PHP
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
45 3
实战~如何组织一个多容器项目docker-compose
|
2月前
|
Java 应用服务中间件 Linux
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
本文主要讲解了Docker的安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库以及Docker容器虚拟化与传统虚拟机比较。
1267 12
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
|
1月前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
112 7
|
2月前
|
SQL 关系型数据库 数据库
国产数据实战之docker部署MyWebSQL数据库管理工具
【10月更文挑战第23天】国产数据实战之docker部署MyWebSQL数据库管理工具
173 4
国产数据实战之docker部署MyWebSQL数据库管理工具
|
2月前
|
运维 Cloud Native 云计算
云原生之旅:Docker容器化实战
本文将带你走进云原生的世界,深入理解Docker技术如何改变应用部署与运维。我们将通过实际案例,展示如何利用Docker简化开发流程,提升应用的可移植性和伸缩性。文章不仅介绍基础概念,还提供操作指南和最佳实践,帮助你快速上手Docker,开启云原生的第一步。
|
2月前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
|
2月前
|
Kubernetes Linux 开发者
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
100 0
|
2月前
|
存储 Cloud Native 开发者
深入探索容器化技术——Docker的实战应用
深入探索容器化技术——Docker的实战应用
42 0
|
2月前
|
存储 安全 Docker
Docker 的实战应用与优化策略
Docker 的实战应用与优化策略
40 0
|
2月前
|
JavaScript Linux 持续交付
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
60 0

热门文章

最新文章