自定义 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多平台发布

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

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

相关文章

使用unreal engine5.3.2创建c++第一人称游戏

UE5系列文章目录 文章目录 UE5系列文章目录前言一、NuGet 简介二、解决方法&#xff1a; 前言 为了使用unreal engine5.3.2创建c第一人称游戏&#xff0c;今天安装了Visual Studio 2022专业版。在ue5中创建c工程&#xff0c;结果编译器报错&#xff1a; 严重性 代码 说明 项目…

如何构建用于从收据中提取信息的生成式人工智能工具

原文地址&#xff1a;how-to-build-a-generative-ai-tool-for-information-extraction-from-receipts 使用 LangChain 和 OpenAI 工具从 Google Drive 中存储的收据图像中提取结构化信息 2024 年 4 月 10 日 纸质收据有各种样式和格式&#xff0c;是自动信息提取的一个有趣目…

【大模型应用】使用 Windows 窗体作为 Copilot 应用程序的 Ollama AI 前端(测试llava视觉问答)...

项目 “WinForm_Ollama_Copilot” 是一个使用Windows Forms作为前端的Ollama AI Copilot应用程序。这个项目的目的是提供一个用户界面(UI)&#xff0c;通过它&#xff0c;用户可以与Ollama AI进行交互。以下是该项目的一些关键特点和功能&#xff1a; Ollama Copilot: 这是一个…

SSM+Vue在线OA办公系统

在线办公分三个用户登录&#xff0c;管理员&#xff0c;经理&#xff0c;员工。 SSM架构&#xff0c;maven管理工具&#xff0c;数据库Mysql&#xff0c;系统有文档&#xff0c;可有偿安装调试及讲解&#xff0c;项目保证质量。需要划到 最底 下可以联系到我。 功能如下&am…

免安装SQL管理工具HeidiSQL建库如何选Collation字符校对

免安装SQL管理工具HeidiSQL 文章目录 免安装SQL管理工具HeidiSQL一、安装二、建库因此&#xff0c;通常我们选择&#xff1a; 一、安装 到官方网址&#xff1a;https://www.heidisql.com/ 下载后按不同版本安装或解压&#xff0c;运行目录中的heidisql应用程序。 该工具可以对…

万界星空科技商业开源MES+项目合作+商业开源低代码平台

今天我想和大家分享的是一套商业开源的 MES制造执行管理系统带源码。对于制造业而言&#xff0c;MES 是一个至关重要的系统&#xff0c;它可以帮助企业提高生产效率、优化资源利用、提高产品质量&#xff0c;从而增强市场竞争力。 什么是 MES&#xff1f; MES 是指通过计算机技…

Luminar开始为沃尔沃生产下一代激光雷达传感器

在自动驾驶技术的浪潮中&#xff0c;激光雷达&#xff08;LiDAR&#xff09;传感器以其高精度和强大的环境感知能力&#xff0c;逐渐成为了该领域的技术之星。Luminar&#xff08;路安达&#xff09;公司作为自动驾驶技术的领军企业&#xff0c;近日宣布已开始为沃尔沃汽车生产…

Git使用指北

目录 创建一个Git仓库本地仓库添加文件文件提交到本地仓库缓冲区添加远程仓库地址本地仓库推送到远程仓库创建新的分支拉取代码同步删除缓冲区的文件&#xff0c;远程仓库的文件.gitignore文件 创建一个Git仓库 Git仓库分为远程和本地两种&#xff0c;远程仓库如Githu上创建的…

Themis新篇章:老牌衍生品协议登陆Blast L2,探索全新经济模型

本文将深入分析 Themis 的最新经济模型&#xff0c;探讨其核心概念和机制、优势与创新之处、风险与挑战。 一、引言 随着区块链技术的不断发展&#xff0c;DeFi 衍生品项目逐渐成为市场的焦点。而用户体验的革新&#xff0c;进一步的金融创新&#xff0c;去中心化治理方案的优…

