在Ubuntu上搞PostgreSQL,差不多就三条路:Docker拉镜像跑、apt直接装、自己下源码编译。选哪种主要看场景——想快速起一套测试环境,Docker最省心;开发机或者临时用一下,apt两下搞定;生产环境或者需要定制版本,再考虑源码编译。
下面挨个过一遍,命令都是实测能跑的。
Docker 方式
适合要隔离环境、方便迁移,或者不想在宿主机上装一堆依赖的情况。
先把Docker装了,这一步网上教程很多,这里直接贴命令:
sudo apt update && sudo apt upgrade -y
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io -y
sudo systemctl start docker
sudo systemctl enable docker
然后拉镜像,不用指定版本的话直接 latest:
docker pull postgres:latest
数据肯定要持久化,先在宿主机上建个目录:
mkdir -p /home/postgres/data
chmod 777 -R /home/postgres/data
注意,chmod 777 是图省事,开发环境凑合用,生产环境别这么搞,后面会再说。
启动容器,把端口、用户、密码、库名和挂载目录都带上:
docker run -d \--name postgres \-e POSTGRES_USER=myuser \-e POSTGRES_PASSWORD=mypassword \-e POSTGRES_DB=mydatabase \-p 5432:5432 \-v /home/postgres/data:/var/lib/postgresql/data \postgres:latest
-d后台跑--name容器名字-e那几个环境变量就是初始化用的-p宿主机端口:容器端口-v数据目录挂载
跑完 docker ps -a 看一眼状态,没起来就 docker logs postgres 查日志。
apt 直接装
最简单的方式,适合本地开发或者快速验证。
sudo apt update
sudo apt install postgresql
装完服务就自动起来了,sudo systemctl status postgresql 确认一下。
切换到 postgres 用户进 psql:
sudo -i -u postgres
psql
在里面建库建用户:
CREATE DATABASE mydb;
CREATE USER myuser WITH PASSWORD 'mypassword';
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;
到这里就能用了。这种方式默认配置都在系统默认路径下,不太适合需要调一大堆参数的生产场景,但跑个测试绰绰有余。
源码编译安装
需要特定版本,或者想自己控制安装路径、编译参数的时候走这条路。我一般给生产环境部署的机器,会倾向于源码编译,因为包管理器里的版本有时候滞后。
先装编译依赖:
sudo apt update && sudo apt upgrade -y
sudo apt install build-essential libreadline-dev zlib1g-dev bison flex libpq-dev libicu-dev make
下载源码包,这里以 16.2 为例:
mkdir -p /opt/pgsql
cd /opt/pgsql
wget https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.gz
tar -zxvf postgresql-16.2.tar.gz -C /opt/pgsql/
configure 指定安装路径,然后 make:
cd /opt/pgsql/postgresql-16.2
./configure --prefix=/opt/pgsql/pgsql-16.2
make && sudo make install
创建 postgres 用户和组,初始化数据目录:
sudo groupadd postgres
sudo useradd -g postgres postgres
sudo mkdir -p /opt/pgsql/pgsql-16.2/data
sudo chown postgres:postgres /opt/pgsql/pgsql-16.2/data
sudo -u postgres /opt/pgsql/pgsql-16.2/bin/initdb -D /opt/pgsql/pgsql-16.2/data
配 systemd 服务,这样开机自启、用 systemctl 管理比较方便:
sudo vim /etc/systemd/system/postgresql.service
内容:
[Unit]
Description=PostgreSQL RDBMS
After=network.target[Service]
Type=forking
User=postgres
Group=postgres
ExecStart=/opt/pgsql/pgsql-16.2/bin/pg_ctl start -D /opt/pgsql/pgsql-16.2/data -s -o "-p 5432"
ExecStop=/opt/pgsql/pgsql-16.2/bin/pg_ctl stop -D /opt/pgsql/pgsql-16.2/data -s -m fast
ExecReload=/opt/pgsql/pgsql-16.2/bin/pg_ctl reload -D /opt/pgsql/pgsql-16.2/data -s[Install]
WantedBy=multi-user.target
然后启动:
sudo systemctl daemon-reload
sudo systemctl enable postgresql
sudo systemctl start postgresql
常见问题
端口冲突——换个映射端口就行,比如 -p 5433:5432,连的时候记得改端口号。
权限问题——很多人一开始图方便直接 chmod 777,开发机无所谓,生产环境最好把数据目录的所有者改成容器里 postgres 用户对应的 uid(一般是999),或者源码编译时用 postgres 用户初始化。
连不上数据库——先确认容器或者服务是不是跑着的,再看看 pg 日志,最后查防火墙有没有放行对应端口。
生产环境额外提几句
别用 chmod 777,已经说过了,权限收敛一下,目录 owner 设对。
备份定期做,pg_dump 配合 cron 或者专门的备份工具,别等数据丢了再拍大腿。
监控和日志,Docker 环境可以直接 docker logs 接出来,或者上 Prometheus + Grafana 那套;源码或 apt 装的去看 pg 的日志目录,配上合适的日志级别,不然出了问题半天找不到线索。
