执行docker-compose up时卡在创建PHP和MySQL容器(Windows异常Mac正常)
Hey there! Let's figure out why your Docker Compose setup is stuck in an infinite creation loop on Windows when it works perfectly on Mac. I’ve run into similar cross-platform Docker quirks before, so let’s break this down step by step.
First, let’s note that Windows and macOS handle Docker volumes, file systems, and system permissions differently—those are almost always the culprits here.
1. Check Container Logs First (Critical!)
The "creating..." loop usually means containers are failing to start and restarting repeatedly. To get to the root of the issue, pull the logs for your db and php containers:
- For the MySQL container:
docker logs <your_db_container_name> - For the PHP container:
docker logs <your_php_container_name>
Logs will tell you exactly what’s wrong—like MySQL failing to initialize due to volume permissions, or PHP scripts crashing from line-ending issues. Don’t skip this step!
2. Fix Volume Mounting Issues
Bind Mount Permissions (PHP Service)
Windows Docker Desktop needs explicit permission to access your local files. Here’s how to fix it:
- Open Docker Desktop > Settings > Resources > File Sharing
- Make sure the parent folder of your
frontenddirectory is listed and checked (Docker needs access to read/write to./frontend:/var/www/html) - Add the
:delegatedflag to your PHP volume mount to optimize file system performance (this prevents slow syncs that can cause startup timeouts):php: build: ./frontend ports: - "80:80" volumes: - ./frontend:/var/www/html:delegated links: - db
Anonymous Volume Quirks (MySQL Service)
Your MySQL service uses an anonymous volume (/var/lib/mysql), which can hit permission issues on Windows’ NTFS file system. Switch to a named volume instead—Docker manages these more cleanly cross-platform:
services: db: build: ./backend restart: always ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql # Use named volume instead of anonymous environment: - MYSQL_ROOT_PASSWORD=123 - MYSQL_DATABASE=demo - MYSQL_USER=user - MYSQL_PASSWORD=123 # Define the named volume at the bottom of your compose file volumes: mysql_data:
3. Fix Line Ending Mismatches
Windows uses CRLF line endings, while macOS/Linux uses LF. If you edited your Dockerfiles or shell scripts on Windows, this can break container startup (e.g., a startup script fails to execute due to wrong line endings):
- In VS Code, click the CR/LF indicator in the bottom-right corner and switch to LF
- If using Git, set
autocrlfto false to prevent automatic line-ending conversion:git config --global core.autocrlf false
4. Ensure MySQL is Ready Before PHP Starts
Your current setup uses links, which doesn’t guarantee MySQL is fully initialized before PHP starts. This can cause PHP to fail connecting to the database, restarting the container. Replace links with depends_on + healthcheck to wait for MySQL to be ready:
services: db: build: ./backend restart: always ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=123 - MYSQL_DATABASE=demo - MYSQL_USER=user - MYSQL_PASSWORD=123 healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p123"] timeout: 20s retries: 10 php: build: ./frontend ports: - "80:80" volumes: - ./frontend:/var/www/html:delegated depends_on: db: condition: service_healthy # Wait until MySQL is healthy
5. Verify Docker Desktop Settings
- Use WSL 2 Backend: If you’re on Windows 10/11, enable WSL 2 in Docker Desktop > Settings > General > Use the WSL 2 based engine. WSL 2 has far better file system compatibility and performance than Hyper-V for Docker.
- Check Resource Allocation: Go to Settings > Resources > Advanced and ensure Docker has at least 2GB of RAM and 2 CPU cores—insufficient resources can cause containers to crash on startup.
Start with checking the logs, then work through these fixes one by one. Chances are, it’s either a volume permission issue or line-ending mismatch causing your containers to fail repeatedly.
内容的提问来源于stack exchange,提问作者Patrick Passarella

