dockerfile避坑笔记(VMWare下使用Ubuntu在Ubuntu20.04基础镜像下docker打包多个go项目)

一、docker简介

docker是一种方便跨平台迁移应用的程序,通过docker可以实现在同一类操作系统中,如Ubuntu和RedHat两个linux操作系统中,实现程序的跨平台部署。比如我在Ubuntu中打包了一个go项目的docker镜像(镜像为二进制文件,相当于windows中的exe文件),这个镜像可以直接在另一台Ubuntu上运行,而无需再次配运行环境。下面这张图是我对docker的理解。
原始程序迁移方式在这里插入图片描述
docker镜像迁移方式
在这里插入图片描述

二、dockerfile编写

将项目打包为docker镜像通过编写dockerfile来实现,dockerfile的写法类似于shell编程。
PS:最终的dockerfile不易过长(但是调试时可以多些RUN,这样可以减少重复编译,提高调试速度),因为每个语句都会被编译为一个镜像,然后commit到一起形成一个最终的镜像。
其基本的结构如下:

FROM ***(指定基础镜像,即这个镜像在哪个操作系统下面运行)
#示例:FROM  Ubuntu:20.04

MAINTAINER ***(指定维护者信息,选填)
#示例:MAINTAINER Tom

LABEL ***(docker build的启动入口,可以不写)
#示例:LABEL helloworld

RUN ***(docker build时需要执行的命令,为shell指令)
#RUN git clone github.com/xxxx.git

ADD/COPY ***(将宿主机的文件拷贝到目标镜像中,ADD会自动解压,COPY不会)
#示例:COPY 	. .
#前一个目录为当前文件夹下的相对路径,后一个文件为dockerfile镜像中的路径

WORKDIR ***(设置当前工作目录,相当于进入容器后在哪个目录里面)


VOLUME ***(存放文件的地方,也叫挂载主机目录,分布式存储中使用)

EXPOSE ***(指定对外的端口)

CMD ***(指定容器启动后要做的事情)

打包镜像:

docker build -t demo/go-hello:1.0 -f dockerfile .
#docker build为固定写法,-t表示生成目标镜像的名字以及版本号 -f表示dockerfile文件的名称,
#最后的‘.’表示当前目录下构建docker

构建运行容器:

docker run  -it -p xxx:xxx
#-i 以交互模式运行,-t 为容器分配一个命令行
#-p 容器端口映射到主机端口的模式

三、docker build原理

完成dockerfile后,需要运行docker build命令来执行程序。
docker build的执行过程如下:

1.将上下文打包发送到docker的守护进程

2.docker build 命令向docker server 发送http请求,请求包含上下文信息。

3.docker server开始构建镜像:
①创建一个临时目录,将上下文中的内容解压到临时目录下,然后读取dockerfile中的指令。
②将执行分发到不同的模块进行操作,为每一条指令构造一个临时容器并执行,执行完毕后commit。
③将所有commit的镜像合并,得到最终的镜像。

这里需要注意,docker build会将当前文件下的所有文件发送到docker server,如果有些文件在docker过程中并不需要,可以在当前目录下创建忽略 .dockerignore 文件,并写入忽略文件的文件名。

docker避坑笔记

调试背景

我在windows10下安装VMWare,WMware中安装了Ubuntu20.04,并使用桥接模式连接的windows10主机。(说明虚拟机与主机的IP地址互相独立,Ubuntu无法通过127.0.0.1访问Windos10),同时在Ubuntu20.04基础镜像下打包golang项目的镜像。

问题1:docker build运行dockerfile报错,E: Unable to locate package xxx

这里报错有很多原因,大概可以归为以下几类:
1、当前的apt-get不是最新版,所以无法找到这个库
解决方案,运行apt-get update

apt-get update

2、使用上述方法后,仍然报错,可能就是真的没这个包,或者这个包在外网下载,国内无法访问或访问速度过慢。这里采用换源的方法,看看能不能解决。
解决方案:在dockerfile中加入

RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

问题2:dockerfile安装golang时报错,显示Do you want to continue? [Y/n] Abort.

dockerfile运行过程中,无法接受用户的输入,但是有些软件包的安装过程需要用户进行交互,所以会出现问题。
解决方案:在dockerfile中加入下面两句话:

ENV DEBIAN_FRONTEND=noninteractive #关闭交互功能

apt-get install -y xxx #-y表示所有的交互都是选择默认的选项,xxx为需要安装的包名

问题3:dockerfile运行apt-get install golang时报错,显示Undefined:any

开发环境为golang1.21.3,但是是用apt-get install golang默认下载的版本小于golang1.18,,而any关键字是golang1.18以后才引入的关键字,所以会没法编译。
解决方案:不使用apt-get install golang安装,更换下面的方式

#指定版本安装golang
RUN apt-get update && apt-get install -y wget && \
    wget https://mirrors.aliyun.com/golang/go1.21.3.linux-amd64.tar.gz && \
    tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz && \
    rm go1.21.3.linux-amd64.tar.gz

# 设置Go的环境变量
ENV PATH=$PATH:/usr/local/go/bin

