收到来自 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 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
  • 为了填充命名卷的文件(或分别备份它们),您可以使用图像 debianubuntu 左右的临时容器,结合同时绑定挂载和卷挂载:

    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'