自定义 Dockerfile 构建 PostgreSQL 15 编译版 Docker 镜像

news2024/11/25 2:24:11

BG

前几日 Sean 老师发布了一篇文章 – PostgreSQL安装(一): 再简单点儿,用Docker?, 介绍如何快速安装启动 PostgreSQL 数据库。

本文再稍微延伸一点,介绍一下如何自定义 Dockerfile,加入自己想要预制的参数,构建一个自定义的 Docker Image.

Dockerfile 介绍

Dockerfile 是用于定义 Docker 镜像的一种格式。它是一个包含了一系列指令的文本文件,每个指令对应一个镜像层的操作,用于指定如何构建 Docker 镜像。

以下是一个基本的 Dockerfile 示例:

# 使用一个基础镜像
FROM ubuntu:latest

# 更新软件包列表
RUN apt-get -y update

# 安装软件包
RUN apt-get install -y nginx

# 复制文件到容器中
COPY index.html /usr/share/nginx/html/

# 设置环境变量
ENV MY_VAR=my_value

# 暴露端口
EXPOSE 80

# 运行命令
CMD ["nginx", "-g", "daemon off;"]

这个示例 Dockerfile 做了以下几件事:

  • 使用最新版的 Ubuntu 作为基础镜像。
  • 更新软件包列表,并安装 Nginx。
  • 将一个名为 index.html 的文件复制到容器的 /usr/share/nginx/html/ 目录中。
  • 设置了一个名为 MY_VAR 的环境变量,其值为 my_value。
  • 暴露了容器的 80 端口。
  • 在容器启动时,运行 Nginx 并以守护进程模式运行。

使用 Dockerfile,可以通过在 Dockerfile 所在目录执行 docker build 命令来构建 Docker 镜像,例如:

docker build -t my_ngx:latest .

构建结果如下:

从另一个角度讲,如果有一个 Docker Image, 想剖析一下这个镜像如何生成,这样可能做到么?

类似于反编译,这是有难度的,但也可以查看到蛛丝马迹,

比如使用 docker history <image> 命令,查看 Image 的历史。

或者其他第三方工具,比如 dockerfile-from-image。

自定义 PostgreSQL 15 的 Dockerfile

上面介绍过了 Dockerfile 的基本结构,下面就来准备 PostgreSQL 的镜像,基本步骤如下:

1. 基于 CentOS 7 的最新版构建镜像

上面案例中的 FROM ubuntu:latest 改为 FROM centos:7 即可。
这里可以加上镜像的描述,比如维护者:

maintainer="Shawn Yan"

还可以加入其他系统环境变量,比如将语言设定为英文 utf8,

ENV LANG=en_US.UTF-8

2. 替换自带 yum 源,并安装依赖

As you know, CentOS 自带的官方 yum 源连接速度十分、非常、很不理想,所以这里将原有的 repo 文件替换成我常用的 repo。

然后,安装必要的依赖。
由于本文介绍的是构建编译版的 PostgreSQL,所以还需要安装编译工具,以及一些开发包。
这里其实就会出现一个副作用,构建出来的镜像 size 肯定要比直接安装二进制包要大。