问题4:开启容器后,使用Ubuntu访问容器端口,发现连接被重置(等于容器的端口连不上)。

这里涉及到了2个知识,
第一个知识是,容器默认的网络模式是桥接,即容器内部具有独立的IP地址,通过0.0.0.0IP对外提供服务。所以,如果程序内部原来通过127.0.0.1:8888的方式对其他容器或者主机提供服务,那么需要改为0.0.0.0:8888。如果主机想要通过127.0.0.1::8888访问容器,需要更改docker run语句如下:

docker run -d -p 127.0.0.1:8888:8888 <image_name>

这里说明了端口映射,将容器的0.0.0.0::8888端口映射到主机的127.0.0.1:8888端口。
第二个知识是防火墙有可能会拦截请求,最好把Ubuntu的防火墙关了。

#关闭防火墙服务
sudo systemctl stop ufw.service

#检查防护墙服务是否关闭
sudo ufw status

我试了前面两个办法都不行,只能上大招,重启容器的网卡服务。

systemctl stop docker # 停止docker 服务
pkill docker # 杀掉docker进程
iptables -t nat -F # 清理iptables
ip link set docker0 down # 停止docker0网卡
brctl delbr docker0 # 删除docker0网卡--重点!
systemctl start docker # 启动docker服务

问题5:上述方法可以实现容器与主机的通信,但是容器之间的通信还需要获取到容器的IP地址才可以实现

但是我在本地编写的代码,都是用的127.0.0.1:xxxx的格式进行通讯,现在突然要换为容器的IP地址进行通讯,又需要更改代码,所以我采用了其他方式,将容器的网络模式更换为host模型,即与主机共享同一个IP空间。

最终的dockerfile

# 使用指定的基础镜像
FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive

# 换为清华源
# RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

RUN apt-get update && apt-get install -y gcc git

RUN apt-get update && apt-get install -y wget && \
    wget https://mirrors.aliyun.com/golang/go1.21.3.linux-amd64.tar.gz && \
    tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz && \
    rm go1.21.3.linux-amd64.tar.gz

# 设置Go的环境变量
ENV PATH=$PATH:/usr/local/go/bin

# 创建工作目录并拷贝你的 Go 项目代码到容器中
WORKDIR /Cache
COPY . /Cache

# 构建Go项目
RUN go build -o server2

# 暴露应用程序所使用的端口
EXPOSE 9528
EXPOSE 8766

# 定义容器启动命令,这里假设你的Go项目生成了一个名为server1的可执行文件
CMD ["./server2"]

最终的docker-compose.yml

version: '3'

services:
  service1:
    build: ./server1
    network_mode: "host"

  service2:
    build: ./server2
    network_mode: "host"

  service3:
    build: ./server3
    network_mode: "host"

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年11月5日网规考试备忘

早上题目回忆&#xff1a; pki体系 ipsec&#xff0c;交换安全&#xff08;流量抑制&#xff09; aohdlc bob metclaf —ethernet pon tcp三次握手 OSPF lsa&#xff1f;交换机组ospf配置问题&#xff0c;ping网关可通&#xff0c;AB不通 raid6 300G*8 网络利用率 停等协议10…

【C++初阶】一、入门知识讲解(C++关键字、命名空间、C++输入输出、缺省参数、函数重载)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【数据结构初阶】十一、归并排序(比较排序)的讲解和实现 &#xff08;递归版本 非递归版本 -- C语言实现&#xff09;-CSDN博客 引入&#xff1a;什么是C C语言是结构化和模块化的…

剑指JUC原理-9.Java无锁模型

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

Flink SQL 窗口聚合详解

1.滚动窗⼝&#xff08;TUMBLE&#xff09; **滚动窗⼝定义&#xff1a;**滚动窗⼝将每个元素指定给指定窗⼝⼤⼩的窗⼝&#xff0c;滚动窗⼝具有固定⼤⼩&#xff0c;且不重叠。 例如&#xff0c;指定⼀个⼤⼩为 5 分钟的滚动窗⼝&#xff0c;Flink 将每隔 5 分钟开启⼀个新…

如何在知识付费系统小程序开发中实现社区互动和用户参与

在知识付费系统小程序的开发中&#xff0c;实现社区互动和用户参与可以通过以下步骤实现&#xff1a; 1. 建立用户身份验证和管理系统 // 后端示例代码&#xff08;Node.js&#xff09; // 用户注册 app.post(/register, (req, res) > {const { username, email, passwor…

如何在电脑上制作可视化待办任务清单?

在现代高效工作的节奏下&#xff0c;上班族们需要管理大量的待办任务和工作事项。可视化的待办任务清单能够使我们清晰地了解自己的任务进度和工作优先级。每天打开电脑&#xff0c;我们可以直观地看到还有哪些任务需要完成&#xff0c;避免遗漏和混乱。而如何将这些任务清单可…

数据结构之堆的实现(图解➕源代码)

一、堆的定义 首先明确堆是一种特殊的完全二叉树&#xff0c;分为大根堆和小根堆&#xff0c;接下来我们就分别介绍一下这两种不同的堆。 1.1 大根堆&#xff08;简称&#xff1a;大堆&#xff09; 在大堆里面&#xff1a;父节点的值 ≥ 孩子节点的值 我们的兄弟节点没有限制&…

