如何管理挂载到docker容器中的卷的权限?

toiithl6  于 2023-05-28  发布在  Docker
关注(0)|答案(2)|浏览(202)

我正在开发一个WordPress主题,并希望在我的开发设置中使用Docker。我做的很简单:

  • 创建运行MySQL 5.7的database服务
  • 创建一个wordpress服务,我将主题文件夹作为卷挂载到/var/www/html/wp-content/themes

然而,我正在努力处理卷权限。
我正在使用以下项目文件夹结构:

.
├── docker-compose.yml
└── my-theme

我的**docker-compose.yml**文件如下:

version: '3.2'

services:
  database:
    image: mysql:5.7
    volumes:
      - my_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: root

  wordpress:
    depends_on:
      - database
    image: wordpress:php7.3-apache
    ports:
      - '8000:80'
    restart: always
    environment:
      WORDPRESS_DB_HOST: database:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: root
    working_dir: /var/www/html
    volumes:
      - type: volume
        source: ./my-theme
        target: /var/www/html/wp-content/themes/my-theme
volumes:
  my_data: {}

当我运行docker-compose up时,一切都按预期工作:容器被创建,我可以在浏览器中访问WordPress。然而,我作为卷挂载的主题在激活时不会渲染任何东西。
当我将sh放入wordpress容器(docker-compose exec wordpress sh)时,我可以看到wp-content/themes文件夹是root所有的。所以我想这就是问题所在。
我通过手动和递归地chown在容器中的wp-content文件夹中验证了这是一个权限问题:

chown -R www-data:www-data /var/www/html/wp-content

一旦完成,我的主题就像预期的那样呈现了。所以现在我正在寻找一种方法来避免这个chown过程(这个想法是任何其他开发人员都可以克隆这个项目,只需运行docker-compose up并开始工作)。
我尝试的第一件事是制作一个Dockerfile,在那里我将构建一个稍微定制的Wordpress图像:

FROM wordpress:php7.3-apache
RUN mkdir -p /var/www/html/wp-content/themes/test-theme \
  && chown -R /var/www/html/wp-content

我的理由是,通过创建目录并预先执行chown操作,卷将继承用户:组Map。唉,没有这样的事;挂载卷将覆盖此Map并将其设置回root:root
之后,我尝试在docker-compose.yml文件中设置APACHE_RUN_USERAPACHE_RUN_GROUP环境变量:

version: '3.2'

services:
  database:
    ...

  wordpress:
    ...
    environment:
      WORDPRESS_DB_HOST: database:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: root
      APACHE_RUN_USER: '$(id -u)'
      APACHE_RUN_GROUP: '$(id -g)'
    working_dir: /var/www/html
    volumes:
      - type: volume
        source: ./my-theme
        target: /var/www/html/wp-content/themes/my-theme
volumes:
  my_data: {}

然而,这在构建时抛出了一堆Apache错误。
我现在有点不知所措了在Docker中管理挂载卷的权限有什么最佳实践吗?我在谷歌上搜索了很多,但我找到的解决方案有点超出了我的理解范围。

qq24tv8q

qq24tv8q1#

您可以通过覆盖wordpress图像的入口点来实现这一点。
在项目中创建一个文件startup.sh,make是可执行的:

#!/bin/bash

chown -R www-data:www-data /var/www/html/wp-content
docker-entrypoint.sh apache2-foreground

然后在你的docker-compose.yml中:

...
  wordpress:
...
    working_dir: /var/www/html
    volumes:
        - './my-theme:/var/www/html/wp-content/themes/my-theme'
        - './startup.sh:/startup.sh'
    entrypoint: /startup.sh

这对我来说很有效,如果你在实施过程中遇到问题,请告诉我。

kcwpcxri

kcwpcxri2#

向ChatGPT询问了问题,它解决了问题)

FROM php:8.0-apache

# Create a www-data user with the same UID and GID as the host user
ARG WWW_DATA_UID=1000
ARG WWW_DATA_GID=1000
RUN usermod -u $WWW_DATA_UID www-data && groupmod -g $WWW_DATA_GID www-data

# Rest of the Dockerfile...

通过将容器内www-data用户的UID和GID设置为与主机相同的值,挂载的文件和目录的所有权现在应该正确反映www-data用户。

version: "3.9"

services:
    wordpress:
        build:
            context: .
        ports:
            - 80:80
        volumes:
            - ./src:/var/www/html:rw
        user: www-data

相关问题