# Update yum source
RUN rm -rf /etc/yum.repos.d/*.repo
ADD my.repo /etc/yum.repos.d/my.repo

# Install deps
RUN yum -y update \
    && yum -y install wget gcc make ...

RUN 命令上面介绍过了,ADD 是将本地文件添加到镜像中的指定位置,这里是将常用的 yum 源写入到 my.repo 再添加到镜像中。

3. 下载 PG 15 源码,并编译

说到编译 PostgreSQL 源码,这里介绍一个参数,--with-extra-version=STRING , 该参数将STRING附加到PostgreSQL版本号。例如,您可以使用它来标记从未发布的Git快照构建的二进制文件,或者包含带有额外版本字符串的自定义补丁,例如Git描述标识符或分发包发布号。

在 Dockerfile 中,使用 RUN 命令来执行动作,使用 && 接续动作,使用 \ 进行换行。

如此,下载源码,编译,安装一气呵成。

RUN wget https://mirrors.neusoft.edu.cn/postgresql/source/v$PG_VERSION/postgresql-$PG_VERSION.tar.gz \
    && echo "$PG_SHA256 postgresql-$PG_VERSION.tar.gz" | sha256sum -c - \
    && tar xzf postgresql-$PG_VERSION.tar.gz \
    && cd postgresql-$PG_VERSION \
    && ./configure --prefix=/opt/postgresql --with-extra-version="-ShawnYan" \
    && make -j $(nproc) world \
    && make install-world \

4. 创建 postgres 用户,并指定环境变量

在许多 Linux 系统中,PostgreSQL 用户的 UID 默认为 26。这是因为在过去的一些 Linux 系统中,UID 26 被保留给系统用户 postgres,该用户是PostgreSQL 数据库的默认所有者。这意味着如果你使用了默认的 PostgreSQL 安装程序,那么系统会自动为 postgres 用户分配 UID 26。
按照惯例,这里也将 postgres 用户的 UID 设定为 26。并将常用的环境变量预设好,如 PGDATA, PGHOME

RUN useradd -u 26 postgres \
    && echo "export PGDATA=/var/lib/pgsql/15/data" >> /home/postgres/.bash_profile \
    && echo "export PGHOME=/opt/postgresql" >> /home/postgres/.bash_profile \
    && echo "export PATH=\$PGHOME/bin:\$PATH" >> /home/postgres/.bash_profile \

5. 创建 PGDATA 目录,并初始化 PG 实例

创建 PGDATA 路径,并将权限赋予 postgres 用户。然后在 postgres 用户下初始化实例,初始化时指定数据目录。

# PGDATA
RUN mkdir -p /var/lib/pgsql/15/data && chown -R postgres:postgres /var/lib/pgsql
ENV PGDATA=/var/lib/pgsql/15/data

# Init
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/postgresql/bin
RUN su -l postgres -c "initdb --pgdata='$PGDATA'" 2>&1 < /dev/null

这样,当运行 docker image 时,镜像里的 PostgreSQL 就已经初始化完成,可以直接使用,而不需要进入容器再次调整。

6. 暴露 5432 端口,准备启动 PostgreSQL 服务

PG 默认使用 5432 端口,如果是实验环境则无需更改。更进一步,这个端口是启动后容器的端口,可通过 <容器IP:5432 > 直接访问容器里的 PG,而非宿主机上的端口,如需绑定到宿主机上的 5432 端口,则需要在启动容器上,传参 -p 5432:5432。还有一点好处是,可以同时运行若干容器,端口均为 5432,且不会冲突。

# Port
EXPOSE 5432

# Start PostgreSQL
CMD ["postgres", "-D", "/var/lib/pgsql/15/data"]

到此,自定义的 PostgreSQL 15 编译版 Dockerfile 已定制完成。

构建 PostgreSQL 15 镜像

Dockerfile 是核心,构建步骤很简单,只需要应用刚才的 dockfile 即可,剩下的交给 Docker。

docker build -f Dockerfile -t my-postgresql:15.2 .

build 时传参 -t 可以将生成的镜像打上标签和版本号。

镜像构建完成后,可使用 docker images 查看镜像。

拉取 PostgreSQL 官方镜像,对比可以发现自定义的镜像文件比官方镜像大 200MB 多。

[root@centos7 docker]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED        SIZE
my-postgresql   15.2      7028a1396388   14 hours ago   633MB
postgres        latest    3b6645d2c145   2 weeks ago    379MB

运行 PostgreSQL 容器

可以指定镜像直接启动容器:

[root@centos7 docker]# docker run -d my-postgresql:15.2
a0ed010c3f0252614f2840dd7485190be6f708066e8822bb10b219e5342474e5
[root@centos7 docker]# docker ps
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS      NAMES
a0ed010c3f02   my-postgresql:15.2   "postgres -D /var/li…"   4 seconds ago   Up 3 seconds   5432/tcp   intelligent_perlman

也可以指定名称启动容器,但要注意 name 需要放到镜像名前:

[root@centos7 docker]# docker run --name pg15 -d my-postgresql:15.2
35d5cdcf4e375d6e1be3bd07730c4774fc58cb3f9586d1c44a4cb81fddcb38d9
[root@centos7 docker]# docker run --name s1 -d my-postgresql:15.2
05ffd0e594d35fc05175e92a1f6919f16fcaa48be6237271e4273ce2097c97a7
[root@centos7 docker]# docker run --name s2 -d my-postgresql:15.2
7ca429feae556ec16bc197f9bac6e0590d28b7b50479f5d1ef88c853689d7858
[root@centos7 docker]# docker ps
CONTAINER ID   IMAGE                COMMAND                  CREATED          STATUS          PORTS      NAMES
7ca429feae55   my-postgresql:15.2   "postgres -D /var/li…"   3 seconds ago    Up 2 seconds    5432/tcp   s2
05ffd0e594d3   my-postgresql:15.2   "postgres -D /var/li…"   18 seconds ago   Up 16 seconds   5432/tcp   s1
35d5cdcf4e37   my-postgresql:15.2   "postgres -D /var/li…"   28 seconds ago   Up 27 seconds   5432/tcp   pg15

可直接连接容器里的 postgresql:

docker exec -it pg15 psql

也可使用本地 psql 客户端连接容器,但需先确认容器的 IP,或者在启动容器前传参绑定端口:

psql -h 172.17.0.3

后续

定制容器可以做的事情还很多,比如:

  1. 内置数据库、用户,开箱即用
  2. 最短时间、最小资源启动主从复制,或配置高可用架构
  3. 可反复创建、销毁容器,作为实验环境不断练习

– END –

如果这篇文章为你带来了灵感或启发,就请帮忙点『赞』or『在看』or『转发』吧,感谢!(๑˃̵ᴗ˂̵)

本文由mdnice多平台发布

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

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

相关文章

C语言----贪吃蛇(补充)

各位看官好&#xff0c;我想大家应该已经看过鄙人的上一篇博客贪吃蛇了吧。鄙人在上一篇博客中只是着重的写了贪吃蛇的实现代码&#xff0c;但是前期的一些知识还没有具体的介绍&#xff0c;比如确认光标位置&#xff0c;句柄等。那么我这一篇博客就来补充上一篇博客所留下来的…

笔试狂刷--Day9(模拟 + dp + 规律)

大家好,我是LvZi,今天带来笔试狂刷--Day9 一.添加逗号 题目链接:添加逗号 分析: 模拟 代码: import java.util.*;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);i…

社交媒体数据恢复:TT语音

TT语音数据恢复方法 1. 恢复聊天记录 如果您的TT语音聊天记录丢失&#xff0c;可以通过以下步骤尝试恢复&#xff1a; 登录TT语音&#xff1a;首先&#xff0c;您需要登录您的TT语音账户。如果您忘记了密码&#xff0c;可以通过点击登录页面的“忘记密码”链接&#xff0c;然…

【强训笔记】day7

NO.1 思路&#xff1a;双指针模拟&#xff0c;begin表示最长数字字符串最后一个字符&#xff0c;而len表示数字字符串的长度&#xff0c;i用来遍历&#xff0c;如果为数字&#xff0c;那么定义j变量继续遍历&#xff0c;直到不为数字&#xff0c;i-j如果大于len&#xff0c;就…

基于寄存器的STM32操作流程

寄存器点灯 寄存器操作STM32的好处是不需要依靠外部文件&#xff0c;自由度更高&#xff0c;更为底层&#xff0c;但也更加繁杂。 通过寄存器点灯&#xff0c;需要按照电路结构与手册配置寄存器&#xff1a; 电路结构如下&#xff1a;可知需配置的GPIO为GPIOB5与GPIOE5。 在…

机器学习之基于Jupyter中国环境治理投资数据分析及可视化

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 机器学习之基于Jupyter中国环境治理投资数据分析及可视化项目是一个结合了机器学习和数据可视化技术的项目&#xf…

SoapUI-x64-5.7.2安装教程

http://localhost:49652/Test.asmx?WSDL 双击请求&#xff1a;

Word技巧:3种方法快速重复上一步操作

在编辑Word文档的时候&#xff0c;我们经常需要重复上一步操作&#xff0c;如果重复性的操作很多&#xff0c;就会很耽误时间&#xff0c;那怎么可以快速重复上一步操作呢&#xff1f;下面分享3种方法&#xff0c;一起来看看吧&#xff01; 方法1&#xff1a;利用“格式刷”功能…

利用亚马逊云科技GenAI企业助手Amazon Q Business构建企业代码开发知识库

2024年五一节假日的前一天&#xff0c;亚马逊云科技正式重磅发布了云计算行业期待已久的服务——Amazon Q Business。Amazon Q Business是专为企业用户打造的一个开箱即用的完善而强大企业GenAI助手。企业用户只需要将Amazon Q Business连接到现有的企业内部数据源&#xff0c;…

【免费Java系列】大家好 ,给大家出一些今天学习内容的案例点赞收藏关注,持续更新作品 !

PS:每个内容块下都有教学博文的超链接,有需要可以点过去学习 ! 目录 匿名内部类 1. 实现接口 2. 继承抽象类 3. 实现事件处理 枚举 1. 定义一个简单的枚举类型 2. 枚举类型可以有属性和方法 3. 枚举类型可以实现接口 泛型 1. 定义一个泛型类 2. 使用泛型方法 3. 泛型…

华为手机 鸿蒙系统-android studio识别调试设备,开启adb调试权限

1.进入设置-关于手机-版本号&#xff0c;连续点击7次 认证&#xff1a;有锁屏密码需要输入密码&#xff0c; 开启开发者配置功能ok 进入开发者配置界面 打开调试功能 重新在androd studio查看可运行running devices显示了&#xff0c; 不行的话&#xff0c;重启一下android …

【Flask 系统教程 4】Jinjia2模版和语法

Jinjia2 模板 模板的介绍 Jinja2 是一种现代的、设计优雅的模板引擎&#xff0c;它是 Python 的一部分&#xff0c;由 Armin Ronacher 开发。Jinja2 允许你在 HTML 文档中嵌入 Python 代码&#xff0c;以及使用变量、控制结构和过滤器来动态生成内容。它的语法简洁清晰&#…

U盘未初始化?别慌,数据还有救!

当我们将U盘插入电脑&#xff0c;期待地打开“我的电脑”或文件管理器&#xff0c;却发现U盘显示为未初始化&#xff0c;这种心情无异于一盆冷水浇头。但先别急着慌张&#xff0c;这篇文章将带你了解U盘未初始化的原因&#xff0c;并提供有效的数据恢复方案&#xff0c;让你在遭…

24.5.2数据结构|顺序表实现

主要是记笔记&#xff0c;留着以后复习回来看的&#xff0c;有些内容解释的并不清晰。也就稍微可以借鉴借鉴。 目录 一、如何定义结构&#xff1f; 二、看书搞清楚顺序表实现流程 三、使用clion写代码 实现代码过程中的错误代码 一、如何定义结构&#xff1f; 应该有的部…

AI与电力

好多写AI会导致电力匮乏的消息,不绝于耳。然而大部分只能知其然,却不能知其所以然,为什么缺,怎么缺,缺多少,没什么答案也没什么可参考的。 我关注一个事情,一般先了解一下论点,然后重点看论据,最后再自己论证合理不。今天这篇文章主要聊一下数据层面上是谈一谈AI如何导…

微信小程序+esp8266温湿度读取

本文主要使用微信小程序显示ESP8266读取的温湿度并通过微信小程序控制LED灯。小程序界面如下图所示 原理讲解 esp8266 通过mqtt发布消息,微信小程序通过mqtt 订阅消息,小程序订阅后,就可以实时收到esp8266 传输来的消息。 个人可免费注册五个微信小程序账号,在微信小程序官…

Python_GUI框架 Pyside6的信号与槽应用

Python_GUI框架 Pyside6的信号与槽应用 在Pyside6框架中&#xff0c;信号与槽&#xff08;Signals and Slots&#xff09;机制是连接用户界面元素与响应功能的核心机制。我们可以把信号想象成一根电线&#xff0c;而槽就是电线的另一端连接的灯泡。当电线&#xff08;信号&…

ubuntu 小工具

随着在专业领域待得越久&#xff0c;发现总会遇到各种奇怪的需求。因此&#xff0c;这里介绍一些ubuntu上的一些小工具。 meld 对比文件 sudo apt-get install meld sudo apt --fix-broken install # maybeHow to compare two files

量子城域网建设设备系列(二):量子密钥管系统(KMS)

在上文介绍光量子交换机的文章中我们提到&#xff0c;量子保密通信网络的通道切换是由量子密钥管理系统&#xff08;Key Management System&#xff0c;KMS&#xff09;给光量子交换机下发信道切换指令&#xff0c;实现整个网络中任意两对量子密钥分发终端的量子信道互联互通&a…

buuctf-misc-23.FLAG

23.FLAG 题目&#xff1a;stegsolve得出PK-zip文件&#xff0c;改后缀名为zip,解压后查看文件类型为ELF 使用kali-strings或者ida获取flag 点击Save Bin将其另存为一个zip文件 而后解压我们另存的这个1234.zip文件后&#xff0c;可以得到 我们用ida打开它&#xff0c;打开后就…