Nacos2.2.3版本运行startup.cmd出现闪退,无错误信息解决方法

Nacos2.2.3版本运行startup.cmd出现闪退&#xff0c;无错误信息解决方法 一、问题描述二、解决方法 一、问题描述 当我下载好nacos2.2.3版解压之后&#xff0c;直接双击startup.cmd出现闪退&#xff0c;而且 没有错误提示信息。后来经过一番搜索尝试&#xff0c;终于解决了自己…

Spring 中 @Qualifier 注解还能这么用?

今天想和小伙伴们聊一聊 Qualifier 注解的完整用法&#xff0c;同时也顺便分析一下它的实现原理。 说到 Qualifier&#xff0c;有的小伙伴可能会觉得诧异&#xff0c;这也只得写一篇文章&#xff1f;确实&#xff0c;但凡有点开发经验&#xff0c;多多少少可能都遇到过 Qualif…

《算法通关村—轻松搞定合并二叉树》

《算法通关村—轻松搞定合并二叉树》 描述 leetcode 617 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要将这两棵树合并成一棵…

酒水展示预约小程序的效果如何

酒的需求度非常高&#xff0c;各种品牌、海量经销商组成了庞大市场&#xff0c;而在实际经营中&#xff0c;酒水品牌、经销商、门店经营者等环节往往也面临着品牌传播拓客引流难、产品展示预约订购难、营销难、销售渠道单一等痛点。 那么商家们应该怎样解决呢&#xff1f; 可以…

Vue3多页面开发实践

前言&#xff1a; 项目需求&#xff0c;把项目中的一个路由页面单摘出来作为一个新的项目。项目部署到服务器上后&#xff0c;通过一个链接的形式可以直接访问到新项目的页面。 解决方式&#xff1a; 使用Vue多页面方式打包项目 实现步骤&#xff1a; 1、在项目的src目录下&am…

MySQL(8):聚合函数

聚合函数介绍 聚合函数&#xff1a; 对一组数据进行汇总的函数&#xff0c;输入的是一组数据的集合&#xff0c;输出的是单个值。 聚合函数类型&#xff1a;AVG(),SUM(),MAX(),MIN(),COUNT() AVG / SUM 只适用于数值类型的字段&#xff08;或变量&#xff09; SELECT AVG(…

【IK分词器安装】

安装IK分词器&#xff1a; 下载链接&#xff08;如果es版本不同可以修改下版本号&#xff09;&#xff1a;https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip 通常下载是比较慢的&#xff1a;有需要可以从…

golang工程——opentelemetry简介、架构、概念、追踪原理

opentelemetry 简介 OpenTelemetry&#xff0c;简称OTel&#xff0c;是一个与供应商无关的开源可观测性框架&#xff0c;用于检测、生成、收集和导出 遥测数据&#xff0c;如轨迹、度量、日志。OTel的目标是提供一套标准化的供应商无关SDK、API和工具&#xff0c;用于接 收、…

Mean-Shift聚类方法

刘玉琪 跟随 出版于 台湾人工智能学院 一、说明 上一篇介绍了基于密度的分群方法——DBSCAN&#xff0c;本篇会介绍另一个分群方法——Mean Shift&#xff0c;与DBSCAN一样不需要预先知道欲分群的数量&#xff0c;而对于分群的形状也没有限制。 然而&#xff0c;这个方法是基…

网络层:控制平面

路由选择算法 路由选择算法就是为了在端到端的数据传输中&#xff0c;选择路径上路由器的最好的路径。通常&#xff0c;一条好的路径指具有最低开销的路径。最低开销路径是指源和目的地之间具有最低开销的一条路。 根据集中式还是分散式来划分 集中式路由选择算法&#xff1a…

基础Redis-Java客户端操作介绍

Java客户端操作介绍 2.基础-Redis的Java客户端a.介绍b.Jedisc.Jedis连接池d.SpringDataRedise.SpringDataRedis的序列化方式f.StringRedisTemplate 2.基础-Redis的Java客户端 a.介绍 Jedis 以Redis命令作为方法名称&#xff0c;学习成本低&#xff0c;简单实用。但是Jedis实例…

性能工作站,双十一大促,超值推荐:蝰蛇峡谷 NUC12SNKi7迷你主机,优惠抢购!

近年来&#xff0c;ITX主机和小型化系统变得越来越受欢迎。英特尔的NUC受到许多玩家们的关注。作为mini主机的代表NUC小巧设计和灵活性使它成为很多玩家和科技爱好者的选择。它的高性能和可玩性使得它在迷你型准系统市场上备受推崇。双11来临之际&#xff0c;我们分析下哪款高性…

【React】【react-globe.gl】3D Objects效果

目录 想要实现的效果实现过程踩坑安装依赖引入页面 想要实现的效果 示例地址 实现过程 踩坑 示例是通过script引入的依赖&#xff0c;但本人需要在react项目中实现该效果。按照react-globe.gl官方方法引入总是报错 Cant import the named export AmbientLight from non EcmaS…