Skip to content

Commit 404c77e

Browse files
committed
fix: 添加数据目录权限修复逻辑,更新 README.md 以说明挂载权限问题及解决方案
1 parent a413aec commit 404c77e

2 files changed

Lines changed: 71 additions & 15 deletions

File tree

‎Dockerfile‎

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
1515
wget \
1616
sudo \
1717
systemd \
18+
gosu \
1819
&& rm -rf /var/lib/apt/lists/*
1920

2021
# 安装 Pig 包管理器
@@ -130,11 +131,24 @@ if [ -z "$POSTGRES_DB" ]; then\n\
130131
fi\n\
131132
\n\
132133
# ===========================================\n\
134+
# 修复数据目录权限(用于挂载场景)\n\
135+
# ===========================================\n\
136+
# 如果目录存在但不是 postgres 用户所有,修复权限\n\
137+
if [ -d "$PGDATA" ]; then\n\
138+
current_owner=$(stat -c "%u:%g" "$PGDATA" 2>/dev/null || echo "0:0")\n\
139+
if [ "$current_owner" != "999:999" ]; then\n\
140+
echo "=== 修复数据目录权限: $current_owner -> 999:999 ==="\n\
141+
chown -R 999:999 "$PGDATA"\n\
142+
echo "=== 权限修复完成 ==="\n\
143+
fi\n\
144+
fi\n\
145+
\n\
146+
# ===========================================\n\
133147
# 数据库初始化(仅在首次启动时执行)\n\
134148
# ===========================================\n\
135149
if [ ! -s "$PGDATA/PG_VERSION" ]; then\n\
136150
echo "=== 初始化 PostgreSQL 数据库 ==="\n\
137-
/usr/pgsql/bin/initdb\n\
151+
gosu postgres /usr/pgsql/bin/initdb\n\
138152
\n\
139153
echo "=== 配置 PostgreSQL 参数 ==="\n\
140154
# 配置网络访问\n\
@@ -146,29 +160,29 @@ if [ ! -s "$PGDATA/PG_VERSION" ]; then\n\
146160
\n\
147161
echo "=== 启动 PostgreSQL 进行初始化 ==="\n\
148162
# 启动 PostgreSQL 进行初始化\n\
149-
/usr/pgsql/bin/postgres &\n\
163+
gosu postgres /usr/pgsql/bin/postgres &\n\
150164
sleep 5\n\
151165
\n\
152166
echo "=== 创建用户和数据库 ==="\n\
153167
# 如果用户不是默认的 postgres,创建新用户\n\
154168
if [ "$POSTGRES_USER" != "postgres" ]; then\n\
155-
/usr/pgsql/bin/psql -c "CREATE USER $POSTGRES_USER WITH SUPERUSER PASSWORD '\''$POSTGRES_PASSWORD'\'';"\n\
169+
gosu postgres /usr/pgsql/bin/psql -c "CREATE USER $POSTGRES_USER WITH SUPERUSER PASSWORD '\''$POSTGRES_PASSWORD'\'';"\n\
156170
else\n\
157-
/usr/pgsql/bin/psql -c "ALTER USER postgres PASSWORD '\''$POSTGRES_PASSWORD'\'';"\n\
171+
gosu postgres /usr/pgsql/bin/psql -c "ALTER USER postgres PASSWORD '\''$POSTGRES_PASSWORD'\'';"\n\
158172
fi\n\
159173
\n\
160174
# 创建指定的数据库\n\
161175
if [ "$POSTGRES_DB" != "postgres" ]; then\n\
162-
/usr/pgsql/bin/createdb -U postgres -O $POSTGRES_USER "$POSTGRES_DB"\n\
176+
gosu postgres /usr/pgsql/bin/createdb -U postgres -O $POSTGRES_USER "$POSTGRES_DB"\n\
163177
fi\n\
164178
\n\
165179
echo "=== 执行扩展初始化脚本 ==="\n\
166180
# 执行初始化脚本\n\
167181
for f in /docker-entrypoint-initdb.d/*; do\n\
168182
case "$f" in\n\
169183
*.sh) echo "$0: running $f"; . "$f" ;;\n\
170-
*.sql) echo "$0: running $f"; /usr/pgsql/bin/psql -U postgres -d "$POSTGRES_DB" -f "$f" ;;\n\
171-
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | /usr/pgsql/bin/psql -U postgres -d "$POSTGRES_DB" ;;\n\
184+
*.sql) echo "$0: running $f"; gosu postgres /usr/pgsql/bin/psql -U postgres -d "$POSTGRES_DB" -f "$f" ;;\n\
185+
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | gosu postgres /usr/pgsql/bin/psql -U postgres -d "$POSTGRES_DB" ;;\n\
172186
*) echo "$0: ignoring $f" ;;\n\
173187
esac\n\
174188
done\n\
@@ -179,14 +193,13 @@ if [ ! -s "$PGDATA/PG_VERSION" ]; then\n\
179193
fi\n\
180194
\n\
181195
echo "=== 启动 PostgreSQL 服务 ==="\n\
182-
# 启动 PostgreSQL\n\
183-
exec /usr/pgsql/bin/postgres\n\
196+
# 启动 PostgreSQL(以 postgres 用户身份)\n\
197+
exec gosu postgres /usr/pgsql/bin/postgres\n\
184198
' > /usr/local/bin/docker-entrypoint.sh && chmod +x /usr/local/bin/docker-entrypoint.sh
185199

186-
# 不需要安装额外的包,直接使用系统自带的 su 命令
187-
188-
# 切换回postgres用户
189-
USER postgres
190-
200+
# ===========================================
191201
# 设置启动命令
202+
# ===========================================
203+
# 注意:容器以 root 用户运行,启动脚本使用 gosu 切换到 postgres 用户
204+
# 这样可以修复挂载目录的权限问题
192205
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]

‎README.md‎

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,50 @@ SET pg_trgm.similarity_threshold = 0.3;
503503

504504
### 常见问题
505505

506-
1. **扩展安装失败**
506+
#### 1. 挂载数据目录权限错误
507+
508+
当使用 `-v` 参数挂载宿主机目录时,可能会遇到权限错误:
509+
510+
```
511+
initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
512+
```
513+
514+
**原因**: 容器内的 `postgres` 用户(UID 999)没有权限修改挂载的宿主机目录。
515+
516+
**解决方案**: 本镜像已内置权限修复逻辑,会在启动时自动修复挂载目录的权限。但如果仍遇到问题,可以尝试以下方法:
517+
518+
```bash
519+
# 方法 1:以 root 权限运行容器(推荐用于本地开发)
520+
docker run -d \
521+
--name postgres-zh \
522+
-v /path/to/your/data:/var/lib/postgresql/data \
523+
-e POSTGRES_PASSWORD=your_password \
524+
-p 5432:5432 \
525+
eyeix/postgres-zh:v17
526+
527+
# 方法 2:手动修改宿主机目录权限(推荐用于生产环境)
528+
sudo chown -R 999:999 /path/to/your/data
529+
```
530+
531+
**使用命名卷(推荐)**: 使用 Docker 命名卷可以避免权限问题,Docker 会自动处理权限:
532+
533+
```yaml
534+
# docker-compose.yml
535+
services:
536+
postgres:
537+
image: eyeix/postgres-zh:v17
538+
volumes:
539+
- postgres_data:/var/lib/postgresql/data # 使用命名卷
540+
environment:
541+
POSTGRES_PASSWORD: your_password
542+
ports:
543+
- "5432:5432"
544+
545+
volumes:
546+
postgres_data:
547+
```
548+
549+
#### 2. 扩展安装失败
507550
508551
```bash
509552
# 检查扩展是否正确安装

0 commit comments

Comments
 (0)