Docekrfile和docker compose编写指南及注意事项

news2024/11/16 9:55:53

Dockerfile

基础语法

我们通过编写dockerfile,将每一层要做的事情使用语法固定下来,之后运行指令就可以通过docker来制作自己的镜像了。

构建镜像的指令:docker build /path -t imageName:tag

注意,docker build后的path必须是dockerfile文件所在的目录。

制作镜像的过程中的输出信息挺详细的,如果我们编写的dockerfile文件有误,可以直接通过输出判断,并对dockerfile文件进行更改。

指令

说明

示例

FROM

指定基础镜像

FROM centos:6

ENV

设置环境变量,可在后面指令使用

ENV key value

COPY

拷贝本地文件到镜像的指定目录

COPY ./xx.jar /tmp/app.jar

RUN

执行Linux的shell命令,一般是安装过程的命令

RUN yum install gcc

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: mysql
    container_name: diJieXiaMysql
    ports:
      - "3710:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - /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:
      - diJieXia

  redis:
    image: redis
    container_name: diJieXiaRedis
    ports:
      - "3711:6379"
    command: ["redis-server", "--requirepass", "123456"]
    networks:
      - diJieXia
  
  #通过重新构建镜像的方式获取Go镜像,相当于docker build .
  dijiexia:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: diJieXiaProject
    ports:
      - "8001:8001"
      - "8000:8000"
    networks:
      - diJieXia
    depends_on:
      - mysql
      - redis

  nginx:
    image: nginx
    container_name: diJieXiaNginx
    ports:
      - "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: mysql
    container_name: diJieXiaMysql
    ports:
      - "3710:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - /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: 30s
      timeout: 3s
      retries: 3
    networks:
      - diJieXia

  redis:
    image: redis
    container_name: diJieXiaRedis
    ports:
      - "3711:6379"
    volumes:
      - /opt/dijiexia_redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - /opt/dijiexia_redis/data:/data
    command: [ "redis-server", "--requirepass", "123456" ]
    healthcheck:
      test: [ "CMD","redis-cli","ping" ]
      interval: 30s
      timeout: 3s
      retries: 3
    networks:
      - diJieXia

  #通过重新构建镜像的方式获取Go镜像,相当于docker build .
  dijiexia:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: diJieXiaProject
    ports:
      - "8001:8001"
      - "8000:8000"
    networks:
      - diJieXia
    volumes:
      - ./conf:/conf
    command:
      - RUN apk add --no-cache curl
    healthcheck:
      test: [ "CMD","curl","-f","http://localhost:8000/api/v1/admin/captcha" ]
      interval: 30s
      timeout: 5s
      retries: 3
    depends_on:
      mysql:
        condition: service_healthy
        required: true
      redis:
        condition: service_healthy
        required: true

  nginx:
    image: nginx
    container_name: diJieXiaNginx
    ports:
      - "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_healthy
        required: false
    networks:
      - diJieXia

networks:
  diJieXia:
    name: diJieXia111
volumes:
  diJieXiaRedisConf: { }
  diJieXiaRedisData: { }

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

通过condition和required参数,我们可以更加精准地控制容器编排的顺序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2170992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是文件完整性监控(FIM)

组织经常使用基于文件的系统来组织、存储和管理信息。文件完整性监控(FIM)是一种用于监控和验证文件和系统完整性的技术,识别用户并提醒用户对文件、文件夹和配置进行未经授权或意外的变更是 FIM 的主要目标,有助于保护关键数据和…

贝锐洋葱头浏览器随时随地访问教务系统,轻松搞定选课

教育网的“拥堵”早已是老生常谈,学生数量庞大、上网时间集中、带宽有限,导致网络速度慢。尤其是从外部网络访问教育网时,更是因为跨运营商的缘故变得缓慢。 而学校内网也是类似的情况,课余时间和上课时间的网络使用情况差别巨大…

【Python报错已解决】TypeError: unhashable type: ‘numpy.ndarray‘

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

【API安全】crAPI靶场全解

目录 BOLA Vulnerabilities Challenge 1 - Access details of another user’s vehicle Challenge 2 - Access mechanic reports of other users Broken User Authentication Challenge 3 - Reset the password of a different user Excessive Data Exposure Challenge …

深度解析APP软件开发:构建卷轴式分销系统的实践探索

在移动互联网的浪潮中,APP软件的开发与应用不断推动着商业模式的创新与发展。其中,卷轴模式分销系统作为一种新兴的营销手段,正逐渐受到市场的青睐。作为程序员,深入探索并实践这一模式的系统开发,不仅是对技术能力的挑…

深入理解函数【JavaScript】

在 JavaScript 中,函数作为一种重要的基本结构,承载着编程中的许多关键概念。下面是与函数相关的内容介绍: 1. 函数定义 JavaScript 中有多种方式定义函数: 1.1 函数声明(Function Declaration) functi…

