Docekrfile和docker compose编写指南及注意事项
Dockerfile
基础语法
我们通过编写dockerfile,将每一层要做的事情使用语法固定下来,之后运行指令就可以通过docker来制作自己的镜像了。
构建镜像的指令:docker build /path -t imageName:tag
注意,docker build后的path必须是dockerfile文件所在的目录。
制作镜像的过程中的输出信息挺详细的,如果我们编写的dockerfile文件有误,可以直接通过输出判断,并对dockerfile文件进行更改。

| 指令 | 说明 | 示例 |
|---|---|---|
| FROM | 指定基础镜像 |
|
| ENV | 设置环境变量,可在后面指令使用 |
|
| COPY | 拷贝本地文件到镜像的指定目录 |
|
| RUN | 执行Linux的shell命令,一般是安装过程的命令 |
|
| EXPOSE | 指定容器运行时监听的端口,是给镜像使用者看的 | EXPOSE 8080 |
| ENTRYPOINT | 镜像中应用的启动命令,容器运行时调用 | ENTRYPOINT java -jar xx.jar |
dockerfile编写模板
Go程序Dockerfile模板【两阶段构建】
# 构建:使用golang:1.21版本
FROM golang:1.21 as build# 容器环境变量添加 容器内部的环境变量 key value的形式
ENV GO111MODULE=on \GOPROXY=https://goproxy.cn,direct \CGO_ENABLED=0 \GOOS=linux \GOARCH=amd64#移动到工作目录,没有该目录会自动创建
WORKDIR /go/release# 把全部文件复制到/go/release目录
COPY . .# 编译: 把main.go编译为可执行的二进制文件, 并命名为app
RUN go build -o dijiexiaApp# 运行: 使用scratch作为基础镜像
FROM alpine as prod# 在build阶段, 复制时区配置到镜像的/etc/localtime
COPY --from=build /usr/share/zoneinfo/Asia/Shanghai /etc/localtime# 在build阶段, 复制./app目录下的可执行二进制文件到当前目录
COPY --from=build /go/release/dijiexiaApp /# 在build阶段, 复制yaml配置文件到当前目录, 此处需要注意调用该配置文件时使用的相对路径, main.go在当前目录下执行
# 一些配置文件不需要在容器内部进行创建,回来直接挂载到容器外部即可,
COPY --from=build /go/release/conf /conf
COPY --from=build /go/release/app/casbin/model.conf /app/casbin/EXPOSE 8000
EXPOSE 8001# 启动服务 CMD是运行镜像时,执行的命令
ENTRYPOINT ["./dijiexiaApp","./conf/develop.yaml"]
Java程序Dockerfile模板
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装JDK
RUN cd $JAVA_DIR \&& tar -xf ./jdk8.tar.gz \&& mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定项目监听的端口
EXPOSE 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
docker compose
一般我们的项目通常包含多个容器,比如业务项目容器、MySQL容器、Redis容器、RabbitMQ容器。如果我们仍然采用手动部署的方式,是比较麻烦的。我们需要逐个将容器启动,并且需要记录容器的启动顺序,因为容器之间可能存在依赖的关系。复杂一点的话,我们还需要将各个容器加入到一个网络中,方便通过容器名进行通信。而通过Docker Compose可以帮助我们实现多个相互关联容器的快速部署。
docekr-compose.yaml文件的编写语法大致和通过命令启动容器的格式一致,以下是它们之间的关系
| docker run 参数 | docker compose 指令 | 说明 |
|---|---|---|
| --name | container_name | 容器名称 |
| -p | ports | 端口映射 |
| -e | environment | 环境变量 |
| -v | volumes | 数据卷配置 |
| --network | networks | 网络 |
docker-compose编写模板
version: "1.1"services:mysql:image: mysqlcontainer_name: diJieXiaMysqlports:- "3710:3306"environment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: 123volumes:- /opt/dijiexia_mysql/conf:/etc/mysql/conf.d #目录挂载MySQL的配置文件- /opt/dijiexia_mysql/data:/var/lib/mysql #目录挂载MySQL的数据- /opt/dijiexia_mysql/init:/docker-entrypoint-initdb.d #初始化数据库脚本挂载点,MySQL容器首次启动时,会自动执行.sh,.sql文件networks:- diJieXiaredis:image: rediscontainer_name: diJieXiaRedisports:- "3711:6379"command: ["redis-server", "--requirepass", "123456"]networks:- diJieXia#通过重新构建镜像的方式获取Go镜像,相当于docker build .dijiexia:build:context: .dockerfile: Dockerfilecontainer_name: diJieXiaProjectports:- "8001:8001"- "8000:8000"networks:- diJieXiadepends_on:- mysql- redisnginx:image: nginxcontainer_name: diJieXiaNginxports:- "3712:80"volumes:- /opt/dijiexia_front/nginx/conf/nginx.conf:/etc/nginx/nginx.conf #将nginx的配置文件nginx.conf挂载出来- /opt/dijiexia_front/nginx/conf.d:/etc/nginx/conf.d #挂载nginx的配置文件夹,通过在nginx.conf中的设置,会自动读取给目录下以.conf结尾的文件- /opt/dijiexia_front/nginx/html:/usr/share/nginx/html #将加载静态页面的目录挂载出来networks:- diJieXia
networks:diJieXia:name: diJieXia111
简单的depends_on存在的问题:
在本版本的docker-compose.yaml文件的模板中,会有一个问题:我们的Go程序会启动失败,原因是因为Go程序所依赖的MySQL容器和Redis容器没有完全启动成功,导致Go程序获取MySQL或Redis连接的时候失败。

