收到来自 docker 的错误 - 构成用户必须拥有数据目录
Receiving an error from a docker-compose that the user must own the data directory
每次尝试构建映像时,都会收到以下错误:
服务器必须由拥有数据目录的用户启动。
以下是我的docker文件:
version: "3.7"
services:
db:
image: postgres
container_name: xxxxxxxxxxxx
volumes:
- ./postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: $POSTGRES_DB
POSTGRES_USER: $POSTGRES_USER
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
nginx:
image: nginx:latest
restart: always
container_name: xxxxxxxxxxxx-nginx
volumes:
- ./deployment/nginx:/etc/nginx
logging:
driver: none
depends_on: ["radio"]
ports:
- 8080:80
- 8081:443
radio:
build:
context: .
dockerfile: "./deployment/Dockerfile"
image: test-radio
command: './manage.py runserver 0:3000'
container_name: xxxxxxxxxxxxxxx
restart: always
depends_on: ["db"]
volumes:
- type: bind
source: ./api
target: /app/api
- type: bind
source: ./xxxxxx
target: /app/xxxxx
environment:
POSTGRES_DB: $POSTGRES_DB
POSTGRES_USER: $POSTGRES_USER
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
POSTGRES_HOST: $POSTGRES_HOST
AWS_KEY_ID: $AWS_KEY_ID
AWS_ACCESS_KEY: $AWS_ACCESS_KEY
AWS_S3_BUCKET_NAME: $AWS_S3_BUCKET_NAME
networks:
default:
图像是使用以下 run.sh 文件构建的:
#!/usr/bin/env sh
if [ ! -f .pass ]; then
openssl rand -base64 32 > .pass
fi
#export POSTGRES_DB="xxxxxxxxxxxxxxxxx"
#export POSTGRES_USER="xxxxxxxxxxxxxx"
#export POSTGRES_PASSWORD="xxxxxxxxxxxxxxxxxxxx"
#export POSTGRES_HOST="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export POSTGRES_DB="xxxxxxxxxxxxxxxxxx"
export POSTGRES_USER="xxxxxxxxxxxxxxxxxxxx"
export POSTGRES_PASSWORD="`cat .pass`"
export POSTGRES_HOST="db"
export AWS_KEY_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export AWS_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxx"
export AWS_S3_BUCKET_NAME=""
echo "Your psql password is in .pass do not commit this file."
echo "The app will be available on localhost:8080 shortly"
if [ -z "" ]; then
docker-compose up
else
docker-compose up
fi
我想知道我的错误是否是由于尝试使用 bash 脚本在 Windows 机器上部署服务引起的?
问题详情
鉴于规范
,OP 观察到的行为肯定来自 UID/GID 不匹配
volumes:
- ./postgres-data:/var/lib/postgresql/data
(可以看作 docker-compose 等同于 docker run -v "$PWD/postgres-data:/var/lib/postgresql/data" …
) bind-mounts 容器内的 $PWD/postgres-data
文件夹,可以按原样访问其文件(包括 owner/group 元数据)。
此外,请注意主机和容器之间 owner/group 元数据的处理 仅依赖于数字 UID 和 GID,而不依赖于所有者和组名。
有关 Docker 上下文中的 UID 和 GID 的更多信息,另请参阅 Medium 上的 that article。
绑定安装是必需的解决方法
为了完整起见,Whosebug 上的这个答案描述了几种解决绑定挂载 UID 不匹配问题的可能解决方案(包括最直接的解决方案,即更改文件的 UID :):
其他解决方案
跟随,你可能想使用命名卷,主要在于使用:
- docker volume 命令
- and/or
docker run
option -v …:…
.
备注:
docker run -v PATH1:PATH2 …
当且仅当 PATH1
是绝对的(即以/
)(例如,-v "$PWD:$PWD"
是一个常见的成语)
docker run -v NAME:PATH2 …
当且仅当 NAME
不包含任何 /
(即匹配正则表达式 [a-zA-Z0-9][a-zA-Z0-9_.-]
).
- 即使我们事先没有手动 运行
docker volume create foo
,如果需要,docker run -v foo:/data --rm -it debian
也会创建命名卷 foo
。
为了填充命名卷的文件(或分别备份它们),您可以使用图像 debian
、ubuntu
左右的临时容器,结合同时绑定挂载和卷挂载:
Add a file /home/user/bar.txt
in a new volume foo
file1=/home/user/bar.txt # initial file
uid=2000 # target User-ID in the volume
gid=2000 # target Group-ID in the volume
docker pull debian
docker run -v "$file1:$file1:ro" -v foo:/data \
-e file1="$file1" -e uid="$uid" -e gid="$gid" \
--rm -it debian bash -exc \
'cp -v -- "$file1" /data/bar.txt && chown -v $uid:$gid /data/bar.txt'
docker volume ls
Backup the foo
volume in a tarball
date=$(date +'%Y%m%d_%H%M%S')
back="backup_$date.tar.gz"
destdir=/home/user/backup
mkdir -p "$destdir"
docker run -v foo:/data -v "$destdir:/backup" -e back="$back" \
--rm -it debian bash -exc 'tar cvzf "/backup/$back" /data'
每次尝试构建映像时,都会收到以下错误:
服务器必须由拥有数据目录的用户启动。
以下是我的docker文件:
version: "3.7"
services:
db:
image: postgres
container_name: xxxxxxxxxxxx
volumes:
- ./postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: $POSTGRES_DB
POSTGRES_USER: $POSTGRES_USER
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
nginx:
image: nginx:latest
restart: always
container_name: xxxxxxxxxxxx-nginx
volumes:
- ./deployment/nginx:/etc/nginx
logging:
driver: none
depends_on: ["radio"]
ports:
- 8080:80
- 8081:443
radio:
build:
context: .
dockerfile: "./deployment/Dockerfile"
image: test-radio
command: './manage.py runserver 0:3000'
container_name: xxxxxxxxxxxxxxx
restart: always
depends_on: ["db"]
volumes:
- type: bind
source: ./api
target: /app/api
- type: bind
source: ./xxxxxx
target: /app/xxxxx
environment:
POSTGRES_DB: $POSTGRES_DB
POSTGRES_USER: $POSTGRES_USER
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
POSTGRES_HOST: $POSTGRES_HOST
AWS_KEY_ID: $AWS_KEY_ID
AWS_ACCESS_KEY: $AWS_ACCESS_KEY
AWS_S3_BUCKET_NAME: $AWS_S3_BUCKET_NAME
networks:
default:
图像是使用以下 run.sh 文件构建的:
#!/usr/bin/env sh
if [ ! -f .pass ]; then
openssl rand -base64 32 > .pass
fi
#export POSTGRES_DB="xxxxxxxxxxxxxxxxx"
#export POSTGRES_USER="xxxxxxxxxxxxxx"
#export POSTGRES_PASSWORD="xxxxxxxxxxxxxxxxxxxx"
#export POSTGRES_HOST="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export POSTGRES_DB="xxxxxxxxxxxxxxxxxx"
export POSTGRES_USER="xxxxxxxxxxxxxxxxxxxx"
export POSTGRES_PASSWORD="`cat .pass`"
export POSTGRES_HOST="db"
export AWS_KEY_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export AWS_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxx"
export AWS_S3_BUCKET_NAME=""
echo "Your psql password is in .pass do not commit this file."
echo "The app will be available on localhost:8080 shortly"
if [ -z "" ]; then
docker-compose up
else
docker-compose up
fi
我想知道我的错误是否是由于尝试使用 bash 脚本在 Windows 机器上部署服务引起的?
问题详情
鉴于规范
,OP 观察到的行为肯定来自 UID/GID 不匹配volumes:
- ./postgres-data:/var/lib/postgresql/data
(可以看作 docker-compose 等同于 docker run -v "$PWD/postgres-data:/var/lib/postgresql/data" …
) bind-mounts 容器内的 $PWD/postgres-data
文件夹,可以按原样访问其文件(包括 owner/group 元数据)。
此外,请注意主机和容器之间 owner/group 元数据的处理 仅依赖于数字 UID 和 GID,而不依赖于所有者和组名。
有关 Docker 上下文中的 UID 和 GID 的更多信息,另请参阅 Medium 上的 that article。
绑定安装是必需的解决方法
为了完整起见,Whosebug 上的这个答案描述了几种解决绑定挂载 UID 不匹配问题的可能解决方案(包括最直接的解决方案,即更改文件的 UID :):
其他解决方案
跟随
- docker volume 命令
- and/or
docker run
option-v …:…
.
备注:
docker run -v PATH1:PATH2 …
当且仅当PATH1
是绝对的(即以/
)(例如,-v "$PWD:$PWD"
是一个常见的成语)docker run -v NAME:PATH2 …
当且仅当NAME
不包含任何/
(即匹配正则表达式[a-zA-Z0-9][a-zA-Z0-9_.-]
).- 即使我们事先没有手动 运行
docker volume create foo
,如果需要,docker run -v foo:/data --rm -it debian
也会创建命名卷foo
。 为了填充命名卷的文件(或分别备份它们),您可以使用图像
debian
、ubuntu
左右的临时容器,结合同时绑定挂载和卷挂载:Add a file
/home/user/bar.txt
in a new volumefoo
file1=/home/user/bar.txt # initial file uid=2000 # target User-ID in the volume gid=2000 # target Group-ID in the volume docker pull debian docker run -v "$file1:$file1:ro" -v foo:/data \ -e file1="$file1" -e uid="$uid" -e gid="$gid" \ --rm -it debian bash -exc \ 'cp -v -- "$file1" /data/bar.txt && chown -v $uid:$gid /data/bar.txt' docker volume ls
Backup the
foo
volume in a tarballdate=$(date +'%Y%m%d_%H%M%S') back="backup_$date.tar.gz" destdir=/home/user/backup mkdir -p "$destdir" docker run -v foo:/data -v "$destdir:/backup" -e back="$back" \ --rm -it debian bash -exc 'tar cvzf "/backup/$back" /data'