Docker Postgres
需求
在搭建wiki时,按照网上教程使用docker搭建wiki.js,同时使用docker搭建mysql做数据存储。
浏览官网时,注意到wiki.js的后续升级,不再支持mysql等数据库,仅支持postgres数据库。
为了便于后续升级,避免数据在不同数据库间转移(目前我能想到的就是直接将帖子的重要内容拷贝下来粘贴到新的wiki页面上),需要将mysql替换成postgres(即数据库PostgreSQL)。
环境
系统:Docker Container (Ubuntu 22.04.4)
前提
1、了解Linux命令、文件权限、文件组织结构。
2、了解docker基本命令,掌握创建、进入、删除容器的操作和数据卷的挂载。
步骤
(个人并没有使用docker compose工具管理配置)
(按照个人习惯,一般先使用docker建立测试的应用容器,检查使用到的端口和应用数据文件,然后规划好映射到主机的端口和待挂载的数据卷,拷贝需要的文件到主机,最后建立持续运行的容器)
安装postgres
获取最新的镜像文件:
docker pull postgres
运行测试:
docker run -e POSTGRES_PASSWORD=password --name postgres --restart always -d postgres
端口规划:192.168.1.111:7000:5432
挂载卷规划:(同时拷贝容器内的文件到主机目录中)
/mnt/.../localtime/Shanghai:/etc/localtime
/mnt/.../postgresql/data:/var/lib/postgresql/data
/mnt/.../conf/postgresql:/etc/postgresql
/mnt/.../conf/postgresql-common:/etc/postgresql-common
/mnt/.../init.d/postgresql:/etc/init.d/postgresql
安装:(删除原来安装用于测试的容器)
(换行后的完整指令参考)
docker run \
-p 192.168.1.111:7000:5432 \
-e POSTGRES_PASSWORD=password \
-v /mnt/.../localtime/Shanghai:/etc/localtime \
-v /mnt/.../postgresql/data:/var/lib/postgresql/data \
-v /mnt/.../conf/postgresql:/etc/postgresql \
-v /mnt/.../conf/postgresql-common:/etc/postgresql-common \
-v /mnt/.../init.d/postgresql:/etc/init.d/postgresql \
--name postgresql_wiki \
--restart=always \
-d postgre
(不换行的完整指令参考)
docker run -p 192.168.1.111:7000:5432 -e POSTGRES_PASSWORD=password -v /mnt/…/localtime/Shanghai:/etc/localtime -v /mnt/…/postgresql/data:/var/lib/postgresql/data -v /mnt/…/conf/postgresql:/etc/postgresql -v /mnt/…/conf/postgresql-common:/etc/postgresql-common -v /mnt/…/init.d/postgresql:/etc/init.d/postgresql --name postgresql_wiki --restart=always -d postgres
创建数据库
1、进入容器内部(命令自行到网上查询)
2、登录并创建数据库
//登录数据库
psql -Upostgres
//创建数据库postgres_wiki
CREATE DATABASE postgres_wiki;
3、查看已经存在的数据库 \l
4、退出数据库 \q
5、退出容器 exit
安装wiki.js
步骤与安装postgres类似,这里直接提供最终指令
(换行后的完整指令参考)
docker run \
-p 192.168.1.111:7001:3443 \
-p 192.168.1.111:7002:3000 \
-e "DB_TYPE=postgres" \
-e "DB_HOST=192.168.1.111" \
-e "DB_PORT=7000" \
-e "DB_USER=postgres" \
-e "DB_PASS=password" \
-e "DB_NAME=postgres_wiki" \
-v /mnt/.../localtime/Shanghai:/etc/localtime \
-v /mnt/.../wiki:/wiki \
--name wiki \
--restart=always \
-d requarks/wiki
(不换行的完整指令参考)
docker run -p 192.168.1.111:7001:3443 -p 192.168.1.111:7002:3000 -e "DB_TYPE=postgres" -e "DB_HOST=192.168.1.111" -e "DB_PORT=7000" -e "DB_USER=postgres" -e "DB_PASS=password" \-e "DB_NAME=postgres_wiki" -v /mnt/…/localtime/Shanghai:/etc/localtime -v /mnt/…/wiki:/wiki --name wiki --restart=always -d requarks/wiki
经验总结
postgres的账号密码
使用docker安装时设置了密码,但进入容器登录并没有用到密码 ,与mysql不同的是,postgres是不存在root账号的,它默认使用名为“postgres”的账号。
使用指令alter role postgres with password '
设置密码后重新登录数据库,系统也没有提示我需要输入密码。password
';
(这个问题,后续没有继续研究)
错误的挂载卷
开始安装时,使用-v /mnt/.../postgresql:/var/lib/postgresql
,按照自己的对数据卷的理解,容器内的“/var/lib/postgresql
”目录所有内容直接被替换成了主机目录下的“/mnt/.../postgresql
”的内容。
但是删除测试容器,重新建立容器时发现以下现象:
1、利用现有数据重新建立容器,不指定POSTGRES_PASSWORD密码,docker容器运行异常。
2、删除原有容器,利用现有数据重新建立容器后,进入数据库查看,发现建立的数据库消失了。
3、在第2点上重新测试,建立容器后,重启容器(非删除重建),创建的数据库并没有消失。
对于第一点,开始我并未在意,因为我下次创建容器指定POSTGRES_PASSWORD参数即可,并不影响服务的使用。
但是第2点却意味着,如果我正式使用该服务,当我试图重建容器,数据会消失,无法保存。这让我不禁思考,是否我挂载数据卷错误,或者没有保存数据库到主机?
而第3点却说明,我已经保存数据库到了主机,不然按照docker的原理,重启容器,数据会丢失。(纠正:容器不是沙箱,docker重启容器并不会丢失数据,数据卷挂载目的是数据持久化,避免删除容器后丢失数据)
我使用inspect命令查看容器,发现了问题所在。容器的配置详情如下:
![](https://net.iloves.top/wp-content/uploads/2024/04/image-1024x792.png)
在Mounts详情中,有一个使用了系统命名的数据卷(第一个红框)。说明它是系统自动挂载的,并非按照我指定的路径挂载。
同样的在Volume详情中,它也明确指出了需要挂载的目标路径为“/var/lib/postgresql/data”,而我却试图用一个更大范围的路径“/var/lib/postgresql”去包含它,所以系统就自动创建一个数据卷并挂载到容器上。
这就能解释第2点为何重建容器后原建的数据库不存在了,每次重建容器,系统就自动挂载了一个新的数据卷,自然数据就看不到了(实际上还存在主机的docker目录上)。
因此创建数据卷前还需要使用“inspect”命令查清楚需要挂载的卷,将一切数据掌握在自己手中。
数据卷清理
在“错误的挂载卷”章节意外发现默认挂载卷的存在,让我想起诸多容器测试验证时,均用到了默认挂载的方式。这意味着,现在有许多未使用的数据卷作为垃圾占据着主机的存储空间,这是之前一直未想到的。
列出挂载卷
docker volume ls
清除无主数据卷
docker volume prune
也可以进入/var/lib/docker/volumes
目录查看创建的默认数据卷,但不推荐使用rm命令删除,避免误删。
当你尝试进入/var/lib/docker/volumes
目录,是否会遇到sudo cd
的操作呢,这就要用到sudo -i提升用户权限(或者使用sudo -s打开特殊shell)。