Docker 容器定义用户主文件夹

Docker Container Define user home folder

我在 docker-compse.yml

中有以下 php 服务
version: '3'

networks:
  laravel:
    driver: bridge

services:
  nginx:
    image: nginx:stable-alpine
    restart: unless-stopped
    ports:
      - "${WEB_PORT}:80"
    volumes:
      - "${PROJECT_DIR}:/var/www/html"
      - "${NGINX_CONFIG}:/etc/nginx/conf.d/default.conf"
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - php
      - mysql
    networks:
      - laravel

  mysql:
    image: mysql:5.7.29
    restart: unless-stopped
    user: "${HOST_UID}:${HOST_GID}"
    tty: true
    ports:
      - "${SQL_PORT}:3306"
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./docker/mysql:/var/lib/mysql
    networks:
      - laravel

  php:
    build:
      context: ./docker
      dockerfile: Dockerfile-php
    user: "${HOST_UID}:${HOST_GID}"
    volumes:
      - "${PROJECT_DIR}:/var/www/html"
      - ./docker/php/php.ini:/usr/local/etc/php/php.ini
      #- "${COMPOSER_CACHE_DIR}:/.composer/cache"
      #- "${COMPOSER_CONFIG}:/.composer/config"
    working_dir: /var/www/html
    networks:
      - laravel

  npm:
    image: node:13.7
    user: "${HOST_UID}:${HOST_GID}"
    volumes:
      - "${PROJECT_DIR}:/var/www/html"
    working_dir: /var/www/html
    entrypoint: ['npm']

当我运行whoami在容器中时,它returns:

whoami: cannot find name for user ID 1000

我认为这是一个问题,因为没有主目录,docker-compose exec php ls ~ returns:

ls: cannot access '/home/clarg': No such file or directory

这会导致 docker-compose exec php php artisan tinker 返回:

   ErrorException 

  Writing to directory /.config/psysh is not allowed.

  at vendor/psy/psysh/src/ConfigPaths.php:362
    358▕             @\mkdir($dir, 0700, true);
    359▕         }
    360▕ 
    361▕         if (!\is_dir($dir) || !\is_writable($dir)) {
  ➜ 362▕             \trigger_error(\sprintf('Writing to directory %s is not allowed.', $dir), \E_USER_NOTICE);
    363▕ 
    364▕             return false;
    365▕         }
    366▕ 

      +20 vendor frames 
  21  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

通过谷歌搜索,我看到这是在主目录中,容器中不存在。

我该如何解决这个问题?

编辑:

Dockerfile-php:

FROM php:8.0-fpm

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions gd zip pdo_mysql

# check https://github.com/mlocati/docker-php-extension-installer#supported-php-extensions for more extensions

COPY --from=composer /usr/bin/composer /usr/bin/composer

php.ini https://pastebin.com/T2iYTZz2

您的 docker 容器对主机上可能存在或不存在的用户一无所知,因此除非您将这些用户与它们的随附配置和目录结构一起构建,否则唯一的事情就是你不再喂养 docker 你的本地 UID 和 GID 是“运行 容器作为 root 以外的东西”,这很好。

但通常您不想将 docker container/image 绑定到启动它的特定环境,例如:要求与本地用户同名的用户存在于其中容器及其所有相关目录等。

在这种特定情况下,看起来 artisan 只是想缓存一些配置,您可以通过环境变量控制它的位置:

XDG_CONFIG_HOME=/some/writeable/directory

您可以在项目的 Dockerfile、docker-compose 或 .env 文件中设置。我建议将它设置到项目目录中的某处,但在 docroot 之外。

参考:

这对于您想挂载到本地工作目录进行测试的本地开发人员来说已经足够了,但是如果您要 build/deploy 最后 docker 图片。