### Build and Start Development Image Source: https://github.com/dunglas/symfony-docker/blob/main/docs/troubleshooting.md Command to build and start the development Docker image. This uses the default compose configuration. ```bash docker compose up --wait ``` -------------------------------- ### Build and Start Production Image Source: https://github.com/dunglas/symfony-docker/blob/main/docs/troubleshooting.md Command to build and start the production Docker image. This explicitly uses the production-specific compose files and ensures a clean build. ```bash docker compose -f compose.yaml -f compose.prod.yaml build --pull --no-cache docker compose -f compose.yaml -f compose.prod.yaml up --wait ``` -------------------------------- ### Install Debian Packages with Alpine Equivalents Source: https://github.com/dunglas/symfony-docker/blob/main/docs/alpine.md Updates package installation commands from apt-get to apk add for Alpine Linux, installing 'file' and 'git'. ```diff # hadolint ignore=DL3008 -RUN <<-'EOF' - apt-get update - apt-get install -y --no-install-recommends \ - file \ - git +# hadolint ignore=DL3018 +RUN <<-'EOF' + apk add --no-cache \ + file \ + git ``` -------------------------------- ### Install libtree on Alpine Source: https://github.com/dunglas/symfony-docker/blob/main/docs/alpine.md Modifies the command to install 'libtree' using apk add instead of apt-get for Alpine Linux. ```diff # hadolint ignore=DL3008,SC3054,DL4006 -RUN <<-'EOF' - apt-get update - apt-get install -y --no-install-recommends libtree +# hadolint ignore=DL3018,SC3054,DL4006 +RUN <<-'EOF' + apk add --no-cache libtree ``` -------------------------------- ### Enable Xdebug Debugging on Linux/Mac Source: https://github.com/dunglas/symfony-docker/blob/main/docs/xdebug.md Enable step-by-step debugging by including 'debug' in the XDEBUG_MODE environment variable when starting Docker Compose. This is necessary for non-Dev Container setups. ```bash XDEBUG_MODE=develop,debug docker compose up --wait ``` -------------------------------- ### Rebuild and Start Docker Environment Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Rebuild the Docker images and restart the services after making configuration changes. ```console docker compose down --remove-orphans && docker compose build --pull --no-cache ``` ```console docker compose up --wait ``` -------------------------------- ### Install ORM Pack Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Install the symfony/orm-pack package to manage database interactions. ```console docker compose exec php composer req symfony/orm-pack ``` -------------------------------- ### Install OpenCode CLI and VS Code Extensions Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md Configure the Dev Container to install the OpenCode CLI and necessary VS Code extensions upon creation. This ensures the agent is ready to use after the container rebuilds. ```json { // Install the CLI on container creation (alongside the existing intelephense install) "postCreateCommand": "npm install -g intelephense && curl -fsSL https://opencode.ai/install | bash", "customizations": { "vscode": { "extensions": [ "sst-dev.opencode", "bmewburn.vscode-intelephense-client", "xdebug.php-debug" ] } } } ``` -------------------------------- ### Verify Xdebug Installation Source: https://github.com/dunglas/symfony-docker/blob/main/docs/xdebug.md Execute this command within the PHP container to verify that Xdebug is installed and to check its version. The output should display the Xdebug version. ```bash $ docker compose exec php php --version ``` -------------------------------- ### Configure DNS A Record Source: https://github.com/dunglas/symfony-docker/blob/main/docs/production.md Example of a DNS A record configuration to point your domain name to your server's IP address. Ensure `your-domain-name.example.com` is replaced with your actual domain. ```dns your-domain-name.example.com. IN A 207.154.233.113 ``` -------------------------------- ### Configure postStartCommand in devcontainer.json Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md This JSON snippet shows how to add a `postStartCommand` to the `.devcontainer/devcontainer.json` file. This command executes a firewall initialization script when the container starts, ensuring network security policies are applied. ```json { "postStartCommand": "sudo /app/.devcontainer/init-firewall.sh" } ``` -------------------------------- ### Build and Run Production Docker Containers Source: https://github.com/dunglas/symfony-docker/blob/main/docs/production.md Builds the production Docker image without cache and starts the application containers. Ensure you replace `your-domain-name.example.com` and set secure secrets for `APP_SECRET` and `CADDY_MERCURE_JWT_SECRET`. ```console # Build fresh production image docker compose -f compose.yaml -f compose.prod.yaml build --pull --no-cache # Start container SERVER_NAME=your-domain-name.example.com \ APP_SECRET=ChangeMe \ CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \ docker compose -f compose.yaml -f compose.prod.yaml up --wait ``` -------------------------------- ### Install MySQL Driver in Dockerfile Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Add the `pdo_mysql` extension to the `Dockerfile` to enable MySQL connectivity. ```diff ###> doctrine/doctrine-bundle ### -RUN install-php-extensions pdo_pgsql +RUN install-php-extensions pdo_mysql ###< doctrine/doctrine-bundle ### ``` -------------------------------- ### Run Production Containers without HTTPS Source: https://github.com/dunglas/symfony-docker/blob/main/docs/production.md Starts the application containers in production mode, exposing only an HTTP server. Replace `your-domain-name.example.com` with your domain or IP and set secure secrets. ```console SERVER_NAME=:80 \ APP_SECRET=ChangeMe \ CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \ docker compose -f compose.yaml -f compose.prod.yaml up --wait ``` -------------------------------- ### Install FrankenPHP Symfony Runtime Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md Install the FrankenPHP runtime for Symfony versions up to 7.3 to enable worker mode. ```bash composer require runtime/frankenphp-symfony ``` -------------------------------- ### Install Development Symfony Versions Source: https://github.com/dunglas/symfony-docker/blob/main/docs/options.md Use the STABILITY environment variable to install non-stable Symfony versions. Set it to 'dev' to use the development branch. This is only used if no composer.json is found. ```bash STABILITY=dev docker compose up --wait ``` ```batch set STABILITY=dev && docker compose up --wait&set STABILITY= ``` -------------------------------- ### Add Tools to Dev Dockerfile Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md Installs necessary tools like aggregate, curl, dnsmasq, and iptables within the Docker development image. ```dockerfile # hadolint ignore=DL3008 RUN <<-'EOF' mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" apt-get update apt-get install -y --no-install-recommends \ aggregate \ curl \ dnsmasq \ dnsutils \ iproute2 \ ipset \ iptables \ jq \ sudo install-php-extensions xdebug rm -rf /var/lib/apt/lists/* useradd -m -s /bin/bash nonroot # Allow nonroot to run only the firewall script as root, without a password echo "nonroot ALL=(root) NOPASSWD: /app/.devcontainer/init-firewall.sh" > /etc/sudoers.d/init-firewall chmod 0440 /etc/sudoers.d/init-firewall git config --system --add safe.directory /app EOF ``` -------------------------------- ### Install FrankenPHP Runtime Source: https://github.com/dunglas/symfony-docker/blob/main/docs/options.md Required for Symfony 7.3 or earlier with FrankenPHP in worker mode. Add the FrankenPHP Symfony runtime and configure the Caddyfile. ```bash composer require runtime/frankenphp-symfony ``` ```diff worker { file ./public/index.php + env APP_RUNTIME Runtime\FrankenPhpSymfony\Runtime {$FRANKENPHP_WORKER_CONFIG} } ``` -------------------------------- ### Synchronize Project with Symfony Docker Template Source: https://github.com/dunglas/symfony-docker/blob/main/docs/updating.md Run this command to synchronize your project with the latest version of the Symfony Docker skeleton. Ensure you have curl installed. ```bash curl -sSL https://raw.githubusercontent.com/coopTilleuls/template-sync/main/template-sync.sh | sh -s -- https://github.com/dunglas/symfony-docker ``` -------------------------------- ### Enable Xdebug Debugging on Windows Source: https://github.com/dunglas/symfony-docker/blob/main/docs/xdebug.md Enable step-by-step debugging on Windows by setting the XDEBUG_MODE environment variable before starting Docker Compose. The variable is reset after the command. ```batch set XDEBUG_MODE=develop,debug&& docker compose up --wait&set XDEBUG_MODE= ``` -------------------------------- ### Disable HTTPS for Local Development Source: https://github.com/dunglas/symfony-docker/blob/main/docs/tls.md Starts the Symfony Docker project using HTTP instead of HTTPS by setting specific environment variables. ```bash SERVER_NAME=http://localhost \ MERCURE_PUBLIC_URL=http://localhost/.well-known/mercure \ docker compose up --wait ``` -------------------------------- ### Add Custom Domain to ipset Allowlist Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md This bash command demonstrates how to add a custom domain to the `ipset` configuration within the dnsmasq setup. By appending the domain to the `ipset=` line in the script, you extend the firewall's allowlist to include your agent's provider API or private registry. ```bash # Domains are '/'-separated, ending with the ipset name ipset=/github.com/.../your-domain.com/allowed-domains ``` -------------------------------- ### Install Claude Code Dev Container Feature Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md Add the Claude Code Dev Container feature and VS Code extensions to your devcontainer.json for integration. ```json { "features": { "ghcr.io/devcontainers/features/node:1": {}, "ghcr.io/devcontainers-extra/features/claude-code:2": {}, }, "customizations": { "vscode": { "extensions": [ "anthropic.claude-code", "bmewburn.vscode-intelephense-client", "xdebug.php-debug", ], }, }, } ``` -------------------------------- ### Connect to Server via SSH Source: https://github.com/dunglas/symfony-docker/blob/main/docs/production.md Use this command to connect to your provisioned server via SSH. Replace `` with your server's IP address. ```console ssh root@ ``` -------------------------------- ### Create Certificate Directory Source: https://github.com/dunglas/symfony-docker/blob/main/docs/tls.md Creates a directory to store custom TLS certificates for Caddy. ```bash mkdir -p frankenphp/certs ``` -------------------------------- ### Firewall Verification Checks Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md These commands verify the firewall configuration by attempting to connect to a blocked domain (example.com) and a permitted domain (api.github.com). Success or failure of these checks indicates whether the firewall is correctly blocking or allowing traffic as intended. ```bash # Verify if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then echo "ERROR: Firewall check failed — able to reach example.com" exit 1 else echo "OK: example.com is blocked" fi if ! curl --connect-timeout 5 https://api.github.com/zen >/dev/null 2>&1; then echo "ERROR: Firewall check failed — unable to reach api.github.com" exit 1 else echo "OK: api.github.com is reachable" fi ``` -------------------------------- ### Copy Skeleton Files using CP Command Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md If you downloaded the skeleton as a ZIP archive, use this command to copy the extracted files into your existing project directory. ```bash cp -Rp symfony-docker/. my-existing-project/ ``` -------------------------------- ### Build Production Docker Images Source: https://github.com/dunglas/symfony-docker/blob/main/docs/troubleshooting.md Use this command to build fresh Docker images specifically for a production environment. It ensures that only production-relevant configurations are used and that images are built from scratch. ```bash docker compose -f compose.yaml -f compose.prod.yaml build --pull --no-cache ``` -------------------------------- ### Clone Project Repository Source: https://github.com/dunglas/symfony-docker/blob/main/docs/production.md Clone your Symfony project onto the server using Git. Replace `/` with your GitHub repository details. ```console git clone git@github.com:/.git ``` -------------------------------- ### Use Custom HTTP Ports Source: https://github.com/dunglas/symfony-docker/blob/main/docs/options.md Adjust HTTP, HTTPS, and HTTP3 ports using environment variables. Note that Let's Encrypt only supports standard ports. ```bash HTTP_PORT=8000 HTTPS_PORT=4443 HTTP3_PORT=4443 docker compose up --wait ``` -------------------------------- ### VS Code launch.json Configuration for PHP Debugging Source: https://github.com/dunglas/symfony-docker/blob/main/docs/xdebug.md Configure Visual Studio Code's launch.json file to enable PHP debugging. This includes setting the type, request, and path mappings for the debugger. ```json { "version": "0.2.0", "configurations": [ { "name": "Debug PHP", "type": "php", "request": "launch", "pathMappings": { "/app": "${workspaceFolder}" } } ] } ``` -------------------------------- ### Add make to Dockerfile Source: https://github.com/dunglas/symfony-docker/blob/main/docs/makefile.md This snippet shows how to add the `make` utility to your Docker image by modifying the Dockerfile. Rebuild the PHP image after adding this line. ```diff gettext \ git \ + make \ ``` -------------------------------- ### Test MySQL Connection Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Verify the database connection by running a simple SQL query using the Symfony console. ```console docker compose exec php bin/console dbal:run-sql -q "SELECT 1" && echo "OK" || echo "Connection is not working" ``` -------------------------------- ### Switch to Alpine Base Image and Shell Source: https://github.com/dunglas/symfony-docker/blob/main/docs/alpine.md Replaces the Debian-based FrankenPHP image with an Alpine-based one and updates the shell command for Alpine compatibility. ```diff -FROM dunglas/frankenphp:1-php8.5 AS frankenphp_upstream +FROM dunglas/frankenphp:1-php8.5-alpine AS frankenphp_upstream -SHELL ["/bin/bash", "-euxo", "pipefail", "-c"] +SHELL ["/bin/ash", "-eux", "-o", "pipefail", "-c"] ``` -------------------------------- ### Generate Custom TLS Certificates with mkcert Source: https://github.com/dunglas/symfony-docker/blob/main/docs/tls.md Generates self-signed TLS certificate and key files using mkcert for a specified local hostname. ```bash mkcert -cert-file frankenphp/certs/tls.pem -key-file frankenphp/certs/tls.key "server-name.localhost" ``` -------------------------------- ### Switch Production Image to Alpine Source: https://github.com/dunglas/symfony-docker/blob/main/docs/alpine.md Changes the base image for the production stage from Debian to Alpine. ```diff -FROM debian:13-slim AS frankenphp_prod +FROM alpine:3 AS frankenphp_prod ``` -------------------------------- ### Configure MySQL in Docker Compose Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Update the `compose.yaml` file to use a MySQL image and configure its environment variables and healthcheck. ```diff ###> doctrine/doctrine-bundle ### - image: postgres:${POSTGRES_VERSION:-16}-alpine + image: mysql:${MYSQL_VERSION:-8.0.32} environment: - POSTGRES_DB: ${POSTGRES_DB:-app} + MYSQL_DATABASE: ${MYSQL_DATABASE:-app} # You should definitely change the password in production + MYSQL_RANDOM_ROOT_PASSWORD: "true" - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!} + MYSQL_PASSWORD: ${MYSQL_PASSWORD:-!ChangeMe!} - POSTGRES_USER: ${POSTGRES_USER:-app} + MYSQL_USER: ${MYSQL_USER:-app} healthcheck: - test: ["CMD", "pg_isready", "-d", "${POSTGRES_DB:-app}", "-U", "${POSTGRES_USER:-app}"] + test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] timeout: 5s retries: 5 start_period: 60s volumes: - - database_data:/var/lib/postgresql/data:rw + - database_data:/var/lib/mysql:rw # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! - # - ./docker/db/data:/var/lib/postgresql/data:rw + # - ./docker/db/data:/var/lib/mysql:rw ###< doctrine/doctrine-bundle ### ``` -------------------------------- ### Configure Caddy to Use Custom TLS Certificates Source: https://github.com/dunglas/symfony-docker/blob/main/docs/tls.md Adds Caddy directives to use custom TLS certificate and key files, and mounts the certificate directory into the PHP service. ```diff php: environment: + CADDY_EXTRA_CONFIG: | + https:// { + tls /etc/caddy/certs/tls.pem /etc/caddy/certs/tls.key + } # ... volumes: + - ./frankenphp/certs:/etc/caddy/certs:ro # ... ``` -------------------------------- ### Enable Docker Support with Composer Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md Configure Symfony Flex to enable Docker support by setting the 'docker' extra configuration to 'true' in your composer.json file. ```bash composer config --json extra.symfony.docker 'true' ``` -------------------------------- ### Update Shell for Production Image Source: https://github.com/dunglas/symfony-docker/blob/main/docs/alpine.md Sets the shell for the Alpine-based production image to /bin/ash. ```diff -SHELL ["/bin/bash", "-euxo", "pipefail", "-c"] +SHELL ["/bin/ash", "-eux", "-o", "pipefail", "-c"] ``` -------------------------------- ### Copy Magic File for Alpine Source: https://github.com/dunglas/symfony-docker/blob/main/docs/alpine.md Updates the source path for the magic.mgc file when copying it to the Alpine-based production image. ```diff -COPY --from=frankenphp_prod_builder /usr/lib/file/magic.mgc /usr/lib/file/magic.mgc +COPY --from=frankenphp_prod_builder /usr/share/misc/magic.mgc /usr/share/misc/magic.mgc ``` -------------------------------- ### Build Docker Images Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md Build the Docker images for your Symfony project using docker compose. The --pull and --no-cache flags ensure you are using the latest base images and rebuilding from scratch. ```bash docker compose build --pull --no-cache ``` -------------------------------- ### Update .env for MySQL Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Modify the `.env` file to set the `DATABASE_URL` for the MySQL connection. ```dotenv DATABASE_URL=mysql://${MYSQL_USER:-app}:${MYSQL_PASSWORD:-!ChangeMe!}@database:3306/${MYSQL_DATABASE:-app}?serverVersion=${MYSQL_VERSION:-8.0.32}&charset=${MYSQL_CHARSET:-utf8mb4} ``` -------------------------------- ### Customize Server Name Source: https://github.com/dunglas/symfony-docker/blob/main/docs/options.md Set the SERVER_NAME environment variable to change the server's address or name. This is useful for local development or custom domain configurations. ```bash SERVER_NAME="app.localhost" docker compose up --wait ``` -------------------------------- ### Select Specific Symfony Version Source: https://github.com/dunglas/symfony-docker/blob/main/docs/options.md Use SYMFONY_VERSION to pin a specific Symfony version. This is useful for ensuring compatibility or testing specific releases. Note that this is only used if no composer.json is found. ```bash SYMFONY_VERSION=6.4.* docker compose up --wait ``` ```batch set SYMFONY_VERSION=6.4.* && docker compose up --wait&set SYMFONY_VERSION= ``` -------------------------------- ### Copy Skeleton Files using Git Archive Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md Use this command to copy the contents of the Symfony Docker skeleton into your existing project without including Git-related files. ```bash git archive --format=tar HEAD | tar -xC my-existing-project/ ``` -------------------------------- ### Add Caddy Root CA to Windows Trust Store Source: https://github.com/dunglas/symfony-docker/blob/main/docs/tls.md Copies the Caddy root certificate from the PHP container and adds it to the Windows ROOT certificate store. ```bash docker compose cp php:/data/caddy/pki/authorities/local/root.crt %TEMP%/root.crt && certutil -addstore -f "ROOT" %TEMP%/root.crt ``` -------------------------------- ### Include Local Environment Files in Production Images Source: https://github.com/dunglas/symfony-docker/blob/main/docs/production.md Configures the production Docker Compose file to include local environment variables from `.env.prod.local`. This is useful for passing sensitive configurations to containers. ```yaml # compose.prod.yaml services: php: env_file: - .env.prod.local # ... ``` -------------------------------- ### Configure iptables Firewall Rules Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md This section sets up iptables rules to control network traffic. It redirects DNS queries through dnsmasq, allows traffic to the host gateway, permits inbound HTTP/HTTPS, and enforces default DROP policies for all other traffic, with specific exceptions for established connections and whitelisted outbound destinations. ```bash # Redirect all outbound DNS queries (port 53) through dnsmasq so it can # populate the ipset before each connection. dnsmasq's own upstream queries # go to Docker's actual DNS port (not 53), so they are unaffected by these rules. iptables -t nat -I OUTPUT -p tcp --dport 53 -j DNAT --to-destination 127.0.0.2:53 iptables -t nat -I OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.2:53 # Allow traffic to/from the host gateway IP HOST_IP=$(ip route | grep default | cut -d" " -f3) [ -z "$HOST_IP" ] && { echo "ERROR: Failed to detect host IP" exit 1 } echo "Host gateway IP: $HOST_IP" iptables -A INPUT -s "$HOST_IP" -j ACCEPT iptables -A OUTPUT -d "$HOST_IP" -j ACCEPT # Allow inbound connections to published service ports (HTTP/HTTPS) iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A INPUT -p udp --dport 443 -j ACCEPT # Default DROP policies iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # Allow established connections iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow outbound traffic to local/private networks (e.g., Docker Compose services # and a model running on the host via host.docker.internal) iptables -A OUTPUT -d 10.0.0.0/8 -j ACCEPT iptables -A OUTPUT -d 172.16.0.0/12 -j ACCEPT iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT # Allow outbound to whitelisted IPs only (GitHub CIDRs + IPs populated by dnsmasq) iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT # Reject everything else with immediate feedback iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited echo "Firewall configuration complete" ``` -------------------------------- ### Enable Autonomous Mode via CLI Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md This command-line instruction enables autonomous mode for the `claude` tool, allowing it to bypass permission prompts. This is an alternative to configuring it within VS Code settings. ```console claude --dangerously-skip-permissions ``` -------------------------------- ### Makefile Template for Symfony Docker Source: https://github.com/dunglas/symfony-docker/blob/main/docs/makefile.md This is a comprehensive Makefile template for managing Symfony projects with Docker. It defines variables for Docker Compose and container commands, and provides targets for common development tasks. ```Makefile # Executables (local) DOCKER_COMP = docker compose # Docker containers PHP_CONT = $(DOCKER_COMP) exec php # Executables PHP = $(PHP_CONT) php COMPOSER = $(PHP_CONT) composer SYMFONY = $(PHP) bin/console # Misc .DEFAULT_GOAL = help .PHONY : help build up start down logs sh composer vendor sf cc test ## —— 🎵 🐳 The Symfony Docker Makefile 🐳 🎵 —————————————————————————————————— help: ## Outputs this help screen @grep -E '(^[a-zA-Z0-9\./_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%%-30s\033[0m %%s\n", $$1, $$2}' | sed -e 's/.\[32m##/\[33m/' ## —— Docker 🐳 ———————————————————————————————————————————————————————————————— build: ## Builds the Docker images @$(DOCKER_COMP) build --pull --no-cache up: ## Start the docker hub in detached mode (no logs) @$(DOCKER_COMP) up --detach start: build up ## Build and start the containers down: ## Stop the docker hub @$(DOCKER_COMP) down --remove-orphans logs: ## Show live logs @$(DOCKER_COMP) logs --tail=0 --follow sh: ## Connect to the FrankenPHP container @$(PHP_CONT) sh bash: ## Connect to the FrankenPHP container via bash so up and down arrows go to previous commands @$(PHP_CONT) bash test: ## Start tests with phpunit, pass the parameter "c=" to add options to phpunit, example: make test c="--group e2e --stop-on-failure" @$(eval c ?=) @$(DOCKER_COMP) exec -e APP_ENV=test php bin/phpunit $(c) ## —— Composer 🧙 —————————————————————————————————————————————————————————————— composer: ## Run composer, pass the parameter "c=" to run a given command, example: make composer c='req symfony/orm-pack' @$(eval c ?=) @$(COMPOSER) $(c) vendor: ## Install vendors according to the current composer.lock file vendor: c=install --prefer-dist --no-dev --no-progress --no-scripts --no-interaction vendor: composer ## —— Symfony 🎵 ——————————————————————————————————————————————————————————————— sf: ## List all Symfony commands or pass the parameter "c=" to run a given command, example: make sf c=about @$(eval c ?=) @$(SYMFONY) $(c) cc: c=c:c ## Clear the cache cc: sf ``` -------------------------------- ### View Git Diffs Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md After re-executing composer recipes, use 'git diff' to review the changes made to your project files and revert any unwanted modifications. ```bash git diff ``` -------------------------------- ### Extract Docker DNS Port and Configure dnsmasq Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md This script extracts the dynamic DNS port used by Docker's embedded DNS server and configures dnsmasq to use this port. It sets up dnsmasq to listen on an alternate loopback address and populate an ipset with resolved domain IPs, ensuring that only whitelisted domains are accessible. ```bash # Extract Docker's actual DNS port so dnsmasq can connect to it directly. # Docker's embedded DNS listens on a random high port and uses iptables NAT to # redirect 127.0.0.11:53 → 127.0.0.11:. By pointing dnsmasq at the real # port, its upstream queries naturally bypass our port-53 DNAT rules (no # uid-owner tricks needed) and don't require the DOCKER_OUTPUT NAT chain. DOCKER_DNS_PORT=$(echo "$DOCKER_DNS_RULES" | sed -n 's/.*udp.*--to-destination 127\.0\.0\.11:\([0-9]*\).*/\1/p' | head -1) [ -z "$DOCKER_DNS_PORT" ] && { echo "ERROR: Failed to extract Docker DNS port" exit 1 } echo "Docker DNS port: $DOCKER_DNS_PORT" # Configure dnsmasq to dynamically populate the ipset as domains are resolved. # This means the ipset always contains current IPs regardless of CDN rotation — # the IP is added to the ipset the moment it is resolved, before the connection # is made, so no connection is ever blocked due to stale IPs. # Add your agent's provider domain here (e.g. anthropic.com, api.openai.com). cat >/etc/dnsmasq.d/firewall-ipset.conf </dev/null || true dnsmasq --conf-dir=/etc/dnsmasq.d echo "dnsmasq started" ``` -------------------------------- ### EditorConfig for Makefile Source: https://github.com/dunglas/symfony-docker/blob/main/docs/makefile.md This configuration ensures your editor uses tabs instead of spaces for Makefile files, which is crucial for Makefile compatibility. Apply this to your .editorconfig file. ```editorconfig [Makefile] indent_style = tab ``` -------------------------------- ### Fix File Permissions on Linux Source: https://github.com/dunglas/symfony-docker/blob/main/docs/troubleshooting.md Run this command to set ownership of project files created by the Docker container to your current user. This is useful if you encounter editing permission issues on Linux. ```bash docker compose run --rm php chown -R $(id -u):$(id -g) . ``` -------------------------------- ### Configure PhpStorm for Xdebug CLI Debugging Source: https://github.com/dunglas/symfony-docker/blob/main/docs/xdebug.md When debugging CLI commands with PhpStorm, set the PHP_IDE_CONFIG environment variable to specify the server name for path mapping. ```bash XDEBUG_SESSION=1 PHP_IDE_CONFIG="serverName=symfony" php bin/console ... ``` -------------------------------- ### Add Caddy Root CA to Linux Trust Store Source: https://github.com/dunglas/symfony-docker/blob/main/docs/tls.md Copies the Caddy root certificate from the PHP container and updates the system's trusted certificates on Linux. ```bash docker cp $(docker compose ps -q php):/data/caddy/pki/authorities/local/root.crt /usr/local/share/ca-certificates/root.crt && sudo update-ca-certificates ``` -------------------------------- ### Update Database URL in services.php.environment Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Modify the `DATABASE_URL` environment variable in `services.php.environment` to reflect the MySQL connection details. ```yaml DATABASE_URL: mysql://${MYSQL_USER:-app}:${MYSQL_PASSWORD:-!ChangeMe!}@database:3306/${MYSQL_DATABASE:-app}?serverVersion=${MYSQL_VERSION:-8.0.32}&charset=${MYSQL_CHARSET:-utf8mb4} ``` -------------------------------- ### Network Firewall Script Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md Bash script to lock down outbound network access using iptables and ipset, allowing only specified domains via dnsmasq. ```bash #!/bin/bash # Locks down outbound network access to an allowlist using iptables + ipset. # dnsmasq intercepts DNS queries and adds the resolved IPs for allowed domains # to the ipset dynamically, so the ipset stays current despite CDN IP rotation. set -euo pipefail IFS=$'\n\t' # 1. Extract Docker DNS info BEFORE any flushing DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11" || true) # Flush existing rules and delete existing ipsets iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X ipset destroy allowed-domains 2>/dev/null || true # 2. Selectively restore ONLY internal Docker DNS resolution # These rules redirect queries to 127.0.0.11:53 to Docker's actual DNS port. # These are restored first; later, our DNS redirect rules are inserted with # `iptables -t nat -I OUTPUT ...`, so they precede these Docker rules. Only # dnsmasq's upstream queries (which are exempt from our redirect) pass through them. if [ -n "$DOCKER_DNS_RULES" ]; then echo "Restoring Docker DNS rules..." iptables -t nat -N DOCKER_OUTPUT 2>/dev/null || true iptables -t nat -N DOCKER_POSTROUTING 2>/dev/null || true echo "$DOCKER_DNS_RULES" | xargs -L 1 iptables -t nat else echo "No Docker DNS rules to restore" fi # Allow DNS (outbound only; return traffic is handled by ESTABLISHED,RELATED) # and localhost (covers dnsmasq ↔ Docker DNS on 127.0.0.11). iptables -A OUTPUT -p udp --dport 53 -j ACCEPT iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Create ipset with CIDR support ipset create allowed-domains hash:net # GitHub IP ranges echo "Fetching GitHub IP ranges..." gh_ranges=$(curl -s --connect-timeout 10 --max-time 30 --fail https://api.github.com/meta) [ -z "$gh_ranges" ] && { echo "ERROR: Failed to fetch GitHub IP ranges" exit 1 } echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null || { echo "ERROR: GitHub API response missing required fields" exit 1 } while read -r cidr; do [[ "$cidr" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]] || \ { echo "ERROR: Invalid CIDR: $cidr" exit 1 } echo "Adding GitHub range $cidr" ipset add allowed-domains "$cidr" -exist done < <(echo "$gh_ranges" | jq -r '(.web + .api + .git)[]' | grep -v ':' | aggregate -q) ``` -------------------------------- ### Grant NET_ADMIN Capability in Compose Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md Adds the NET_ADMIN capability to the PHP service in docker-compose.devcontainer.yaml to allow firewall management. ```yaml services: php: cap_add: - NET_ADMIN ``` -------------------------------- ### Update libtree command for Alpine Source: https://github.com/dunglas/symfony-docker/blob/main/docs/alpine.md Adjusts the libtree command to work with Alpine's package manager and file paths. ```diff mkdir -p /tmp/libs -BINARIES=( - frankenphp - php - file -) -for target in $(printf '%s\n' "${BINARIES[@]}" | xargs -I{} which {}) \ +BINARIES="frankenphp php file" +for target in $(printf '%s\n' $BINARIES | xargs -I{} which {}) \ - libtree -pv "$target" 2>/dev/null | grep -oP '(?:── )\K/\S+(?= \[)' | while IFS= read -r lib; do + libtree -pv "$target" 2>/dev/null | sed -n 's/.*── \(\/\[^ ]*\)\[.*/\1/p' | while IFS= read -r lib; do -rm -rf /var/lib/apt/lists/* ``` -------------------------------- ### Expose MySQL Port in Docker Compose Override Source: https://github.com/dunglas/symfony-docker/blob/main/docs/mysql.md Adjust the `compose.override.yaml` to expose the MySQL port (3306) instead of the PostgreSQL port. ```diff ###> doctrine/doctrine-bundle ### database: ports: - - "5432" + - "3306" ###< doctrine/doctrine-bundle ### ``` -------------------------------- ### Enable Autonomous Mode in VS Code Settings Source: https://github.com/dunglas/symfony-docker/blob/main/docs/agents.md These VS Code settings, added to `.devcontainer/devcontainer.json`, enable autonomous mode for Claude Code. This allows the agent to bypass permission prompts, streamlining its operation by setting `claudeCode.allowDangerouslySkipPermissions` and `claudeCode.initialPermissionMode`. ```json { "claudeCode.allowDangerouslySkipPermissions": true, "claudeCode.initialPermissionMode": "bypassPermissions" } ``` -------------------------------- ### Re-execute Composer Recipes Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md Remove the existing symfony.lock file and re-execute composer recipes to update Docker-related files based on your project's packages. Use the --force flag to overwrite existing files. ```bash rm symfony.lock composer recipes:install --force --verbose ``` -------------------------------- ### Add Caddy Root CA to macOS Trust Store Source: https://github.com/dunglas/symfony-docker/blob/main/docs/tls.md Copies the Caddy root certificate from the PHP container and adds it to the system's keychain on macOS. ```bash docker cp $(docker compose ps -q php):/data/caddy/pki/authorities/local/root.crt /tmp/root.crt && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/root.crt ``` -------------------------------- ### Update Worker Configuration for FrankenPHP Source: https://github.com/dunglas/symfony-docker/blob/main/docs/existing-project.md Modify the Caddyfile to specify the FrankenPHP runtime for your Symfony application. This is necessary for worker mode. ```caddy worker { file ./public/index.php env APP_RUNTIME Runtime\FrankenPhp\Runtime {$FRANKENPHP_WORKER_CONFIG} } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.