为什么 Mac OSX 在为 Mac 使用 Docker 桌面时仍然表现出不区分大小写

Why does Mac OSX still exhibit case insensitivity when using Docker Desktop for Mac

我正在使用 Docker Desktop for Mac 在本地环境中容器化基本 LAMP 堆栈,然后定期将简单的 MVC 应用程序部署到共享 Linux使用 Bitbucket 管道的服务器。

除路由器外,一切都按预期运行。在生产环境中,自动加载失败是因为 Linux 环境区分路由,例如 App/Controllers/Posts 和 app/controllers/posts。我意识到要使 PSR-4 自动加载正常工作,每个文件夹 / 命名空间和文件 / class 的大小写必须匹配,显然它在产品中失败的原因是实时环境的区分大小写突出了这种不匹配。

然而,使用 Docker 的明显原因是为了避免在本地和生产环境中出现这些不同的行为。在 Mac 上使用 Docker 是否肯定不会区分大小写,即使在基于 Ubuntu 图像的容器中,例如,这样我就可以拿起在本地解决这些问题而无需在产品中进行测试?在 Github (https://github.com/docker/for-mac/issues/320 back in 2016) suggests that this is not possible due to Mac’s "osxfs”. However, when looking at the Docker for Mac docs (https://docs.docker.com/docker-for-mac/) 上提出的问题似乎应该解决这个问题;具体来说:

By default, Mac file systems are case-insensitive while Linux is case-sensitive. On Linux, it is possible to create 2 separate files: test and Test, while on Mac these filenames would actually refer to the same underlying file. This can lead to problems where an app works correctly on a Mac (where the file contents are shared) but fails when run in Linux in production (where the file contents are distinct). To avoid this, Docker Desktop insists that all shared files are accessed as their original case. Therefore, if a file is created called test, it must be opened as test...

(粗体是我加的)

这不是表示应该区分大小写,还是我没有正确阅读文档?作为记录,这是我的 Docker 文件和 docker-compose 文件:

FROM php:7.4-apache

RUN a2enmod rewrite

RUN apt-get update
RUN apt-get install git -y
RUN apt-get install -y libzip-dev zip

RUN docker-php-ext-install pdo pdo_mysql

RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer

WORKDIR /var/www/developmental

COPY .docker/vhost.conf /etc/apache2/sites-available/000-default.conf
version: "3.8"

services:
  php:
    build:
      context: .
      dockerfile: ./.docker/Dockerfile
    ports:
      - 8080:80
    volumes:
      - .:/var/www/developmental

  db:
    image: mysql/mysql-server
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - 3308:3306
    environment:
      MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
    volumes:
      - db-data:/var/lib/mysql
      - ./data:/docker-entrypoint-initdb.d

volumes:
  db-data:

非常感谢(请放轻松 - 我是 Docker 菜鸟,这是我的第一个 Whosebug 问题!)

由于您是 bind-mounting 从主机到容器的目录,它伴随着主机文件系统可能存在的任何异常;例如你在 MacOS 上引用的关于 case-insensitivity 的段落。

使 Docker 图像成为 self-contained 通常更好:编写一个 Docker 文件,将 COPY 所有必需的应用程序代码放入图像中,并避免这个绑定完全挂载。如果您这样做,那么应用程序代码将仅位于 case-sensitive Linux 文件系统中。如果您需要更正文件名的大小写,您可以 RUN mv foo Foo 例如。

# In the Dockerfile
...
WORKDIR /var/www/developmental
COPY . .
# In docker-compose.yml
services:
  php:
    build:
      context: .
      dockerfile: ./.docker/Dockerfile
    ports:
      - 8080:80
    # and remove `volumes:`

在现代 Mac 基于 APFS 的系统上解决此问题的一种方法是创建一个区分大小写的卷,您可以在其中存储 docker 卷数据。 以下将创建一个区分大小写 (APFSX) 的新卷,您可以将其用于卷数据。 注意:您应该在新目录中执行此操作。

mkdir <docker volume directory>
sudo diskutil apfs addVolume disk1 APFSX docker -mountpoint <docker volume directory>
sudo chown -R $(id -u):$(id -g) <docker volume directory>

参考:Feature to opt-in into a case sensitive file-system (osxfs) on a volume mount