Docker容器中Symfony安装后挂载本地目录文件丢失,如何实现二者共存?
解决Docker挂载本地目录覆盖Symfony项目的问题
以下是三种可行的解决方案,既保留容器内Symfony安装逻辑,又能实现本地目录的映射同步:
方案一:容器启动时自动初始化项目文件
适合希望镜像自带Symfony骨架,首次启动自动同步到本地目录的场景。
- 修改Dockerfile:将Symfony项目安装到临时目录,避免被挂载覆盖
FROM php:8.1-fpm WORKDIR /var/www/html RUN apt-get update && apt-get install -y zlib1g-dev g++ git libicu-dev zip libzip-dev zip \ && docker-php-ext-install intl opcache pdo pdo_mysql \ && pecl install apcu \ && docker-php-ext-enable apcu \ && docker-php-ext-configure zip \ && docker-php-ext-install zip RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN curl -sS https://get.symfony.com/cli/installer | bash RUN mv /root/.symfony5/bin/symfony /usr/local/bin/symfony # 将Symfony安装到临时目录,避免被挂载覆盖 RUN composer create-project symfony/skeleton:^6.3 /var/www/symfony-skeleton RUN pecl install xdebug \ && docker-php-ext-enable xdebug RUN touch /var/log/xdebug.log && \ chmod 777 /var/log/xdebug.log # 添加启动脚本 COPY docker/php/entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] CMD ["php-fpm"]
- 创建启动脚本
docker/php/entrypoint.sh:检查挂载目录是否为空,为空则同步项目文件
#!/bin/sh # 检查挂载目录是否未初始化(通过Symfony必备的composer.json判断) if [ ! -f /var/www/html/composer.json ]; then echo "初始化Symfony项目到本地挂载目录..." cp -r /var/www/symfony-skeleton/* /var/www/html/ cp -r /var/www/symfony-skeleton/.[!.]* /var/www/html/ # 复制隐藏文件 fi # 执行容器原启动命令 exec "$@"
- 保持原docker-compose.yml不变:首次启动容器时,脚本会自动将临时目录的Symfony文件同步到本地
./app目录,后续启动会保留本地修改。
方案二:用命名卷初始化后同步到本地
适合先通过镜像生成项目,再将文件同步到本地目录的场景。
- 临时修改docker-compose.yml:使用命名卷替代绑定挂载
version: "3" networks: nginx-php81-mysql8-node: services: # nginx nginx-service: image: nginx:stable-alpine container_name: nginx-container ports: - "8080:80" volumes: - symfony-app:/var/www/html # 替换为命名卷 - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php81-service - mysql8-service # php php81-service: build: context: . dockerfile: docker/php/Dockerfile container_name: php81-container ports: - "8000:8000" volumes: - symfony-app:/var/www/html # 替换为命名卷 - ./docker/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - ./docker/php/conf.d/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini # 定义命名卷 volumes: symfony-app:
- 启动容器并同步文件到本地:
# 启动容器,让镜像中的Symfony项目存入命名卷 docker-compose up -d # 将命名卷中的文件复制到本地./app目录 docker run --rm -v symfony-app:/source -v $(pwd)/app:/target alpine cp -r /source/. /target/ # 停止容器并恢复原docker-compose.yml的绑定挂载配置 docker-compose down
- 恢复绑定挂载:将docker-compose.yml改回原有的
- ./app:/var/www/html,后续启动即可使用本地目录开发。
方案三:本地预先创建Symfony项目
贴近常规开发流程,本地管理项目文件,容器仅提供运行环境。
- 修改Dockerfile:移除创建Symfony项目的命令
FROM php:8.1-fpm WORKDIR /var/www/html RUN apt-get update && apt-get install -y zlib1g-dev g++ git libicu-dev zip libzip-dev zip \ && docker-php-ext-install intl opcache pdo pdo_mysql \ && pecl install apcu \ && docker-php-ext-enable apcu \ && docker-php-ext-configure zip \ && docker-php-ext-install zip RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN curl -sS https://get.symfony.com/cli/installer | bash RUN mv /root/.symfony5/bin/symfony /usr/local/bin/symfony RUN pecl install xdebug \ && docker-php-ext-enable xdebug RUN touch /var/log/xdebug.log && \ chmod 777 /var/log/xdebug.log
- 本地创建Symfony项目:
# 本地执行composer命令创建项目到./app目录 composer create-project symfony/skeleton:^6.3 app
- 启动容器:保持原docker-compose.yml的挂载配置,容器会直接使用本地的Symfony项目文件,本地修改实时同步到容器。
内容的提问来源于stack exchange,提问作者Csaba Vörös
相关产品推荐
相关产品推荐