虽然在yaml中,我们在yaml文件中设置了depends_on,让MySQL容器、Redis容器先于GO业务程序启动。但是可能存在我们的MySQL容器和Redis容器还未启动完毕,而我们的Go程序已经启动了,从而导致我们的Go程序启动失败。理想情况下是MySQL和Redis容器启动完毕并且保证可用后,我们的Go程序才开始启动。因此,在启动Go程序之前,需要对MySQL和Redis做健康检查,确保MySQL和Redis已经启动成功了。如果MySQL或Redis启动失败了,我们还需要将启动失败的容器进行重启或者选择忽略。
为此,DockerCompose提供了两种机制
condition说明:
为此,Docker中提供了一种长定义的模式,方便我们对容器编排的过程做更加精准的设置。
- condition: service_started
- condition: service_healthy
- condition: service_completed_successfully
如果condition设置为service_started,只表示在该容器在所有依赖服务后启动,不保证依赖容器的可用性。
如果condition设置为service_healthy,表示等待依赖服务的健康状态后在启动相关服务。其中健康状态通常是在同期中运行健康检查命令或脚本来确定的。例如,检查HTTP响应或数据连接等。
如果condition设置为service_completed_successfully,表示依赖服务成功完成后(即退出状态码为0),才会启动相关服务,通常用于数据库迁移、初始化脚本等。
required说明:
在长定义语法中,required字段用于指定依赖服务是否是必需的。它控制了当依赖服务未启动或不可用时的行为。
-
当 required 设置为 true(默认值),如果依赖服务未启动或不可用,Compose 将阻止启动相关的服务,并显示警告信息。
-
当 required 设置为 false,Compose 仍会显示警告信息,但不会阻止启动相关的服务。相当于它是可选的,即使依赖服务未启动或不可用,相关服务仍会尝试启动。
version: "1.1"services:mysql:image: mysqlcontainer_name: diJieXiaMysqlports:- "3710:3306"environment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: 123volumes:- /opt/dijiexia_mysql/conf:/etc/mysql/conf.d #目录挂载MySQL的配置文件- /opt/dijiexia_mysql/data:/var/lib/mysql #目录挂载MySQL的数据- /opt/dijiexia_mysql/init:/docker-entrypoint-initdb.d #初始化数据库脚本挂载点,MySQL容器首次启动时,会自动执行.sh,.sql文件healthcheck:test: [ "CMD","mysqladmin","ping","-h","localhost" ]interval: 30stimeout: 3sretries: 3networks:- diJieXiaredis:image: rediscontainer_name: diJieXiaRedisports:- "3711:6379"volumes:- /opt/dijiexia_redis/conf/redis.conf:/usr/local/etc/redis/redis.conf- /opt/dijiexia_redis/data:/datacommand: [ "redis-server", "--requirepass", "123456" ]healthcheck:test: [ "CMD","redis-cli","ping" ]interval: 30stimeout: 3sretries: 3networks:- diJieXia#通过重新构建镜像的方式获取Go镜像,相当于docker build .dijiexia:build:context: .dockerfile: Dockerfilecontainer_name: diJieXiaProjectports:- "8001:8001"- "8000:8000"networks:- diJieXiavolumes:- ./conf:/confcommand:- RUN apk add --no-cache curlhealthcheck:test: [ "CMD","curl","-f","http://localhost:8000/api/v1/admin/captcha" ]interval: 30stimeout: 5sretries: 3depends_on:mysql:condition: service_healthyrequired: trueredis:condition: service_healthyrequired: truenginx:image: nginxcontainer_name: diJieXiaNginxports:- "3712:80"volumes:- /opt/dijiexia_front/nginx/conf/nginx.conf:/etc/nginx/nginx.conf #将nginx的配置文件nginx.conf挂载出来- /opt/dijiexia_front/nginx/conf.d:/etc/nginx/conf.d #挂载nginx的配置文件夹,通过在nginx.conf中的设置,会自动读取给目录下以.conf结尾的文件- /opt/dijiexia_front/nginx/html:/usr/share/nginx/html #将加载静态页面的目录挂载出来depends_on:dijiexia:condition: service_healthyrequired: falsenetworks:- diJieXianetworks:diJieXia:name: diJieXia111
volumes:diJieXiaRedisConf: { }diJieXiaRedisData: { }