温州大麓青年音乐节即将开唱,37组音乐人国庆齐聚共谱华章

金秋十月,当丰收的季节与音乐的旋律相遇,温州将迎来一场前所未有的文化盛事。2024年10月1日至4日,温州大麓青年音乐节将在瓯海盛大举行。不仅是一场音乐的狂欢,更是一次多元文化的碰撞与融合。本届音乐节邀请了37组以上的知名音乐…

WEB3.0是什么?

WEB3.0是什么? web3 之前用户创作分享内容,内容信息用户信息被运营平台的科技公司控制,比如某云,某信,某音,用户对直接的数据没有真正的所有权,web2平台拥有绝对控制权,想禁用你的账…

为什么说3-8岁的行为塑造奠定孩子的一生?

亲爱的爸爸妈妈: 育儿征程中会有无数问题在脑海中闪烁。孩子成长的每一步,都紧紧牵动着我们的心弦。 实际上,成长的关键在于塑造孩子五个至关重要的能力,分别是专注力、思维力、沟通力、抗逆力和行动力。 数业智能心大陆基于自研 …

CJEval:一个基于中国初中考试的多样化考试问题数据集

2024-09-26,由腾讯YouTu Lab和北京大学联合发布的CJEval,是一个基于中国初中生考试数据的评估基准,用于测试和分析大型语言模型(LLMs)在教育任务中的表现,从而提高在线教育平台的智能化水平。 一、背景&…

(done) 声音信号处理基础知识(11) (Complex Numbers for Audio Signal Processing)

参考:https://www.youtube.com/watch?vDgF4m0AWCgA&t1047s 似乎是因为信号处理需要使用复数,作者花了一节课介绍复数 据油管主所说,声学信号处理中引入复数的原因是:快速完成部分计算 这里的例子是,当我们做傅里…

Python库matplotlib之一

Python库matplotlib之一 plot函数使用列表或数组画线绘图的格式 matplotlib.pyplot 是使 matplotlib 像 MATLAB 一样工作的函数集合。每个 pyplot 函数都会对图形进行一些更改:例如, 创建图形在图形中创建绘图区域在绘图区域中绘制一些线条用标签装饰绘…

Redis --- 第一讲 --- 分布式简单介绍

一、认识Redis 定义变量,不就是在内存中存储数据吗?Redis是在分布式系统中,才能发挥威力的。如果只是单机程序。直接通过变量存储数据的方式势必使用Redis更优的选择。由于进程的的隔离性。进程之间通过网络通信,就能共享数据。Re…

keepalived+nginx实现高可用的案例详解(主主模式)

文章目录 前言keepalived主备模式和主主模式有什么区别1. 主备模式(Master-Backup Mode)2. 主主模式(Active-Active Mode 或 Dual Master Mode)主备模式 vs 主主模式 的区别总结: 环境案例实现具体步骤ngx1ngx2验证 前…

【教学类-56-05】数感训练——数字05(指定数字出现次数,速度快)

背景需求: 昨天有客户订购“阿拉伯数字的数感训练” 我查看文件夹,发现前期没有生成过0-50的数字(只研究了学号数感训练的学具) 赶紧用之前写过的代码生成了一份 【教学类-56-01】数感训练——数字01(同样的数字涂色…

猫头虎分享已解决Bug:npm warn old lockfile Could not fetch metadata for yallist@3.1.1

🐯猫头虎分享已解决Bug:npm warn old lockfile Could not fetch metadata for yallist3.1.1 今天有粉丝问猫哥:“🐯猫头虎,我在使用 npm 安装依赖时遇到了一个错误提示 Could not fetch metadata for yallist3.1.1&am…

凿岩机械液压比例多路阀控制器

工程机械应用的BEUEC比例放大器控制比例多路阀主要应用于以下几大类设备中: 1. 挖掘机械:包括挖掘机、挖掘装载机、挖掘船等,主要用于挖掘土壤、煤和矿石等物料。 2. 铲土运输机械:如推土机、铲运机、装载机等,主要用…

亚马逊测评,容易掉评是什么原因,怎么解决

大家好,今天来深入探讨如何有效提升亚马逊测评中的留评率,并解析那些导致评论掉落或难以留下的常见原因,以便采取针对性的策略来优化这一过程。作为卖家,提升留评率无疑是提升产品曝光度和销量的关键一环。 亚马逊测评掉评与留评…

【机器学习】目标分类算法概述

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 目标分类算法概述传统机器学习方法支持向量机(SVM)决策树和随机森林特征提取 基…

docker_阿里云镜像仓库

1.创建个人实例 登录阿里云——控制台——容器镜像服务——创建个人版实例 2.设置密码 设置后可在终端复制上图2测试 [rootserver ~]# sudo docker login --usernameyou_aliyun_name crpi-8y14tvgewmc6tisz.cn-hangzhou.personal.cr.aliyuncs.com Password: WARNING! Your …