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

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.mzph.cn/web/5890.shtml

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

相关文章

react核心知识

1. 对 React 的理解、特性 React 是靠数据驱动视图改变的一种框架&#xff0c;它的核心驱动方法就是用其提供的 setState 方法设置 state 中的数据从而驱动存放在内存中的虚拟 DOM 树的更新 更新方法就是通过 React 的 Diff 算法比较旧虚拟 DOM 树和新虚拟 DOM 树之间的 Chan…

暂时性解决JDK21 无法使用 TimeUnit的问题

我调用 java.util中的TimeUtil时。 JDK17及以下版本时这样正常可以使用的 但是在JDK21中却是个TimeUtil.class文件 我没法调用内部的属性 解决方式&#xff1a;是我卸载了21&#xff0c;使用的了JDK17. 使用场景&#xff1a;原本项目是基于JDK8 的&#xff0c;但是因为其他…

什么是限流?常见的限流算法

目录 1. 什么是限流 2. 常见限流算法 3. 固定窗口算法 4. 滑动窗口算法 5. 漏桶算法 6. 令牌桶算法 7. 限流算法选择 1. 什么是限流 限流&#xff08;Rate Limiting&#xff09;是一种应用程序或系统资源管理的策略&#xff0c;用于控制对某个服务、接口或功能的访问速…

Sortable 拖拽行实现el-table表格顺序号完整例子,vue 实现表格拖拽行顺序号完整例子

npm install sortable<template><vxe-modalref"modalRef"v-model"showModal"title"详情"width"70vw"height"60vh"class"his"transfer><el-table ref"tableRef" :data"tableData&q…

机器学习-06-聚类算法总结

聚类总结 1.聚类 机器学习 任务 聚类 无label的 分类 label是离散的 回归 label是连续的 2.聚类算法-kmeans 划分聚类 思想&#xff1a; D中选取k个作为初始质心 repeat 计算所有点与质心的距离&#xff0c;分到近的质心簇 更新簇之间的质心 until 质心不改 不足&#xff…

Web自动化—Cypress 测试框架概述

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Cypress 测试框架概述 1.1 Cypress 默认文件结构 在Cypress安装…

6.python网络编程

文章目录 1.生产者消费者-生成器版2.生产者消费者--异步版本3.客户端/服务端-多线程版4.IO多路复用TCPServer模型4.1Select4.2Epoll 5.异步IO多路复用TCPServer模型 1.生产者消费者-生成器版 import time# 消费者 def consumer():cnt yieldwhile True:if cnt < 0:# 暂停、…

智能家居|基于SprinBoot+vue的智能家居系统(源码+数据库+文档)

智能家居目录 基于SprinBootvue的智能家居系统 一、前言 二、系统设计 三、系统功能设计 1管理员&#xff1a;个人中心管理功能的详细实现 2管理员&#xff1a;用户信息管理功能的详细实现 3管理员&#xff1a;家具管理功能的详细实现 4管理员&#xff1a;任务管理功能…

Python绘制的好看统计图

代码 sx [Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens, Greens_r, Greys, Greys_r, OrRd, OrRd_r, Oranges, Oranges_r, PRGn, PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, P…

CSAPP | Floating Point

CSAPP | Floating Point b i b_i bi​ b i − 1 b_{i-1} bi−1​ … b 2 b_2 b2​ b 1 b_1 b1​ b 0 b_0 b0​ b − 1 b_{-1} b−1​ b − 2 b_{-2} b−2​ b − 3 b_{-3} b−3​ … b − j b_{-j} b−j​ S ∑ k − j i b k 2 k S\sum_{k-j}^{i}b_k\times2^k S∑k…

了解一下创新奇智的 Orion 分布式机器学习平台

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 创新奇智的 Orion 分布式机器学习平台是一个企业级的端到端机器学习解决方案&#xff0c;它通过整合智能资源调度中心&#xff08;IRC&#xff09;、智能数据自动化中心&#xff08;DAC&#xff09;和自…

HarmonyOS 4.0(鸿蒙开发)01 - 怎么学习鸿蒙引导篇

作为公司的全栈开发工程师 以及 未来的发展是有鸿蒙这个阶段的&#xff0c;以及本身具有这个技术栈由此后续会分享自己在实战中学习到的东西&#xff0c;碰到的bug都会分享出来&#xff0c;这是引导篇期待后续的更新 学习目标&#xff1a; 理解HarmonyOS操作系统的架构和开发…

三维坐标点按剖面分类

一、写在前面 ①配套文件&#xff1a;根据剖面对三维坐标点&#xff08;X,Y,Z&#xff09;分类资源-CSDN文库 ②脱敏处理&#xff1a;蚀变数据已采用随机数生成覆盖 ③剖面坐标按顺序排列在“剖面坐标点.xlsx”文件中 二、3点确定空间中平面方程 原理&#xff1a; 设3点A&…

YOLOv8主要命令讲解

YOLOv8主要有三个常用命令&#xff0c;分别是&#xff1a;train&#xff08;训练&#xff09;、predict&#xff08;预测&#xff09;、export&#xff08;转化模型格式&#xff09;&#xff0c;下面我将展开讲讲三个常用命令的常用参数与具体使用方法。 一、训练 通过自己标…

Docker容器---Harbor私有仓库部署与管理

一、搭建本地私有仓库 1、本地私有仓库简介 有时候使用Docker Hub这样的公共仓库可能不方便&#xff0c;这种情况下用户可以使用registry创建一个本地仓库供私人使用&#xff0c;这点跟Maven的管理类似。 2、使用私有仓库的优点 节省网络带宽&#xff0c;针对于每个镜像不用…

知乎广告开户流程,知乎广告的优势是什么?

社交媒体平台不仅是用户获取知识、分享见解的场所&#xff0c;更是品牌展示、产品推广的重要舞台。知乎作为国内知名的知识分享社区&#xff0c;以其高质量的内容生态和庞大的用户基础&#xff0c;成为了众多企业进行广告投放的优选之地。云衔科技通过其专业服务&#xff0c;助…

【ZIP技巧】zip压缩包太大,怎么缩小?

如果文件压缩成zip压缩包&#xff0c;但是压缩之后&#xff0c;体积仍然很大&#xff0c;该如何解决呢&#xff1f;今天分享ZIP压缩包太大的几个缩小方法。 方法一&#xff1a; 适当减少文件内的不必要文件。 方法二&#xff1a; 使用7-zip格式压缩包&#xff0c;会比zip格…

Python异步Redis客户端与通用缓存装饰器

前言 这里我将通过 redis-py 简易封装一个异步的Redis客户端&#xff0c;然后主要讲解设计一个支持各种缓存代理&#xff08;本地内存、Redis等&#xff09;的缓存装饰器&#xff0c;用于在减少一些不必要的计算、存储层的查询、网络IO等。 具体代码都封装在 HuiDBK/py-tools: …

【PHP】安装指定版本Composer

1、下载指定版本composer.phar文件&#xff1a;https://github.com/composer/composer/releases 2、将下载的文件添加到全局路径&#xff1a; sudo mv composer.phar /usr/local/bin/composer 3、赋予权限&#xff1a; sudo chmod x /usr/local/bin/composer 4、查看compos…

Linux进程——进程的创建(fork的原理)

前言&#xff1a;在上一篇文章中&#xff0c;我们已经会使用getpid/getppid函数来查看pid和ppid,本篇文章会介绍第二种查看进程的方法&#xff0c;以及如何创建子进程&#xff01; 本篇主要内容&#xff1a; 查看进程的第二种方法创建子进程系统调用函数fork 在开始前&#xff…