symfony-docker

repository·main·Indexed 25 days ago

https://github.com/dunglas/symfony-docker

A Docker-based installer and runtime for the Symfony web framework featuring FrankenPHP and Caddy. Designed for production, development, and CI environments, it includes support for Dev Containers, AI coding agents, and extensibility via Symfony Flex recipes for services like PostgreSQL, MySQL, Mercure, and Mailpit.

Tokens
7.5K
Snippets
29
Records
42
Agent score
85%

What's inside symfony-docker

  1. Disable HTTPS for production deployment

    main

    If you prefer to run your application over HTTP only instead of using HTTPS with Let's Encrypt, set the SERVER_NAME environment variable to :80 when starting your containers.

    SERVER_NAME=:80 \
    APP_SECRET=ChangeMe \
    CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \
    docker compose -f compose.yaml -f compose.prod.yaml up --wait
  2. Use the Symfony Docker Makefile template

    main

    To simplify common tasks, you can use a Makefile template in your project root. This template provides shortcuts for Docker, Composer, and Symfony commands.

    Setup Instructions:

    1. Create a new Makefile file at the root of your project.
    2. Copy the template content into the file.
    3. Ensure your editor uses tabs instead of spaces for the Makefile, as Makefiles are not compatible with spaces by default. You can enforce this in .editorconfig:
    [Makefile]
    indent_style = tab

    Running Make commands:

    • To view all available commands, run make.
    • If you are on Windows, you must install chocolatey.org or Cygwin to use the make command.
    make
  3. Install Symfony Docker on an existing project

    main

    To integrate Symfony Docker into an existing project, follow these steps:

    1. Download the skeleton: Download the repository from https://github.com/dunglas/symfony-docker.
    2. Copy files:
      • If using Git, use git archive to avoid overwriting your existing .git directory.
      • If using a ZIP, copy the extracted files into your project root.
    3. Enable Symfony Flex Docker support: Run the composer config command to set extra.symfony.docker to true.
    4. Re-execute recipes: Remove your symfony.lock file and force-install recipes to update Docker-related files based on your current packages.
    5. Build and Start: Build the images using docker compose build and start the environment with docker compose up.
  4. Build fresh images for production use

    main

    By default, docker compose up --wait only uses compose.yaml and compose.override.yaml. To properly build fresh images for a production environment using the production configuration, you must explicitly specify the compose files and use the --pull and --no-cache flags.

    docker compose -f compose.yaml -f compose.prod.yaml build --pull --no-cache
  5. Use Alpine Linux instead of Debian

    main

    By default, Symfony Docker uses Debian-based FrankenPHP images, which is the recommended configuration. You can switch to Alpine-based images to achieve smaller image sizes, though they may be slower and have known issues.

    To switch to Alpine, you must modify your Dockerfile to:

    1. Use the -alpine tag for the frankenphp_upstream stage.
    2. Change the shell from /bin/bash to /bin/ash.
    3. Replace apt-get commands with apk add --no-cache.
    4. Update the frankenphp_prod base image to alpine:3.
    5. Adjust file paths for magic.mgc (from /usr/lib/file/ to /usr/share/misc/).
    -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"]
    
    -# 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-php-extensions \
    
    -# 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
    +    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/*
    
    -FROM debian:13-slim AS frankenphp_prod
    +FROM alpine:3 AS frankenphp_prod
    
    -SHELL ["/bin/bash", "-euxo", "pipefail", "-c"]
    +SHELL ["/bin/ash", "-eux", "-o", "pipefail", "-c"]
    
    -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
  6. Deploy Symfony application in production

    main

    To deploy a Symfony application in production using Symfony Docker, you should use the production-optimized Docker Compose configuration. This process involves building a fresh image without cache and starting the containers with necessary environment variables like SERVER_NAME, APP_SECRET, and CADDY_MERCURE_JWT_SECRET.

    Prerequisites:

    • A Linux server with Docker and Docker Compose installed.
    • A domain name with an A record pointing to your server's IP address (required for Let's Encrypt TLS certificates).
    • Your project files cloned onto the server.

    Deployment Steps:

    1. Build the production image: Use the --pull and --no-cache flags to ensure you are using the latest base images and avoiding stale cache layers.
    2. Start the containers: Pass the required environment variables directly to the docker compose command.
    # 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
  7. Trust the Caddy CA authority on your host machine

    main

    By default, the certificates generated by the Caddy container are not trusted by your host machine. To avoid SSL/TLS warnings, you must copy the root certificate from the php container to your host's trust store.

    Follow the command corresponding to your operating system.

    ### Linux
    ```console
    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

    Mac

    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

    Windows

    docker compose cp php:/data/caddy/pki/authorities/local/root.crt %TEMP%/root.crt && certutil -addstore -f "ROOT" %TEMP%/root.crt
  8. Rebuild and verify MySQL setup

    main

    After making the configuration changes, rebuild the environment and verify the connection works.

    1. Rebuild the environment:

    docker compose down --remove-orphans && docker compose build --pull --no-cache

    2. Start the services:

    docker compose up --wait

    3. Test the connection: Run this command to verify the database is reachable via Doctrine:

    docker compose exec php bin/console dbal:run-sql -q "SELECT 1" && echo "OK" || echo "Connection is not working"
    docker compose down --remove-orphans && docker compose build --pull --no-cache
    docker compose up --wait
    docker compose exec php bin/console dbal:run-sql -q "SELECT 1" && echo "OK" || echo "Connection is not working"
  9. Disable HTTPS for local development

    main

    To run the project using HTTP instead of HTTPS, set the SERVER_NAME and MERCURE_PUBLIC_URL environment variables to use the http:// scheme and start the containers.

    SERVER_NAME=http://localhost \
    MERCURE_PUBLIC_URL=http://localhost/.well-known/mercure \
    docker compose up --wait