我一般都是通过docker部署应用的,主要是方便,体验类似手机安装APP。
网络环境不好的话记得先配置docker镜像加速。
这里使用的是compose文件加env文件的部署方式,避免在compose文件中暴露明文的用户名和密码等关键数据。
bitnami镜像
理论来说相比原版镜像有更高的安全性和性能表现,但需要注意CPU不支持AVX/AVX2指令集的话是跑不起来的,得换官方镜像。
compose文件:
在任意目录创建一个docker-compose.yml文件,本文假设路径在/opt/compose/postgresql,内容如下:
services:
postgres:
# 指定使用 Bitnami 封装的镜像,也可自定义版本号
image: bitnami/postgresql:latest
# 容器名称
container_name: postgres
# 容器退出后总是自动重启
restart: always
# 端口映射: [主机端口]:[容器端口]
# 将服务器的 5432 端口映射到容器的 5432 端口
ports:
- "5432:5432"
# 环境变量,用于初始化数据库
environment:
# 【重要】设置 PostgreSQL 数据库的超级用户(postgres)的密码
- POSTGRESQL_POSTGRES_PASSWORD=${POSTGRESQL_POSTGRES_PASSWORD}
# 【重要】创建一个普通用户 即使你之后不用
- POSTGRESQL_USERNAME=${POSTGRESQL_USERNAME}
# 【重要】为上面的普通用户设置密码
- POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD}
# (可选) 创建一个初始数据库
- POSTGRESQL_DATABASE=${POSTGRESQL_DATABASE}
# 习惯设置时区,主要是看日志方便
- TZ=Asia/Shanghai
# 设置数据库的默认编码与区域,避免乱码
- LANG=C.UTF-8
# 设置共享内存,内存少或者读写频率低不用开
- POSTGRESQL_SHARED_BUFFERS=256MB
# 数据卷挂载,用于持久化数据
volumes:
# 将主机当前目录下的 postgres-data 文件夹映射到容器内的数据目录
# Bitnami 镜像的数据目录通常是 /bitnami/postgresql
- ./postgres-data:/bitnami/postgresql
# 健康检查,可以不用
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# 创建并使用这个docker网络
networks:
default:
name: my_app_network
.env 文件:
在docker-compose.yml文件同目录下创建.env文件,内容如下:
# PostgreSQL 超级用户'postgres'的密码
POSTGRESQL_POSTGRES_PASSWORD=your_strong_superuser_password
# 要创建的应用程序用户名
POSTGRESQL_USERNAME=your_strong_user_name
# 应用程序用户的密码
POSTGRESQL_PASSWORD=your_strong_user_password
# 要创建的数据库名
POSTGRESQL_DATABASE=your_database_name
注:=号后面是要自行替换的数据
部署过程:
cd到compose文件夹,创建文件夹并赋予权限
cd /opt/compose/postgresql
mkdir ./postgres-data
sudo chown 1001:1001 ./postgres-data
然后启动就好了
docker compose up -d
官方镜像
官方镜像朴实无华,首要目标是最广泛的兼容性。
compose文件:
在任意目录创建一个docker-compose.yml文件,本文假设路径在/opt/compose/postgresql,内容如下:
services:
postgres:
# 指定使用 Bitnami 封装的镜像,也可自定义版本号
image: postgres:latest
# 容器名称
container_name: postgres
# 容器退出后总是自动重启
restart: always
# 端口映射: [主机端口]:[容器端口]
# 将服务器的 5432 端口映射到容器的 5432 端口
ports:
- "5432:5432"
# 环境变量,用于初始化数据库
environment:
# 【重要】设置 PostgreSQL 数据库的超级用户(postgres)的密码
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
# (可选) 创建一个普通用户
- POSTGRES_USER=${POSTGRES_USER}
# (可选) 创建一个初始数据库
- POSTGRES_DB=${POSTGRES_DB}
# 习惯设置时区,主要是看日志方便
- TZ=Asia/Shanghai
# 设置数据库的默认编码与区域,避免乱码
- LANG=C.UTF-8
# 设置共享内存,内存少或者读写频率低不用开
- POSTGRESQL_SHARED_BUFFERS=256MB
# 数据卷挂载,用于持久化数据
volumes:
# 将主机当前目录下的 postgres-data 文件夹映射到容器内的数据目录
# Bitnami 镜像的数据目录通常是 /bitnami/postgresql
- ./postgres-data:/var/lib/postgresql/data
# 健康检查,可以不用
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
# 创建并使用这个docker网络
networks:
default:
name: my_app_network
注:官方镜像并不强制要求创建初始用户,但如果设置了
POSTGRES_USER变量,启动脚本会创建一个指定名称的新用户,同时,如果POSTGRES_DB未设置,脚本还会创建一个与该用户同名的数据库,并将所有权赋予该用户,这个新用户的密码由POSTGRES_PASSWORD变量的值决定,也就是说和超级用户同一个密码;如果设置了POSTGRES_DB变量,启动脚本会创建一个指定名称的数据库,这个数据库的所有者取决于POSTGRES_USER是否被设置,如果POSTGRES_USER也设置了,则新数据库的所有者是POSTGRES_USER。如果未设置,则新数据库的所有者是超级用户postgres。
.env 文件:
在docker-compose.yml文件同目录下创建.env文件,内容如下:
# PostgreSQL 超级用户'postgres'的密码
POSTGRES_PASSWORD=your_strong_superuser_password
# 要创建的应用程序用户名
POSTGRES_USER=your_strong_user_name
# 要创建的数据库名
POSTGRES_DB=your_database_name
注:=号后面是要自行替换的数据
部署过程:
cd到compose文件夹直接启动即可
cd /opt/compose/postgresql
docker compose up -d
常用指令
我自己是直接用1panel面板连接数据库进行简单管理的,有需要的话可以自行安装PGAdmin之类的可视化管理工具,下面记一些命令行指令吧:
1. 进入容器执行数据库命令
- 命令格式:
docker exec -it [容器名] psql -U [用户名]
- 示例:
容器名叫postgres,用超级用户postgres登录,在服务器的终端输入:
docker exec -it postgres psql -U postgres
成功后会看到终端的提示符变为 postgres=#,这表示已经以 postgres 用户的身份进入了 PostgreSQL 的交互式终端,可以开始输入SQL命令了。
2. 创建用户、密码和数据库
进入 psql 之后,所有的操作都是标准的SQL语句,并且每一句SQL命令都必须以分号 ; 结尾。
- 创建用户 (并指定密码):
CREATE USER my_app_user WITH PASSWORD 'a_password';
这里 my_app_user 是创建的用户名,a_password 是他的密码,记得用单引号包围密码。
- 创建数据库:
CREATE DATABASE my_app_db;
这里 my_app_db 是创建的数据库名。
3. 将数据库指定给用户
可以在创建数据库时直接指定所有者,也可以在创建后将权限授予用户。
- 方法一:创建时指定所有者:
CREATE DATABASE my_app_db WITH OWNER my_app_user;
这会创建一个名为 my_app_db 的数据库,并直接把它的权限交给 my_app_user。
- 方法二:创建后授予权限:
如果数据库已经存在,可以使用GRANT命令来授权
GRANT ALL PRIVILEGES ON DATABASE my_app_db TO my_app_user;
这条命令的意思是将 my_app_db 数据库的所有权限(读、写、执行等)都授予 my_app_user 用户,这是在实际应用中最常用的授权方式。
4. 特殊快捷命令
在 psql 终端里,有一些以反斜杠 \ 开头的特殊快捷命令,它们不是SQL,所以不需要以分号结尾。
- 查询所有数据库:
\l
- 查询所有用户:
\du
- 切换到另一个数据库:
\c my_app_db
- 列出当前数据库里的所有表:
\dt
- 查看某个表的结构(字段、类型等):
\d your_table_name
- 退出 psql 终端:
\q
5. 退出 psql 和容器
- 首先输入
\q然后按回车,退出 psql。 - 然后输入
exit然后按回车,退出容器。
关于
扩展性
现在搭建的是最核心、最基础的PostgreSQL服务,自带的功能包括:
- 极高的可靠性与事务支持 (ACID):确保数据在任何情况下都不会出错,这是数据库的立身之本。
- 丰富的数据类型:除了常规的数字、文本、日期,原生支持
JSON/JSONB(可以直接操作JSON数据)、数组、范围类型等。 - 强大的索引能力:支持多种索引类型(B-Tree, Hash, GiST, GIN...),保证海量数据下的查询性能。
- 全文搜索:内置了非常优秀的全文搜索引擎,可以实现类似
Elasticsearch的基础搜索功能。 - 高并发控制 (MVCC):允许多个用户同时读写数据而不会互相锁定,性能极佳。
以后可以扩展的功能,以下是几个最著名的例子:
-
地理空间数据
- 扩展名:
PostGIS - 作用:这是地理信息系统,安装后数据库就能理解经纬度、点、线、多边形等地理数据,并能进行复杂的空间查询,比如:“找出距离我500米内所有的咖啡馆”、“计算两个城市之间的最短路线”。
- 扩展名:
-
时序数据
- 扩展名:
TimescaleDB - 作用:将PostgreSQL变成一个时序数据库,专门用来处理带有时间戳的数据,如物联网设备的传感器读数、股票价格、系统监控日志等,查询速度和存储效率远超普通数据表。
- 扩展名:
-
向量数据库
- 扩展名:
pg_vector - 作用:这是AI领域常见扩展之一,它让数据库能存储和查询“向量”,可以进行相似度搜索,比如:“根据这张猫的图片,找出我图库里所有长得像它的图片”、“根据这段文本的含义,找出最相关的文章”。
- 扩展名:
-
定时任务调度器
- 扩展名:
pg_cron - 作用:可以在数据库内部创建类似Linux
cron的定时任务,比如“每天凌晨2点自动清理一次过期数据”。
- 扩展名:
如何实现扩展
通常需要两步:
-
安装扩展:这一步是在数据库软件层面。最简单的方法是使用已经预装了这些扩展的专用Docker镜像。例如,TimescaleDB和PostGIS都有自己的官方Docker镜像 (
timescale/timescaledb和postgis/postgis),它们在官方PostgreSQL的基础上,已经帮您把扩展安装好了。 -
在数据库中启用:进入数据库后,只需执行一句SQL命令,就能为某个特定的数据库开启这个功能。例如:
CREATE EXTENSION postgis;