Windows下Symfony-Docker配置宿主机与容器文件同步方法
问题原因
当前配置未做宿主机代码目录到容器的绑定挂载,所有代码都是镜像构建阶段直接COPY进镜像层的,修改宿主机文件自然不会同步到运行中的容器,必须重新构建镜像才能把新代码打入镜像层。同时现有配置是生产环境构建逻辑,没有适配开发场景的文件监听、热加载需求。
修复步骤
1. 修改docker-compose.yml配置
给php、caddy服务添加项目目录绑定挂载,同时补充必要的持久化卷,避免容器销毁后数据丢失。完整配置参考如下:
version: "3.4" services: db: image: mysql command: --default-authentication-plugin=mysql_native_password restart: always environment: MYSQL_ROOT_PASSWORD: root volumes: - mysql_data:/var/lib/mysql adminer: image: adminer restart: always ports: - 8080:8080 php: build: context: . target: symfony_php args: SYMFONY_VERSION: ${SYMFONY_VERSION:-} SKELETON: ${SKELETON:-symfony/skeleton} STABILITY: ${STABILITY:-stable} APP_ENV: dev restart: unless-stopped volumes: - php_socket:/var/run/php # 核心配置:将宿主机当前项目目录挂载到容器工作目录 - ./:/srv/app # 单独挂载var目录,避免宿主机文件覆盖容器内生成的权限正确的缓存、日志文件 - app_var:/srv/app/var healthcheck: interval: 10s timeout: 3s retries: 3 start_period: 30s environment: MERCURE_URL: ${CADDY_MERCURE_URL:-http://caddy/.well-known/mercure} MERCURE_PUBLIC_URL: https://${SERVER_NAME:-localhost}/.well-known/mercure MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!} APP_ENV: dev caddy: build: context: . target: symfony_caddy depends_on: - php environment: SERVER_NAME: ${SERVER_NAME:-localhost, caddy:80} MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!} MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeMe!} restart: unless-stopped volumes: - php_socket:/var/run/php # 同步挂载项目目录,保证Caddy可以读取public目录下的静态资源 - ./:/srv/app - app_var:/srv/app/var - caddy_data:/data - caddy_config:/config ports: - target: 80 published: ${HTTP_PORT:-80} protocol: tcp - target: 443 published: ${HTTPS_PORT:-443} protocol: tcp - target: 443 published: ${HTTP3_PORT:-443} protocol: udp volumes: php_socket: caddy_data: caddy_config: app_var: mysql_data:
Windows环境注意:必须开启Docker Desktop的WSL2后端,在设置-Resources-WSL Integration中给使用的WSL发行版开启集成,且把项目文件放在WSL的/home目录下,不要放在C/D盘等Windows原生目录,否则会出现文件监听失效、IO性能极差的问题。
2. 调整Dockerfile适配开发环境
现有Dockerfile默认使用生产版php配置,且composer安装时跳过了dev依赖,需要增加环境判断逻辑:
- 找到原有PHP配置链接行:
RUN ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini
替换为根据构建参数切换开发/生产配置的逻辑:
ARG APP_ENV=prod RUN if [ "$APP_ENV" = "dev" ]; then \ ln -s $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini; \ else \ ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini; \ fi
- 找到原有composer install执行块:
RUN set -eux; \ mkdir -p var/cache var/log; \ composer install --prefer-dist --no-dev --no-progress --no-scripts --no-interaction; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer symfony:dump-env prod; \ composer run-script --no-dev post-install-cmd; \ chmod +x bin/console; sync
替换为区分环境的安装逻辑:
RUN set -eux; \ mkdir -p var/cache var/log; \ if [ "$APP_ENV" = "dev" ]; then \ composer install --prefer-dist --no-progress --no-scripts --no-interaction; \ composer dump-autoload --classmap-authoritative; \ else \ composer install --prefer-dist --no-dev --no-progress --no-scripts --no-interaction; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer symfony:dump-env prod; \ composer run-script --no-dev post-install-cmd; \ fi; \ chmod +x bin/console; sync
3. 重建容器生效
配置修改完成后,在项目根目录执行以下命令重启容器即可,不需要全量重新构建镜像:
docker-compose down docker-compose up -d
启动完成后修改宿主机上的PHP、Twig、配置等文件,刷新页面即可实时看到变更,无需重新构建镜像。
常见问题排查
- 文件修改后仍不生效:优先检查项目存放路径,必须放在WSL原生文件系统下,放在/mnt/c/等Windows挂载目录会导致inotify文件监听失效。
- 出现权限报错:进入php容器执行
chown -R www-data:www-data /srv/app给项目目录重新赋权即可。 - 需要部署生产环境时,启动时传入
APP_ENV=prod参数即可自动切回生产构建逻辑,不影响线上使用。
内容的提问来源于stack exchange,提问作者user19468358
相关产品推荐
相关产品推荐