Golang | Leetcode Golang题解之第63题不同路径II

题目&#xff1a; 题解&#xff1a; func uniquePathsWithObstacles(obstacleGrid [][]int) int {n, m : len(obstacleGrid), len(obstacleGrid[0])f : make([]int, m)if obstacleGrid[0][0] 0 {f[0] 1}for i : 0; i < n; i {for j : 0; j < m; j {if obstacleGrid[i]…

Java中使用Redis实现分布式锁的三种方式

1. 导语 随着软件开发领域的不断演进,并发性已经成为一个至关重要的方面,特别是在资源跨多个进程共享的分布式系统中。 在Java中,管理并发性对于确保数据一致性和防止竞态条件至关重要。 Redis作为一个强大的内存数据存储,为在Java应用程序中实现分布式锁提供了一种高效的…

go-mysql-transfer 同步数据到es

同步数据需要注意的事项 前提条件 1 要同步的mysql 表必须包含主键 2 mysql binlog 必须是row 模式 3 不支持程序运行过程中修改表结构 4 要赋予连接mysql 账号的权限 reload, replication super 权限 如果是root 权限则不需要 安装 go-mysql-transfer ​ git clone…

和丰多媒体信息发布系统 QH.aspx 文件上传漏洞复现

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

《十二》Qt各种对话框之FileDialog文件对话框及QMessageBox 消息对话框

QFileDialog 对话框 选择打开一个文件 若要打开一个文件&#xff0c;可调用静态函数 QFileDialog::getOpenFileName()&#xff0c;“打开一个文件”按钮的响应代码如下&#xff1a; void Dialog::on_btnOpen_clicked() { //选择单个文件QString curPathQDir::currentPath()…

【Docker】如何注册Hub账号并上传镜像到Hub仓库

一、创建Hub账户 浏览器访问&#xff1a;hub.docker.com 点击【Sign up】注册账号 输入【邮箱】【用户名】【密码】 ps&#xff1a;用户名要有字母数字&#xff1b;订阅不用勾选 点击【Sign up】注册即可 点击【Sign in】登录账号 输入【邮箱】【密码】 点击【Continue】登录 二…

大数据之数据仓库技术:ETL工具和Kettle简介

大数据之数据仓库技术&#xff1a;ETL工具和Kettle简介 ETL简介ETL工具和KettleKettle家族 Kettle资源KettlePack 任务调度工具 ETL简介 ETL(Extract-Transform-Load): 在大数据技术领域内&#xff0c;用来描述将数据从 来源端 经过 抽取(extract), 转换(transform), 加载(loa…

cefsharp实现资源替换如网页背景、移除替换标签、html标识、执行javascript脚本学习笔记(含源码说明)

(一)实现测试(仅供学习参考) 1.1 目标系统页面(登录页)和登录后首页面中2处(一个替换一个移除) 1.2 实现后效果(使用cefsharp自定义浏览器实现以上功能) 1.3 登录后页面替换和移除 系统名称和一个功能菜单li (二)通过分析代码实现脚本编写 2.1 分开处理,设置了…

C语言/数据结构——每日一题(反转链表)

一.前言 大家好&#xff01;今天又是每日一题环节。今天我为大家分享了一道单链表题——反转链表。 废话不多说&#xff0c;让我们直接进入正题吧。 二.正文 1.1题目信息 这是一道leetCode上面的一道题&#xff1a;https://leetcode.cn/problems/reverse-linked-list 1.2解…

Linux 第十八章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

一周零碎时间练习微服务(nacos,rq,springcloud,es等)内容

目录 1 总览1.1 技术架构1.2 其他1.2.1 数据库1.2.2 后端部分1.2.2.1 复习feign1.2.2.2 复习下网关网关的核心功能特性&#xff1a;网关路由的流程断言工厂过滤器工厂全局过滤器 过滤器执行顺序解决跨域问题 1.2.2.3 es部分复习 1.2.3 前端部分 2 day1 配置网关2.1 任务2.2 网关…