当我再次使用docker compose up -d 运行的时候,会发现先启动MySQL、Redis容器,等到30秒之后,进行一次健康检测,发现MySQL和Redis都处于健康状态,之后才启动Project容器,等到Project容器健康检测后,最后启动Nginx容器。

通过condition和required参数,我们可以更加精准地控制容器编排的顺序。
相关文章:
Docekrfile和docker compose编写指南及注意事项
Dockerfile 基础语法 我们通过编写dockerfile,将每一层要做的事情使用语法固定下来,之后运行指令就可以通过docker来制作自己的镜像了。 构建镜像的指令:docker build /path -t imageName:tag 注意,docker build后的path必须是dockerfile…...
VITS源码解读6-训练推理
1. train.py 1.1 大体流程 执行main函数,调用多线程和run函数执行run函数,加载日志、数据集、模型、模型优化器for循环迭代数据batch,每次执行train_and_evaluate函数,训练模型 这里需要注意,源码中加载数据集用的分…...
力扣 简单 104.二叉树的最大深度
文章目录 题目介绍解法 题目介绍 解法 如果知道了左子树和右子树的最大深度 l 和 r,那么该二叉树的最大深度即为max(l,r)1,而左子树和右子树的最大深度又可以以同样的方式进行计算。因此我们可以用递归的方法来计算二叉树的最大深度。具体而言ÿ…...
单片机长短按简单实现
单片机长短按简单实现 目录 单片机长短按简单实现1 原理2 示例代码2.1 按键实现 3 测试log4 其他实现方式 1 原理 按键检测和处理的步骤如下: 1:定时扫描按键(使用定时器定时扫描,也可以用软件延时或者系统心跳之类的方式&#…...
如何用好通义灵码企业知识库问答能力?
通义灵码企业版:通义灵码企业标准版快速入门_智能编码助手_AI编程_智能编码助手通义灵码(Lingma)-阿里云帮助中心 通义灵码提供了基于企业知识库的问答检索增强的能力,在开发者使用通义灵码 IDE 插件时,可以结合企业知识库内上传的文档、文件…...
C语言自定义类型:联合体
目录 前言一、联合体1.1 联合体类型的声明1.2 联合体的特点1.3 相同成员的结构体和联合体对比1.4 联合体大小的计算1.5 联合体的⼀个练习 总结 前言 前面我讲到C语言中的自定义结构——结构体,其实C语言中的自定义结构不只有结构体,还有枚举和联合体&am…...
【JavaEE】——线程池大总结
阿华代码,不是逆风,就是我疯, 你们的点赞收藏是我前进最大的动力!!希望本文内容能够帮助到你! 目录 引入:问题引入 一:解决方案 1:方案一——协程/纤程 (1…...
编程中为什么使用0和1表示状态
前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 我们看到很多项目都使用0和1表示某些状态信息,具体含义取决于上下文。以下是一些常见的用法: 布尔值&#x…...
C++入门基础知识90(实例)——实例15【求两数的最大公约数】
成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于求两数的最大公约数的相关内容ÿ…...
自动化办公-Python-os模块的使用
os.path 模块的使用 在指定文件路径时,由于操作系统的差异,直接使用硬编码的路径可能会导致程序在不同平台上无法正常运行。为了解决这个问题,Python 提供了 os.path 模块,它包含了一系列用于路径操作的函数,可以帮助您…...
无人机之数据处理技术篇
一、数据采集 无人机通过搭载的各种传感器和设备,如GPS、加速度计、陀螺仪、磁力计、激光雷达(LiDAR)、高光谱相机(Hyperspectral)、多光谱相机(Multispectral)以及普通相机等,实时采集飞行过程中的各种数据。这些数据包括无人机的位置、速度、高度、姿态…...
828华为云征文|部署多功能集成的协作知识库 AFFiNE
828华为云征文|部署多功能集成的协作知识库 AFFiNE 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 AFFiNE3.1 AFFiNE 介绍3.2 AFFiNE 部署3.3 AFFiNE 使用 四、…...
c++(AVL树及其实现)
一、AVL树的概念 AVL树是最先发明的自平衡⼆叉查找树,AVL是⼀颗空树,或者具备下列性质的⼆叉搜索树:它的 左右子树都是AV树,且左右子树的高度差的绝对值不超过1。AVL树是⼀颗高度平衡搜索⼆叉树, 通过控制高度差去控…...
Cesium GIS项目关于湖泊识别与提取的实现
1. 引言 项目背景 随着遥感技术的发展,地理信息系统的应用越来越广泛。本项目旨在开发一个基于Cesium的地理信息系统,利用深度学习技术自动识别并显示湖泊的位置。 目标与意义 通过自动化处理大量遥感影像数据,提高湖泊监测的效率和准确性,为水资源管理和环境保护提供支…...
两个圆形 一个z里面一个z外面,z里面的大,颜色不同 html
两个圆形 一个z里面一个z外面,z里面的大,颜色不同 html <!DOCTYPE html> <html> <head> <style> .outer-circle {width: 150px;height: 150px;border-radius: 50%;background-color: #ff9999; /* 外圆的颜色 */position: relat…...
【Power Query】M函数-table
M函数-table 添加列(AddColumn):条件语句(If..then..else):容错语句(try..otherwise): 排序(ReorderColumns):筛选(Selec…...
uni-app 封装websocket 心跳检测,开箱即用
class websocketUtils {constructor(url, needbeat, options {}) {this.needbeat needbeat;this.url url;this.options options;this.ws null;this.heartbeatInterval options.heartbeatInterval || 10000; // 心跳间隔,默认为10秒 this.reconnectInterval …...
ASP.NET Core8.0学习笔记(十九)——EF Core DbSet
一、DbSet概述 1.DbSet提供了通过DbContext对表进行查询操作的路径。DbSet对应的属性名称将默认映射为实体T的表名。 2.使用DbSet<T>进行查询的方法: (1)直接在DbContext中创建对应的DbSet<T>属性 (2)使用DbSet DbContext.Set<T>方法操作数据表。…...
Android Camera 预览角度和拍照保存图片角度相关
–基于Android R(11) 关于Camera Camera Framework 的架构 Android Camera Framework 是一个分层架构,由以下组件组成: HAL(硬件抽象层): HAL 抽象底层相机硬件,提供与不同设备相机进行交互的标准接口.CameraService : Camera…...
新手如何使用Qt——方法使用
前言 那么这篇文章其实是我在使用Qt的过程当中呢,我发现在Qt使用过程中,在我理解信号和槽这个概念后,在编写槽函数数的时候,发现了自身存在的问题,我的难点是在于当我在编写槽函数的时候,我知道这个槽函数是…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
