initial commit
This commit is contained in:
		
							
								
								
									
										30
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
**/*.log
 | 
			
		||||
**/*.md
 | 
			
		||||
**/*.php~
 | 
			
		||||
**/*.dist.php
 | 
			
		||||
**/*.dist
 | 
			
		||||
**/*.cache
 | 
			
		||||
**/._*
 | 
			
		||||
**/.dockerignore
 | 
			
		||||
**/.DS_Store
 | 
			
		||||
**/.git/
 | 
			
		||||
**/.gitattributes
 | 
			
		||||
**/.gitignore
 | 
			
		||||
**/.gitmodules
 | 
			
		||||
**/docker-compose.*.yaml
 | 
			
		||||
**/docker-compose.*.yml
 | 
			
		||||
**/docker-compose.yaml
 | 
			
		||||
**/docker-compose.yml
 | 
			
		||||
**/Dockerfile
 | 
			
		||||
**/Thumbs.db
 | 
			
		||||
.github/
 | 
			
		||||
docs/
 | 
			
		||||
public/bundles/
 | 
			
		||||
tests/
 | 
			
		||||
var/
 | 
			
		||||
vendor/
 | 
			
		||||
.editorconfig
 | 
			
		||||
.env.*.local
 | 
			
		||||
.env.local
 | 
			
		||||
.env.local.php
 | 
			
		||||
.env.test
 | 
			
		||||
							
								
								
									
										72
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
# EditorConfig helps developers define and maintain consistent
 | 
			
		||||
# coding styles between different editors and IDEs
 | 
			
		||||
# editorconfig.org
 | 
			
		||||
 | 
			
		||||
root = true
 | 
			
		||||
 | 
			
		||||
[*]
 | 
			
		||||
# Change these settings to your own preference
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
# We recommend you to keep these unchanged
 | 
			
		||||
end_of_line = lf
 | 
			
		||||
charset = utf-8
 | 
			
		||||
trim_trailing_whitespace = true
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
 | 
			
		||||
[*.{js,html,ts,tsx}]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[*.json]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[*.md]
 | 
			
		||||
trim_trailing_whitespace = false
 | 
			
		||||
 | 
			
		||||
[*.php]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
[*.sh]
 | 
			
		||||
indent_style = tab
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
[*.xml{,.dist}]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
[*.{yaml,yml}]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
trim_trailing_whitespace = false
 | 
			
		||||
 | 
			
		||||
[.github/workflows/*.yml]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[.gitmodules]
 | 
			
		||||
indent_style = tab
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
[.php_cs{,.dist}]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
[.travis.yml]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[composer.json]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 4
 | 
			
		||||
 | 
			
		||||
[docker-compose{,.*}.{yaml,yml}]
 | 
			
		||||
indent_style = space
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[Dockerfile]
 | 
			
		||||
indent_style = tab
 | 
			
		||||
indent_size = 4
 | 
			
		||||
							
								
								
									
										20
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.env
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
# In all environments, the following files are loaded if they exist,
 | 
			
		||||
# the latter taking precedence over the former:
 | 
			
		||||
#
 | 
			
		||||
#  * .env                contains default values for the environment variables needed by the app
 | 
			
		||||
#  * .env.local          uncommitted file with local overrides
 | 
			
		||||
#  * .env.$APP_ENV       committed environment-specific defaults
 | 
			
		||||
#  * .env.$APP_ENV.local uncommitted environment-specific overrides
 | 
			
		||||
#
 | 
			
		||||
# Real environment variables win over .env files.
 | 
			
		||||
#
 | 
			
		||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
 | 
			
		||||
# https://symfony.com/doc/current/configuration/secrets.html
 | 
			
		||||
#
 | 
			
		||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
 | 
			
		||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
 | 
			
		||||
 | 
			
		||||
###> symfony/framework-bundle ###
 | 
			
		||||
APP_ENV=dev
 | 
			
		||||
APP_SECRET=787ada016f98349a29beefa84d4c2a8b
 | 
			
		||||
###< symfony/framework-bundle ###
 | 
			
		||||
							
								
								
									
										16
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
* text=auto eol=lf
 | 
			
		||||
 | 
			
		||||
*.conf text eol=lf
 | 
			
		||||
*.html text eol=lf
 | 
			
		||||
*.ini text eol=lf
 | 
			
		||||
*.js text eol=lf
 | 
			
		||||
*.json text eol=lf
 | 
			
		||||
*.md text eol=lf
 | 
			
		||||
*.php text eol=lf
 | 
			
		||||
*.sh text eol=lf
 | 
			
		||||
*.yaml text eol=lf
 | 
			
		||||
*.yml text eol=lf
 | 
			
		||||
bin/console text eol=lf
 | 
			
		||||
 | 
			
		||||
*.ico binary
 | 
			
		||||
*.png binary
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
github: [dunglas]
 | 
			
		||||
							
								
								
									
										42
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
name: CI
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
    push:
 | 
			
		||||
    pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
    lint:
 | 
			
		||||
        name: Docker Lint
 | 
			
		||||
        runs-on: ubuntu-latest
 | 
			
		||||
        steps:
 | 
			
		||||
          - name: Checkout
 | 
			
		||||
            uses: actions/checkout@v3
 | 
			
		||||
          - name: Lint Dockerfile
 | 
			
		||||
            uses: hadolint/hadolint-action@master
 | 
			
		||||
            with:
 | 
			
		||||
                dockerfile: Dockerfile
 | 
			
		||||
                ignore: DL3007,DL3018 # Ignore using latest on mlocati/php-extension-installer & version in apk add
 | 
			
		||||
    build:
 | 
			
		||||
        name: Docker build
 | 
			
		||||
        runs-on: ubuntu-latest
 | 
			
		||||
        steps:
 | 
			
		||||
            - name: Checkout
 | 
			
		||||
              uses: actions/checkout@v3
 | 
			
		||||
            - name: Pull images
 | 
			
		||||
              run: docker compose pull
 | 
			
		||||
            - name: Start services
 | 
			
		||||
              run: docker compose up --build -d
 | 
			
		||||
            - name: Wait for services
 | 
			
		||||
              run: |
 | 
			
		||||
                  while status="$(docker inspect --format="{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}" "$(docker compose ps -q php)")"; do
 | 
			
		||||
                    case $status in
 | 
			
		||||
                      starting) sleep 1;;
 | 
			
		||||
                      healthy) exit 0;;
 | 
			
		||||
                      unhealthy) exit 1;;
 | 
			
		||||
                    esac
 | 
			
		||||
                  done
 | 
			
		||||
                  exit 1
 | 
			
		||||
            - name: Check HTTP reachability
 | 
			
		||||
              run: curl http://localhost
 | 
			
		||||
            - name: Check HTTPS reachability
 | 
			
		||||
              run: curl -k https://localhost
 | 
			
		||||
							
								
								
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
 | 
			
		||||
###> symfony/framework-bundle ###
 | 
			
		||||
/.env.local
 | 
			
		||||
/.env.local.php
 | 
			
		||||
/.env.*.local
 | 
			
		||||
/config/secrets/prod/prod.decrypt.private.php
 | 
			
		||||
/public/bundles/
 | 
			
		||||
/var/
 | 
			
		||||
/vendor/
 | 
			
		||||
###< symfony/framework-bundle ###
 | 
			
		||||
							
								
								
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
# Default ignored files
 | 
			
		||||
/shelf/
 | 
			
		||||
/workspace.xml
 | 
			
		||||
# Editor-based HTTP Client requests
 | 
			
		||||
/httpRequests/
 | 
			
		||||
# Datasource local storage ignored files
 | 
			
		||||
/dataSources/
 | 
			
		||||
/dataSources.local.xml
 | 
			
		||||
							
								
								
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.idea/modules.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="ProjectModuleManager">
 | 
			
		||||
    <modules>
 | 
			
		||||
      <module fileurl="file://$PROJECT_DIR$/.idea/wireweb.iml" filepath="$PROJECT_DIR$/.idea/wireweb.iml" />
 | 
			
		||||
    </modules>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										19
									
								
								.idea/php.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								.idea/php.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="MessDetectorOptionsConfiguration">
 | 
			
		||||
    <option name="transferred" value="true" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="PHPCSFixerOptionsConfiguration">
 | 
			
		||||
    <option name="transferred" value="true" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="PHPCodeSnifferOptionsConfiguration">
 | 
			
		||||
    <option name="highlightLevel" value="WARNING" />
 | 
			
		||||
    <option name="transferred" value="true" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="PhpStanOptionsConfiguration">
 | 
			
		||||
    <option name="transferred" value="true" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="PsalmOptionsConfiguration">
 | 
			
		||||
    <option name="transferred" value="true" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										8
									
								
								.idea/wireweb.iml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.idea/wireweb.iml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module type="WEB_MODULE" version="4">
 | 
			
		||||
  <component name="NewModuleRootManager">
 | 
			
		||||
    <content url="file://$MODULE_DIR$" />
 | 
			
		||||
    <orderEntry type="inheritedJdk" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
							
								
								
									
										130
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
#syntax=docker/dockerfile:1.4
 | 
			
		||||
 | 
			
		||||
# The different stages of this Dockerfile are meant to be built into separate images
 | 
			
		||||
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
 | 
			
		||||
# https://docs.docker.com/compose/compose-file/#target
 | 
			
		||||
 | 
			
		||||
# Builder images
 | 
			
		||||
FROM composer/composer:2-bin AS composer
 | 
			
		||||
 | 
			
		||||
FROM mlocati/php-extension-installer:latest AS php_extension_installer
 | 
			
		||||
 | 
			
		||||
# Build Caddy with the Mercure and Vulcain modules
 | 
			
		||||
FROM caddy:2.6-builder-alpine AS app_caddy_builder
 | 
			
		||||
 | 
			
		||||
RUN xcaddy build \
 | 
			
		||||
	--with github.com/dunglas/mercure \
 | 
			
		||||
	--with github.com/dunglas/mercure/caddy \
 | 
			
		||||
	--with github.com/dunglas/vulcain \
 | 
			
		||||
	--with github.com/dunglas/vulcain/caddy
 | 
			
		||||
 | 
			
		||||
# Prod image
 | 
			
		||||
FROM php:8.2-fpm-alpine AS app_php
 | 
			
		||||
 | 
			
		||||
# Allow to use development versions of Symfony
 | 
			
		||||
ARG STABILITY="stable"
 | 
			
		||||
ENV STABILITY ${STABILITY}
 | 
			
		||||
 | 
			
		||||
# Allow to select Symfony version
 | 
			
		||||
ARG SYMFONY_VERSION=""
 | 
			
		||||
ENV SYMFONY_VERSION ${SYMFONY_VERSION}
 | 
			
		||||
 | 
			
		||||
ENV APP_ENV=prod
 | 
			
		||||
 | 
			
		||||
WORKDIR /srv/app
 | 
			
		||||
 | 
			
		||||
# php extensions installer: https://github.com/mlocati/docker-php-extension-installer
 | 
			
		||||
COPY --from=php_extension_installer --link /usr/bin/install-php-extensions /usr/local/bin/
 | 
			
		||||
 | 
			
		||||
# persistent / runtime deps
 | 
			
		||||
RUN apk add --no-cache \
 | 
			
		||||
		acl \
 | 
			
		||||
		fcgi \
 | 
			
		||||
		file \
 | 
			
		||||
		gettext \
 | 
			
		||||
		git \
 | 
			
		||||
	;
 | 
			
		||||
 | 
			
		||||
RUN set -eux; \
 | 
			
		||||
    install-php-extensions \
 | 
			
		||||
    	apcu \
 | 
			
		||||
    	intl \
 | 
			
		||||
		opcache \
 | 
			
		||||
    	zip \
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
###> recipes ###
 | 
			
		||||
###< recipes ###
 | 
			
		||||
 | 
			
		||||
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
 | 
			
		||||
COPY --link docker/php/conf.d/app.ini $PHP_INI_DIR/conf.d/
 | 
			
		||||
COPY --link docker/php/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/
 | 
			
		||||
 | 
			
		||||
COPY --link docker/php/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf
 | 
			
		||||
RUN mkdir -p /var/run/php
 | 
			
		||||
 | 
			
		||||
COPY --link docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck
 | 
			
		||||
RUN chmod +x /usr/local/bin/docker-healthcheck
 | 
			
		||||
 | 
			
		||||
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"]
 | 
			
		||||
 | 
			
		||||
COPY --link docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
 | 
			
		||||
RUN chmod +x /usr/local/bin/docker-entrypoint
 | 
			
		||||
 | 
			
		||||
ENTRYPOINT ["docker-entrypoint"]
 | 
			
		||||
CMD ["php-fpm"]
 | 
			
		||||
 | 
			
		||||
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
 | 
			
		||||
ENV COMPOSER_ALLOW_SUPERUSER=1
 | 
			
		||||
ENV PATH="${PATH}:/root/.composer/vendor/bin"
 | 
			
		||||
 | 
			
		||||
COPY --from=composer --link /composer /usr/bin/composer
 | 
			
		||||
 | 
			
		||||
# prevent the reinstallation of vendors at every changes in the source code
 | 
			
		||||
COPY --link composer.* symfony.* ./
 | 
			
		||||
RUN set -eux; \
 | 
			
		||||
    if [ -f composer.json ]; then \
 | 
			
		||||
		composer install --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress; \
 | 
			
		||||
		composer clear-cache; \
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
# copy sources
 | 
			
		||||
COPY --link  . ./
 | 
			
		||||
RUN rm -Rf docker/
 | 
			
		||||
 | 
			
		||||
RUN set -eux; \
 | 
			
		||||
	mkdir -p var/cache var/log; \
 | 
			
		||||
    if [ -f composer.json ]; then \
 | 
			
		||||
		composer dump-autoload --classmap-authoritative --no-dev; \
 | 
			
		||||
		composer dump-env prod; \
 | 
			
		||||
		composer run-script --no-dev post-install-cmd; \
 | 
			
		||||
		chmod +x bin/console; sync; \
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
# Dev image
 | 
			
		||||
FROM app_php AS app_php_dev
 | 
			
		||||
 | 
			
		||||
ENV APP_ENV=dev XDEBUG_MODE=off
 | 
			
		||||
VOLUME /srv/app/var/
 | 
			
		||||
 | 
			
		||||
RUN rm "$PHP_INI_DIR/conf.d/app.prod.ini"; \
 | 
			
		||||
	mv "$PHP_INI_DIR/php.ini" "$PHP_INI_DIR/php.ini-production"; \
 | 
			
		||||
	mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
 | 
			
		||||
 | 
			
		||||
COPY --link docker/php/conf.d/app.dev.ini $PHP_INI_DIR/conf.d/
 | 
			
		||||
 | 
			
		||||
RUN set -eux; \
 | 
			
		||||
	install-php-extensions \
 | 
			
		||||
    	xdebug \
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
RUN rm -f .env.local.php
 | 
			
		||||
 | 
			
		||||
# Caddy image
 | 
			
		||||
FROM caddy:2.6-alpine AS app_caddy
 | 
			
		||||
 | 
			
		||||
WORKDIR /srv/app
 | 
			
		||||
 | 
			
		||||
COPY --from=app_caddy_builder --link /usr/bin/caddy /usr/bin/caddy
 | 
			
		||||
COPY --from=app_php --link /srv/app/public public/
 | 
			
		||||
COPY --link docker/caddy/Caddyfile /etc/caddy/Caddyfile
 | 
			
		||||
							
								
								
									
										19
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
Copyright (c) Fabien Potencier
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is furnished
 | 
			
		||||
to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										46
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
# Symfony Docker
 | 
			
		||||
 | 
			
		||||
A [Docker](https://www.docker.com/)-based installer and runtime for the [Symfony](https://symfony.com) web framework, with full [HTTP/2](https://symfony.com/doc/current/weblink.html), HTTP/3 and HTTPS support.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
## Getting Started
 | 
			
		||||
 | 
			
		||||
1. If not already done, [install Docker Compose](https://docs.docker.com/compose/install/) (v2.10+)
 | 
			
		||||
2. Run `docker compose build --pull --no-cache` to build fresh images
 | 
			
		||||
3. Run `docker compose up` (the logs will be displayed in the current shell)
 | 
			
		||||
4. Open `https://localhost` in your favorite web browser and [accept the auto-generated TLS certificate](https://stackoverflow.com/a/15076602/1352334)
 | 
			
		||||
5. Run `docker compose down --remove-orphans` to stop the Docker containers.
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
* Production, development and CI ready
 | 
			
		||||
* [Installation of extra Docker Compose services](docs/extra-services.md) with Symfony Flex
 | 
			
		||||
* Automatic HTTPS (in dev and in prod!)
 | 
			
		||||
* HTTP/2, HTTP/3 and [Preload](https://symfony.com/doc/current/web_link.html) support
 | 
			
		||||
* Built-in [Mercure](https://symfony.com/doc/current/mercure.html) hub
 | 
			
		||||
* [Vulcain](https://vulcain.rocks) support
 | 
			
		||||
* Native [XDebug](docs/xdebug.md) integration
 | 
			
		||||
* Just 2 services (PHP FPM and Caddy server)
 | 
			
		||||
* Super-readable configuration
 | 
			
		||||
 | 
			
		||||
**Enjoy!**
 | 
			
		||||
 | 
			
		||||
## Docs
 | 
			
		||||
 | 
			
		||||
1. [Build options](docs/build.md)
 | 
			
		||||
2. [Using Symfony Docker with an existing project](docs/existing-project.md)
 | 
			
		||||
3. [Support for extra services](docs/extra-services.md)
 | 
			
		||||
4. [Deploying in production](docs/production.md)
 | 
			
		||||
5. [Debugging with Xdebug](docs/xdebug.md)
 | 
			
		||||
6. [TLS Certificates](docs/tls.md)
 | 
			
		||||
7. [Using a Makefile](docs/makefile.md)
 | 
			
		||||
8. [Troubleshooting](docs/troubleshooting.md)
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
Symfony Docker is available under the MIT License.
 | 
			
		||||
 | 
			
		||||
## Credits
 | 
			
		||||
 | 
			
		||||
Created by [Kévin Dunglas](https://dunglas.fr), co-maintained by [Maxime Helias](https://twitter.com/maxhelias) and sponsored by [Les-Tilleuls.coop](https://les-tilleuls.coop).
 | 
			
		||||
							
								
								
									
										17
									
								
								bin/console
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								bin/console
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
#!/usr/bin/env php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use App\Kernel;
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
 | 
			
		||||
 | 
			
		||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
 | 
			
		||||
    throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
 | 
			
		||||
 | 
			
		||||
return function (array $context) {
 | 
			
		||||
    $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
 | 
			
		||||
 | 
			
		||||
    return new Application($kernel);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										68
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								composer.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "symfony/skeleton",
 | 
			
		||||
    "type": "project",
 | 
			
		||||
    "license": "MIT",
 | 
			
		||||
    "description": "A minimal Symfony project recommended to create bare bones applications",
 | 
			
		||||
    "minimum-stability": "stable",
 | 
			
		||||
    "prefer-stable": true,
 | 
			
		||||
    "require": {
 | 
			
		||||
        "php": ">=8.2.5",
 | 
			
		||||
        "ext-ctype": "*",
 | 
			
		||||
        "ext-iconv": "*",
 | 
			
		||||
        "symfony/console": "6.2.*",
 | 
			
		||||
        "symfony/dotenv": "6.2.*",
 | 
			
		||||
        "symfony/flex": "^2",
 | 
			
		||||
        "symfony/framework-bundle": "6.2.*",
 | 
			
		||||
        "symfony/runtime": "6.2.*",
 | 
			
		||||
        "symfony/yaml": "6.2.*"
 | 
			
		||||
    },
 | 
			
		||||
    "config": {
 | 
			
		||||
        "allow-plugins": {
 | 
			
		||||
            "php-http/discovery": true,
 | 
			
		||||
            "symfony/flex": true,
 | 
			
		||||
            "symfony/runtime": true
 | 
			
		||||
        },
 | 
			
		||||
        "sort-packages": true
 | 
			
		||||
    },
 | 
			
		||||
    "autoload": {
 | 
			
		||||
        "psr-4": {
 | 
			
		||||
            "App\\": "src/"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "autoload-dev": {
 | 
			
		||||
        "psr-4": {
 | 
			
		||||
            "App\\Tests\\": "tests/"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "replace": {
 | 
			
		||||
        "symfony/polyfill-ctype": "*",
 | 
			
		||||
        "symfony/polyfill-iconv": "*",
 | 
			
		||||
        "symfony/polyfill-php72": "*",
 | 
			
		||||
        "symfony/polyfill-php73": "*",
 | 
			
		||||
        "symfony/polyfill-php74": "*",
 | 
			
		||||
        "symfony/polyfill-php80": "*",
 | 
			
		||||
        "symfony/polyfill-php81": "*"
 | 
			
		||||
    },
 | 
			
		||||
    "scripts": {
 | 
			
		||||
        "auto-scripts": {
 | 
			
		||||
            "cache:clear": "symfony-cmd",
 | 
			
		||||
            "assets:install %PUBLIC_DIR%": "symfony-cmd"
 | 
			
		||||
        },
 | 
			
		||||
        "post-install-cmd": [
 | 
			
		||||
            "@auto-scripts"
 | 
			
		||||
        ],
 | 
			
		||||
        "post-update-cmd": [
 | 
			
		||||
            "@auto-scripts"
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "conflict": {
 | 
			
		||||
        "symfony/symfony": "*"
 | 
			
		||||
    },
 | 
			
		||||
    "extra": {
 | 
			
		||||
        "symfony": {
 | 
			
		||||
            "allow-contrib": false,
 | 
			
		||||
            "require": "6.2.*",
 | 
			
		||||
            "docker": true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2388
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2388
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5
									
								
								config/bundles.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								config/bundles.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										19
									
								
								config/packages/cache.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								config/packages/cache.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
framework:
 | 
			
		||||
    cache:
 | 
			
		||||
        # Unique name of your app: used to compute stable namespaces for cache keys.
 | 
			
		||||
        #prefix_seed: your_vendor_name/app_name
 | 
			
		||||
 | 
			
		||||
        # The "app" cache stores to the filesystem by default.
 | 
			
		||||
        # The data in this cache should persist between deploys.
 | 
			
		||||
        # Other options include:
 | 
			
		||||
 | 
			
		||||
        # Redis
 | 
			
		||||
        #app: cache.adapter.redis
 | 
			
		||||
        #default_redis_provider: redis://localhost
 | 
			
		||||
 | 
			
		||||
        # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
 | 
			
		||||
        #app: cache.adapter.apcu
 | 
			
		||||
 | 
			
		||||
        # Namespaced pools use the above "app" backend by default
 | 
			
		||||
        #pools:
 | 
			
		||||
            #my.dedicated.cache: null
 | 
			
		||||
							
								
								
									
										25
									
								
								config/packages/framework.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								config/packages/framework.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
# see https://symfony.com/doc/current/reference/configuration/framework.html
 | 
			
		||||
framework:
 | 
			
		||||
    secret: '%env(APP_SECRET)%'
 | 
			
		||||
    #csrf_protection: true
 | 
			
		||||
    http_method_override: false
 | 
			
		||||
    handle_all_throwables: true
 | 
			
		||||
 | 
			
		||||
    # Enables session support. Note that the session will ONLY be started if you read or write from it.
 | 
			
		||||
    # Remove or comment this section to explicitly disable session support.
 | 
			
		||||
    session:
 | 
			
		||||
        handler_id: null
 | 
			
		||||
        cookie_secure: auto
 | 
			
		||||
        cookie_samesite: lax
 | 
			
		||||
        storage_factory_id: session.storage.factory.native
 | 
			
		||||
 | 
			
		||||
    #esi: true
 | 
			
		||||
    #fragments: true
 | 
			
		||||
    php_errors:
 | 
			
		||||
        log: true
 | 
			
		||||
 | 
			
		||||
when@test:
 | 
			
		||||
    framework:
 | 
			
		||||
        test: true
 | 
			
		||||
        session:
 | 
			
		||||
            storage_factory_id: session.storage.factory.mock_file
 | 
			
		||||
							
								
								
									
										12
									
								
								config/packages/routing.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								config/packages/routing.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
framework:
 | 
			
		||||
    router:
 | 
			
		||||
        utf8: true
 | 
			
		||||
 | 
			
		||||
        # Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
 | 
			
		||||
        # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
 | 
			
		||||
        #default_uri: http://localhost
 | 
			
		||||
 | 
			
		||||
when@prod:
 | 
			
		||||
    framework:
 | 
			
		||||
        router:
 | 
			
		||||
            strict_requirements: null
 | 
			
		||||
							
								
								
									
										5
									
								
								config/preload.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								config/preload.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
 | 
			
		||||
    require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								config/routes.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								config/routes.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
controllers:
 | 
			
		||||
    resource:
 | 
			
		||||
        path: ../src/Controller/
 | 
			
		||||
        namespace: App\Controller
 | 
			
		||||
    type: attribute
 | 
			
		||||
							
								
								
									
										4
									
								
								config/routes/framework.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								config/routes/framework.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
when@dev:
 | 
			
		||||
    _errors:
 | 
			
		||||
        resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
 | 
			
		||||
        prefix: /_error
 | 
			
		||||
							
								
								
									
										24
									
								
								config/services.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								config/services.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
# This file is the entry point to configure your own services.
 | 
			
		||||
# Files in the packages/ subdirectory configure your dependencies.
 | 
			
		||||
 | 
			
		||||
# Put parameters here that don't need to change on each machine where the app is deployed
 | 
			
		||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
 | 
			
		||||
parameters:
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
    # default configuration for services in *this* file
 | 
			
		||||
    _defaults:
 | 
			
		||||
        autowire: true      # Automatically injects dependencies in your services.
 | 
			
		||||
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
 | 
			
		||||
 | 
			
		||||
    # makes classes in src/ available to be used as services
 | 
			
		||||
    # this creates a service per class whose id is the fully-qualified class name
 | 
			
		||||
    App\:
 | 
			
		||||
        resource: '../src/'
 | 
			
		||||
        exclude:
 | 
			
		||||
            - '../src/DependencyInjection/'
 | 
			
		||||
            - '../src/Entity/'
 | 
			
		||||
            - '../src/Kernel.php'
 | 
			
		||||
 | 
			
		||||
    # add more service definitions when explicit configuration is needed
 | 
			
		||||
    # please note that last definitions always *replace* previous ones
 | 
			
		||||
							
								
								
									
										28
									
								
								docker-compose.override.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								docker-compose.override.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
version: "3.4"
 | 
			
		||||
 | 
			
		||||
# Development environment override
 | 
			
		||||
services:
 | 
			
		||||
  php:
 | 
			
		||||
    build:
 | 
			
		||||
      target: app_php_dev
 | 
			
		||||
    volumes:
 | 
			
		||||
      - ./:/srv/app
 | 
			
		||||
      - ./docker/php/conf.d/app.dev.ini:/usr/local/etc/php/conf.d/app.dev.ini:ro
 | 
			
		||||
      # If you develop on Mac or Windows you can remove the vendor/ directory
 | 
			
		||||
      #  from the bind-mount for better performance by enabling the next line:
 | 
			
		||||
      #- /srv/app/vendor
 | 
			
		||||
    environment:
 | 
			
		||||
      # See https://xdebug.org/docs/all_settings#mode 
 | 
			
		||||
      XDEBUG_MODE: "${XDEBUG_MODE:-off}"
 | 
			
		||||
    extra_hosts:
 | 
			
		||||
      # Ensure that host.docker.internal is correctly defined on Linux
 | 
			
		||||
      - host.docker.internal:host-gateway
 | 
			
		||||
 | 
			
		||||
  caddy:
 | 
			
		||||
    command: ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile", "--watch"]
 | 
			
		||||
    volumes:
 | 
			
		||||
      - ./public:/srv/app/public:ro
 | 
			
		||||
      - ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
 | 
			
		||||
 | 
			
		||||
###> symfony/mercure-bundle ###
 | 
			
		||||
###< symfony/mercure-bundle ###
 | 
			
		||||
							
								
								
									
										13
									
								
								docker-compose.prod.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docker-compose.prod.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
version: "3.4"
 | 
			
		||||
 | 
			
		||||
# Production environment override
 | 
			
		||||
services:
 | 
			
		||||
  php:
 | 
			
		||||
    environment:
 | 
			
		||||
      APP_SECRET: ${APP_SECRET}
 | 
			
		||||
      MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET}
 | 
			
		||||
 | 
			
		||||
  caddy:
 | 
			
		||||
    environment:
 | 
			
		||||
      MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
 | 
			
		||||
      MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
 | 
			
		||||
							
								
								
									
										65
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
version: "3.4"
 | 
			
		||||
 | 
			
		||||
services:
 | 
			
		||||
  php:
 | 
			
		||||
    build:
 | 
			
		||||
      context: .
 | 
			
		||||
      target: app_php
 | 
			
		||||
      args:
 | 
			
		||||
        SYMFONY_VERSION: ${SYMFONY_VERSION:-}
 | 
			
		||||
        STABILITY: ${STABILITY:-stable}
 | 
			
		||||
    restart: unless-stopped
 | 
			
		||||
    volumes:
 | 
			
		||||
      - php_socket:/var/run/php
 | 
			
		||||
    healthcheck:
 | 
			
		||||
      interval: 10s
 | 
			
		||||
      timeout: 3s
 | 
			
		||||
      retries: 3
 | 
			
		||||
      start_period: 30s
 | 
			
		||||
    environment:
 | 
			
		||||
      # Run "composer require symfony/orm-pack" to install and configure Doctrine ORM
 | 
			
		||||
      DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-14}&charset=${POSTGRES_CHARSET:-utf8}
 | 
			
		||||
      # Run "composer require symfony/mercure-bundle" to install and configure the Mercure integration
 | 
			
		||||
      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:-!ChangeThisMercureHubJWTSecretKey!}
 | 
			
		||||
 | 
			
		||||
  caddy:
 | 
			
		||||
    build:
 | 
			
		||||
      context: .
 | 
			
		||||
      target: app_caddy
 | 
			
		||||
    depends_on:
 | 
			
		||||
      - php
 | 
			
		||||
    environment:
 | 
			
		||||
      SERVER_NAME: ${SERVER_NAME:-localhost, caddy:80}
 | 
			
		||||
      MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
 | 
			
		||||
      MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
 | 
			
		||||
    restart: unless-stopped
 | 
			
		||||
    volumes:
 | 
			
		||||
      - php_socket:/var/run/php
 | 
			
		||||
      - caddy_data:/data
 | 
			
		||||
      - caddy_config:/config
 | 
			
		||||
    ports:
 | 
			
		||||
      # HTTP
 | 
			
		||||
      - target: 80
 | 
			
		||||
        published: ${HTTP_PORT:-80}
 | 
			
		||||
        protocol: tcp
 | 
			
		||||
      # HTTPS
 | 
			
		||||
      - target: 443
 | 
			
		||||
        published: ${HTTPS_PORT:-443}
 | 
			
		||||
        protocol: tcp
 | 
			
		||||
      # HTTP/3
 | 
			
		||||
      - target: 443
 | 
			
		||||
        published: ${HTTP3_PORT:-443}
 | 
			
		||||
        protocol: udp
 | 
			
		||||
 | 
			
		||||
# Mercure is installed as a Caddy module, prevent the Flex recipe from installing another service
 | 
			
		||||
###> symfony/mercure-bundle ###
 | 
			
		||||
###< symfony/mercure-bundle ###
 | 
			
		||||
 | 
			
		||||
volumes:
 | 
			
		||||
  php_socket:
 | 
			
		||||
  caddy_data:
 | 
			
		||||
  caddy_config:
 | 
			
		||||
###> symfony/mercure-bundle ###
 | 
			
		||||
###< symfony/mercure-bundle ###
 | 
			
		||||
							
								
								
									
										32
									
								
								docker/caddy/Caddyfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								docker/caddy/Caddyfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
{
 | 
			
		||||
    # Debug
 | 
			
		||||
    {$CADDY_DEBUG}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
{$SERVER_NAME}
 | 
			
		||||
 | 
			
		||||
{$CADDY_EXTRA_CONFIG}
 | 
			
		||||
 | 
			
		||||
log
 | 
			
		||||
 | 
			
		||||
route {
 | 
			
		||||
    root * /srv/app/public
 | 
			
		||||
    mercure {
 | 
			
		||||
        # Transport to use (default to Bolt)
 | 
			
		||||
        transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}
 | 
			
		||||
        # Publisher JWT key
 | 
			
		||||
        publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
 | 
			
		||||
        # Subscriber JWT key
 | 
			
		||||
        subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
 | 
			
		||||
        # Allow anonymous subscribers (double-check that it's what you want)
 | 
			
		||||
        anonymous
 | 
			
		||||
        # Enable the subscription API (double-check that it's what you want)
 | 
			
		||||
        subscriptions
 | 
			
		||||
        # Extra directives
 | 
			
		||||
        {$MERCURE_EXTRA_DIRECTIVES}
 | 
			
		||||
    }
 | 
			
		||||
    vulcain
 | 
			
		||||
    php_fastcgi unix//var/run/php/php-fpm.sock
 | 
			
		||||
    encode zstd gzip
 | 
			
		||||
    file_server
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								docker/php/conf.d/app.dev.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								docker/php/conf.d/app.dev.ini
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
; See https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host
 | 
			
		||||
; See https://github.com/docker/for-linux/issues/264
 | 
			
		||||
; The `client_host` below may optionally be replaced with `discover_client_host=yes`
 | 
			
		||||
; Add `start_with_request=yes` to start debug session on each request
 | 
			
		||||
xdebug.client_host = 'host.docker.internal'
 | 
			
		||||
							
								
								
									
										13
									
								
								docker/php/conf.d/app.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docker/php/conf.d/app.ini
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
expose_php = 0
 | 
			
		||||
date.timezone = UTC
 | 
			
		||||
apc.enable_cli = 1
 | 
			
		||||
session.use_strict_mode = 1
 | 
			
		||||
zend.detect_unicode = 0
 | 
			
		||||
 | 
			
		||||
; https://symfony.com/doc/current/performance.html
 | 
			
		||||
realpath_cache_size = 4096K
 | 
			
		||||
realpath_cache_ttl = 600
 | 
			
		||||
opcache.interned_strings_buffer = 16
 | 
			
		||||
opcache.max_accelerated_files = 20000
 | 
			
		||||
opcache.memory_consumption = 256
 | 
			
		||||
opcache.enable_file_override = 1
 | 
			
		||||
							
								
								
									
										2
									
								
								docker/php/conf.d/app.prod.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								docker/php/conf.d/app.prod.ini
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
opcache.preload_user = www-data
 | 
			
		||||
opcache.preload = /srv/app/config/preload.php
 | 
			
		||||
							
								
								
									
										68
									
								
								docker/php/docker-entrypoint.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										68
									
								
								docker/php/docker-entrypoint.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
# first arg is `-f` or `--some-option`
 | 
			
		||||
if [ "${1#-}" != "$1" ]; then
 | 
			
		||||
	set -- php-fpm "$@"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then
 | 
			
		||||
	# Install the project the first time PHP is started
 | 
			
		||||
	# After the installation, the following block can be deleted
 | 
			
		||||
	if [ ! -f composer.json ]; then
 | 
			
		||||
		CREATION=1
 | 
			
		||||
 | 
			
		||||
		rm -Rf tmp/
 | 
			
		||||
		composer create-project "symfony/skeleton $SYMFONY_VERSION" tmp --stability="$STABILITY" --prefer-dist --no-progress --no-interaction --no-install
 | 
			
		||||
 | 
			
		||||
		cd tmp
 | 
			
		||||
		composer require "php:>=$PHP_VERSION"
 | 
			
		||||
		composer config --json extra.symfony.docker 'true'
 | 
			
		||||
		cp -Rp . ..
 | 
			
		||||
		cd -
 | 
			
		||||
 | 
			
		||||
		rm -Rf tmp/
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if [ "$APP_ENV" != 'prod' ]; then
 | 
			
		||||
		composer install --prefer-dist --no-progress --no-interaction
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if grep -q ^DATABASE_URL= .env; then
 | 
			
		||||
		# After the installation, the following block can be deleted
 | 
			
		||||
		if [ "$CREATION" = "1" ]; then
 | 
			
		||||
			echo "To finish the installation please press Ctrl+C to stop Docker Compose and run: docker compose up --build"
 | 
			
		||||
			sleep infinity
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		echo "Waiting for db to be ready..."
 | 
			
		||||
		ATTEMPTS_LEFT_TO_REACH_DATABASE=60
 | 
			
		||||
		until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(bin/console dbal:run-sql "SELECT 1" 2>&1); do
 | 
			
		||||
			if [ $? -eq 255 ]; then
 | 
			
		||||
				# If the Doctrine command exits with 255, an unrecoverable error occurred
 | 
			
		||||
				ATTEMPTS_LEFT_TO_REACH_DATABASE=0
 | 
			
		||||
				break
 | 
			
		||||
			fi
 | 
			
		||||
			sleep 1
 | 
			
		||||
			ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1))
 | 
			
		||||
			echo "Still waiting for db to be ready... Or maybe the db is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left"
 | 
			
		||||
		done
 | 
			
		||||
 | 
			
		||||
		if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then
 | 
			
		||||
			echo "The database is not up or not reachable:"
 | 
			
		||||
			echo "$DATABASE_ERROR"
 | 
			
		||||
			exit 1
 | 
			
		||||
		else
 | 
			
		||||
			echo "The db is now ready and reachable"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then
 | 
			
		||||
			bin/console doctrine:migrations:migrate --no-interaction
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var
 | 
			
		||||
	setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
exec docker-php-entrypoint "$@"
 | 
			
		||||
							
								
								
									
										8
									
								
								docker/php/docker-healthcheck.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docker/php/docker-healthcheck.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
if env -i REQUEST_METHOD=GET SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping cgi-fcgi -bind -connect /var/run/php/php-fpm.sock; then
 | 
			
		||||
	exit 0
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
exit 1
 | 
			
		||||
							
								
								
									
										8
									
								
								docker/php/php-fpm.d/zz-docker.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docker/php/php-fpm.d/zz-docker.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
[global]
 | 
			
		||||
daemonize = no
 | 
			
		||||
process_control_timeout = 20
 | 
			
		||||
 | 
			
		||||
[www]
 | 
			
		||||
listen = /var/run/php/php-fpm.sock
 | 
			
		||||
listen.mode = 0666
 | 
			
		||||
ping.path = /ping
 | 
			
		||||
							
								
								
									
										49
									
								
								docs/build.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								docs/build.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
# Build Options
 | 
			
		||||
 | 
			
		||||
## Selecting a Specific Symfony Version
 | 
			
		||||
 | 
			
		||||
Use the `SYMFONY_VERSION` environment variable to select a specific Symfony version.
 | 
			
		||||
 | 
			
		||||
For instance, use the following command to install Symfony 5.4:
 | 
			
		||||
 | 
			
		||||
On Linux:
 | 
			
		||||
 | 
			
		||||
    SYMFONY_VERSION=5.4.* docker compose up --build
 | 
			
		||||
On Windows:
 | 
			
		||||
 | 
			
		||||
    set SYMFONY_VERSION=5.4.*&& docker compose up --build&set SYMFONY_VERSION=
 | 
			
		||||
 | 
			
		||||
## Installing Development Versions of Symfony
 | 
			
		||||
 | 
			
		||||
To install a non-stable version of Symfony, use the `STABILITY` environment variable during the build.
 | 
			
		||||
The value must be [a valid Composer stability option](https://getcomposer.org/doc/04-schema.md#minimum-stability).
 | 
			
		||||
 | 
			
		||||
For instance, use the following command to use the development branch of Symfony:
 | 
			
		||||
 | 
			
		||||
On Linux:
 | 
			
		||||
 | 
			
		||||
    STABILITY=dev docker compose up --build
 | 
			
		||||
On Windows:
 | 
			
		||||
    
 | 
			
		||||
    set STABILITY=dev&& docker compose up --build&set STABILITY=
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
## Customizing the Server Name
 | 
			
		||||
 | 
			
		||||
Use the `SERVER_NAME` environment variable to define your custom server name(s).
 | 
			
		||||
 | 
			
		||||
    SERVER_NAME="app.localhost, caddy:80" docker compose up --build
 | 
			
		||||
 | 
			
		||||
If you use Mercure, keep `caddy:80` in the list to allow the PHP container to request the caddy service.
 | 
			
		||||
 | 
			
		||||
*Tips: You can define your server name variable in your `.env` file to keep it at each up*
 | 
			
		||||
 | 
			
		||||
## Using custom HTTP ports
 | 
			
		||||
 | 
			
		||||
Use the environment variables `HTTP_PORT`, `HTTPS_PORT` and/or `HTTP3_PORT` to adjust the ports to your needs, e.g.
 | 
			
		||||
 | 
			
		||||
    HTTP_PORT=8000 HTTPS_PORT=4443 HTTP3_PORT=4443 docker compose up --build
 | 
			
		||||
 | 
			
		||||
to access your application on [https://localhost:4443](https://localhost:4443).
 | 
			
		||||
 | 
			
		||||
*Note: Let's Encrypt only supports the standard HTTP and HTTPS ports. Creating a Let's Encrypt certificate for another port will not work, you have to use the standard ports or to configure Caddy to use another provider.*
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/digitalocean-droplet.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/digitalocean-droplet.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 248 KiB  | 
							
								
								
									
										33
									
								
								docs/existing-project.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								docs/existing-project.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
# Installing on an Existing Project
 | 
			
		||||
 | 
			
		||||
It's also possible to use Symfony Docker with existing projects!
 | 
			
		||||
 | 
			
		||||
First, [download this skeleton](https://github.com/dunglas/symfony-docker). If you clone the Git repository, be sure to remove the `.git` directory to prevent conflicts with the `.git` directory already in your existing project.
 | 
			
		||||
 | 
			
		||||
Then, copy the Docker-related files from the skeleton to your existing project:
 | 
			
		||||
 | 
			
		||||
    cp -Rp symfony-docker/. my-existing-project/
 | 
			
		||||
 | 
			
		||||
Enable the Docker support of Symfony Flex:
 | 
			
		||||
 | 
			
		||||
    composer config --json extra.symfony.docker 'true'
 | 
			
		||||
 | 
			
		||||
Re-execute the recipes to update the Docker-related files according to the packages you use
 | 
			
		||||
 | 
			
		||||
    rm symfony.lock
 | 
			
		||||
    composer symfony:sync-recipes --force --verbose
 | 
			
		||||
 | 
			
		||||
Double-check the changes, revert the changes that you don't want to keep:
 | 
			
		||||
 | 
			
		||||
    git diff
 | 
			
		||||
    ...
 | 
			
		||||
 | 
			
		||||
Build the Docker images:
 | 
			
		||||
 | 
			
		||||
    docker compose build --no-cache --pull
 | 
			
		||||
 | 
			
		||||
Start the project!
 | 
			
		||||
 | 
			
		||||
    docker compose up -d
 | 
			
		||||
 | 
			
		||||
Browse `https://localhost`, your Docker configuration is ready!
 | 
			
		||||
							
								
								
									
										12
									
								
								docs/extra-services.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								docs/extra-services.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
# Support for Extra Services
 | 
			
		||||
 | 
			
		||||
Symfony Docker is extensible. When you install a compatible Composer package using Symfony Flex,
 | 
			
		||||
the recipe will automatically modify the `Dockerfile` and `docker-compose.yml` to fulfill the requirements of this package.
 | 
			
		||||
 | 
			
		||||
The currently supported packages are:
 | 
			
		||||
 | 
			
		||||
* `symfony/orm-pack`: install a PostgreSQL service
 | 
			
		||||
* `symfony/mercure-bundle`: use the Mercure.rocks module shipped with Caddy
 | 
			
		||||
* `symfony/panther`: install chromium and these drivers
 | 
			
		||||
* `symfony/mailer`: install a MailCatcher service
 | 
			
		||||
* `blackfireio/blackfire-symfony-meta`: install a Blackfire service
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/gandi-dns.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/gandi-dns.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 139 KiB  | 
							
								
								
									
										90
									
								
								docs/makefile.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								docs/makefile.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
# Makefile
 | 
			
		||||
 | 
			
		||||
Here is a Makefile template. It provides some shortcuts for the most common tasks.
 | 
			
		||||
To use it, create a new `Makefile` file at the root of your project. Copy/paste
 | 
			
		||||
the content in the template section. To view all the available commands, run `make`.
 | 
			
		||||
 | 
			
		||||
For example, in the [getting started section](/README.md#getting-started), the
 | 
			
		||||
`docker compose` commands could be replaced by:
 | 
			
		||||
 | 
			
		||||
1. Run `make build` to build fresh images
 | 
			
		||||
2. Run `make up` (detached mode without logs)
 | 
			
		||||
3. Run `make down` to stop the Docker containers
 | 
			
		||||
 | 
			
		||||
Of course, this template is basic for now. But, as your application is growing,
 | 
			
		||||
you will probably want to add some targets like running your tests as described
 | 
			
		||||
in [the Symfony book](https://symfony.com/doc/current/the-fast-track/en/17-tests.html#automating-your-workflow-with-a-makefile).
 | 
			
		||||
You can also find a more complete example in this [snippet](https://www.strangebuzz.com/en/snippets/the-perfect-makefile-for-symfony).
 | 
			
		||||
 | 
			
		||||
If you want to run make from within the `php` container, in the [Dockerfile](/Dockerfile),
 | 
			
		||||
add:
 | 
			
		||||
 | 
			
		||||
```diff
 | 
			
		||||
gettext \
 | 
			
		||||
git \
 | 
			
		||||
+make \
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
And rebuild the PHP image.
 | 
			
		||||
 | 
			
		||||
**PS**: If using Windows, you have to install [chocolatey.org](https://chocolatey.org/)
 | 
			
		||||
or use [Cygwin](http://cygwin.com) to use the `make` command. Check out this
 | 
			
		||||
[StackOverflow question](https://stackoverflow.com/q/2532234/633864) for more explanations.
 | 
			
		||||
 | 
			
		||||
## The template
 | 
			
		||||
 | 
			
		||||
```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_CONT) bin/console
 | 
			
		||||
 | 
			
		||||
# Misc
 | 
			
		||||
.DEFAULT_GOAL = help
 | 
			
		||||
.PHONY        : help build up start down logs sh composer vendor sf cc
 | 
			
		||||
 | 
			
		||||
## —— 🎵 🐳 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 PHP FPM container
 | 
			
		||||
	@$(PHP_CONT) sh
 | 
			
		||||
 | 
			
		||||
## —— 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
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										104
									
								
								docs/production.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								docs/production.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
# Deploying in Production
 | 
			
		||||
 | 
			
		||||
Symfony Docker provides Docker images, and a Docker Compose definition optimized for production usage.
 | 
			
		||||
In this tutorial, we will learn how to deploy our Symfony application on a single server using Docker Compose.
 | 
			
		||||
 | 
			
		||||
## Preparing a Server
 | 
			
		||||
 | 
			
		||||
To deploy your application in production, you need a server.
 | 
			
		||||
In this tutorial we will use a virtual machine provided by DigitalOcean, but any Linux server can work.
 | 
			
		||||
If you already have a Linux server with Docker Compose installed, you can skip straight to [the next section](#configuring-a-domain-name).
 | 
			
		||||
 | 
			
		||||
Otherwise, use [this affiliate link](https://m.do.co/c/5d8aabe3ab80) to get $100 of free credit, create an account, then click on "Create a Droplet".
 | 
			
		||||
Then, click on the "Marketplace" tab under the "Choose an image" section and search for the app named "Docker".
 | 
			
		||||
This will provision an Ubuntu server with the latest versions of Docker and Docker Compose already installed!
 | 
			
		||||
 | 
			
		||||
To test, the cheapest plan will be enough, but for real production usage you'll probably want to pick a plan in the "general purpose" section that will fit your needs.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
You can keep the defaults for other settings, or tweak them according to your needs.
 | 
			
		||||
Don't forget to add your SSH key or to create a password then press the "Finalize and create" button.
 | 
			
		||||
 | 
			
		||||
Then, wait a few seconds while your Droplet is provisioning.
 | 
			
		||||
When your Droplet is ready, use SSH to connect:
 | 
			
		||||
 | 
			
		||||
```console
 | 
			
		||||
ssh root@<droplet-ip>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Configuring a Domain Name
 | 
			
		||||
 | 
			
		||||
In most cases, you'll want to associate a domain name to your website.
 | 
			
		||||
If you don't own a domain name yet, you'll have to buy one through a registrar.
 | 
			
		||||
Use [this affiliate link](https://gandi.link/f/93650337) to redeem a 20% discount at Gandi.net.
 | 
			
		||||
 | 
			
		||||
Then create a DNS record of type `A` for your domain name pointing to the IP address of your server.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```dns
 | 
			
		||||
your-domain-name.example.com.  IN  A     207.154.233.113
 | 
			
		||||
````
 | 
			
		||||
 | 
			
		||||
Example in Gandi's UI:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Note: Let's Encrypt, the service used by default by Symfony Docker to automatically generate a TLS certificate doesn't support using bare IP addresses.
 | 
			
		||||
Using a domain name is mandatory to use Let's Encrypt.
 | 
			
		||||
 | 
			
		||||
## Deploying
 | 
			
		||||
 | 
			
		||||
Copy your project on the server using `git clone`, `scp` or any other tool that may fit your need.
 | 
			
		||||
If you use GitHub, you may want to use [a deploy key](https://docs.github.com/en/free-pro-team@latest/developers/overview/managing-deploy-keys#deploy-keys).
 | 
			
		||||
Deploy keys are also [supported by GitLab](https://docs.gitlab.com/ee/user/project/deploy_keys/). 
 | 
			
		||||
 | 
			
		||||
Example with Git:
 | 
			
		||||
 | 
			
		||||
```console
 | 
			
		||||
git clone git@github.com:<username>/<project-name>.git
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Go into the directory containing your project (`<project-name>`), and start the app in production mode:
 | 
			
		||||
 | 
			
		||||
```console
 | 
			
		||||
SERVER_NAME=your-domain-name.example.com \
 | 
			
		||||
APP_SECRET=ChangeMe \
 | 
			
		||||
CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \
 | 
			
		||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Be sure to replace `your-domain-name.example.com` by your actual domain name and to set the values of `APP_SECRET`, `CADDY_MERCURE_JWT_SECRET` to cryptographically secure random values.
 | 
			
		||||
 | 
			
		||||
Your server is up and running, and a Let's Encrypt HTTPS certificate has been automatically generated for you.
 | 
			
		||||
Go to `https://your-domain-name.example.com` and enjoy!
 | 
			
		||||
 | 
			
		||||
## Disabling HTTPS
 | 
			
		||||
 | 
			
		||||
Alternatively, if you don't want to expose an HTTPS server but only an HTTP one, run the following command:
 | 
			
		||||
 | 
			
		||||
```console
 | 
			
		||||
SERVER_NAME=:80 \
 | 
			
		||||
APP_SECRET=ChangeMe \
 | 
			
		||||
CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \
 | 
			
		||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Deploying on Multiple Nodes
 | 
			
		||||
 | 
			
		||||
If you want to deploy your app on a cluster of machines, you can use [Docker Swarm](https://docs.docker.com/engine/swarm/stack-deploy/),
 | 
			
		||||
which is compatible with the provided Compose files.
 | 
			
		||||
 | 
			
		||||
## Configuring a Load Balancer or a Reverse Proxy
 | 
			
		||||
 | 
			
		||||
Since Caddy 2.5, XFF values of incoming requests will be ignored to prevent spoofing.
 | 
			
		||||
So if Caddy is not the first server being connected to by your clients (for example when a CDN is in front of Caddy), you may configure `trusted_proxies` with a list of IP ranges (CIDRs) from which incoming requests are trusted to have sent good values for these headers.
 | 
			
		||||
As a shortcut, `private_ranges` may be configured to trust all private IP ranges.
 | 
			
		||||
 | 
			
		||||
```diff
 | 
			
		||||
-php_fastcgi unix//var/run/php/php-fpm.sock
 | 
			
		||||
+php_fastcgi unix//var/run/php/php-fpm.sock {
 | 
			
		||||
+    trusted_proxies private_ranges
 | 
			
		||||
+}
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										38
									
								
								docs/tls.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								docs/tls.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
# TLS Certificates
 | 
			
		||||
 | 
			
		||||
## Trusting the Authority
 | 
			
		||||
 | 
			
		||||
With a standard installation, the authority used to sign certificates generated in the Caddy container is not trusted by your local machine.
 | 
			
		||||
You must add the authority to the trust store of the host :
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
# Mac
 | 
			
		||||
$ docker cp $(docker compose ps -q caddy):/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
 | 
			
		||||
# Linux
 | 
			
		||||
$ docker cp $(docker compose ps -q caddy):/data/caddy/pki/authorities/local/root.crt /usr/local/share/ca-certificates/root.crt && sudo update-ca-certificates
 | 
			
		||||
# Windows
 | 
			
		||||
$ docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt %TEMP%/root.crt && certutil -addstore -f "ROOT" %TEMP%/root.crt
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Using Custom TLS Certificates
 | 
			
		||||
 | 
			
		||||
By default, Caddy will automatically generate TLS certificates using Let's Encrypt or ZeroSSL.
 | 
			
		||||
But sometimes you may prefer using custom certificates.
 | 
			
		||||
 | 
			
		||||
For instance, to use self-signed certificates created with [mkcert](https://github.com/FiloSottile/mkcert) do as follows:
 | 
			
		||||
 | 
			
		||||
1. Locally install `mkcert`
 | 
			
		||||
2. Create the folder storing the certs: 
 | 
			
		||||
   `mkdir docker/caddy/certs -p`
 | 
			
		||||
3. Generate the certificates for your local host (example: "server-name.localhost"):
 | 
			
		||||
   `mkcert -cert-file docker/caddy/certs/tls.pem -key-file docker/caddy/certs/tls.key "server-name.localhost"`
 | 
			
		||||
4. Add these lines to the `./docker-compose.override.yml` file about `CADDY_EXTRA_CONFIG` environment and volume for the `caddy` service :
 | 
			
		||||
    ```diff
 | 
			
		||||
    caddy:
 | 
			
		||||
    +  environment:
 | 
			
		||||
    +    CADDY_EXTRA_CONFIG: "tls /etc/caddy/certs/tls.pem /etc/caddy/certs/tls.key"
 | 
			
		||||
      volumes:
 | 
			
		||||
    +    - ./docker/caddy/certs:/etc/caddy/certs:ro
 | 
			
		||||
        - ./public:/srv/app/public:ro
 | 
			
		||||
    ```
 | 
			
		||||
5. Restart your `caddy` container
 | 
			
		||||
							
								
								
									
										14
									
								
								docs/troubleshooting.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								docs/troubleshooting.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
# Troubleshooting
 | 
			
		||||
 | 
			
		||||
## Editing Permissions on Linux
 | 
			
		||||
 | 
			
		||||
If you work on linux and cannot edit some of the project files right after the first installation, you can run `docker compose run --rm php chown -R $(id -u):$(id -g) .` to set yourself as owner of the project files that were created by the docker container.
 | 
			
		||||
 | 
			
		||||
## HTTPs and Redirects
 | 
			
		||||
 | 
			
		||||
If Symfony is generating an internal redirect for an `https://` url, but the resulting url is `http://`, you have to uncomment the `TRUSTED_PROXIES` setting in your `.env` file.
 | 
			
		||||
For more details see the [Symfony internal redirect documentation](https://symfony.com/doc/current/routing.html#redirecting-to-urls-and-routes-directly-from-a-route).
 | 
			
		||||
 | 
			
		||||
## TLS/HTTPS Issues
 | 
			
		||||
 | 
			
		||||
See more in the [TLS section](tls.md)
 | 
			
		||||
							
								
								
									
										58
									
								
								docs/xdebug.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								docs/xdebug.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
# Using Xdebug
 | 
			
		||||
 | 
			
		||||
The default development image is shipped with [Xdebug](https://xdebug.org/),
 | 
			
		||||
a popular debugger and profiler for PHP.
 | 
			
		||||
 | 
			
		||||
Because it has a significant performance overhead, the step-by-step debugger is disabled by default.
 | 
			
		||||
It can be enabled by setting the `XDEBUG_MODE` environment variable to `debug`.
 | 
			
		||||
 | 
			
		||||
On Linux and Mac:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
XDEBUG_MODE=debug docker compose up -d
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
On Windows:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
set XDEBUG_MODE=debug&& docker compose up -d&set XDEBUG_MODE=
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Debugging with Xdebug and PHPStorm
 | 
			
		||||
 | 
			
		||||
First, [create a PHP debug remote server configuration](https://www.jetbrains.com/help/phpstorm/creating-a-php-debug-server-configuration.html):
 | 
			
		||||
 | 
			
		||||
1. In the `Settings/Preferences` dialog, go to `PHP | Servers`
 | 
			
		||||
2. Create a new server:
 | 
			
		||||
   * Name: `symfony` (or whatever you want to use for the variable `PHP_IDE_CONFIG`)
 | 
			
		||||
   * Host: `localhost` (or the one defined using the `SERVER_NAME` environment variable)
 | 
			
		||||
   * Port: `443`
 | 
			
		||||
   * Debugger: `Xdebug`
 | 
			
		||||
   * Check `Use path mappings`
 | 
			
		||||
   * Absolute path on the server: `/srv/app`
 | 
			
		||||
 | 
			
		||||
You can now use the debugger!
 | 
			
		||||
 | 
			
		||||
1. In PHPStorm, open the `Run` menu and click on `Start Listening for PHP Debug Connections`
 | 
			
		||||
2. Add the `XDEBUG_SESSION=PHPSTORM` query parameter to the URL of the page you want to debug, or use [other available triggers](https://xdebug.org/docs/step_debug#activate_debugger)
 | 
			
		||||
 | 
			
		||||
    Alternatively, you can use [the **Xdebug extension**](https://xdebug.org/docs/step_debug#browser-extensions) for your preferred web browser. 
 | 
			
		||||
 | 
			
		||||
3. On command line, we might need to tell PHPStorm which [path mapping configuration](https://www.jetbrains.com/help/phpstorm/zero-configuration-debugging-cli.html#configure-path-mappings) should be used, set the value of the PHP_IDE_CONFIG environment variable to `serverName=symfony`, where `symfony` is the name of the debug server configured higher.
 | 
			
		||||
 | 
			
		||||
    Example:
 | 
			
		||||
 | 
			
		||||
    ```console
 | 
			
		||||
    XDEBUG_SESSION=1 PHP_IDE_CONFIG="serverName=symfony" php bin/console ...
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
## Troubleshooting
 | 
			
		||||
 | 
			
		||||
Inspect the installation with the following command. The Xdebug version should be displayed.
 | 
			
		||||
 | 
			
		||||
```console
 | 
			
		||||
$ docker compose exec php php --version
 | 
			
		||||
 | 
			
		||||
PHP ...
 | 
			
		||||
    with Xdebug v3.x.x ...
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										0
									
								
								public/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								public/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										9
									
								
								public/index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								public/index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use App\Kernel;
 | 
			
		||||
 | 
			
		||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
 | 
			
		||||
 | 
			
		||||
return function (array $context) {
 | 
			
		||||
    return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										0
									
								
								src/Controller/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/Controller/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										11
									
								
								src/Kernel.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/Kernel.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App;
 | 
			
		||||
 | 
			
		||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
 | 
			
		||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
 | 
			
		||||
 | 
			
		||||
class Kernel extends BaseKernel
 | 
			
		||||
{
 | 
			
		||||
    use MicroKernelTrait;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								symfony.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								symfony.lock
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
{
 | 
			
		||||
    "symfony/console": {
 | 
			
		||||
        "version": "6.2",
 | 
			
		||||
        "recipe": {
 | 
			
		||||
            "repo": "github.com/symfony/recipes",
 | 
			
		||||
            "branch": "main",
 | 
			
		||||
            "version": "5.3",
 | 
			
		||||
            "ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
 | 
			
		||||
        },
 | 
			
		||||
        "files": [
 | 
			
		||||
            "bin/console"
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "symfony/flex": {
 | 
			
		||||
        "version": "2.2",
 | 
			
		||||
        "recipe": {
 | 
			
		||||
            "repo": "github.com/symfony/recipes",
 | 
			
		||||
            "branch": "main",
 | 
			
		||||
            "version": "1.0",
 | 
			
		||||
            "ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
 | 
			
		||||
        },
 | 
			
		||||
        "files": [
 | 
			
		||||
            ".env"
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "symfony/framework-bundle": {
 | 
			
		||||
        "version": "6.2",
 | 
			
		||||
        "recipe": {
 | 
			
		||||
            "repo": "github.com/symfony/recipes",
 | 
			
		||||
            "branch": "main",
 | 
			
		||||
            "version": "6.2",
 | 
			
		||||
            "ref": "af47254c5e4cd543e6af3e4508298ffebbdaddd3"
 | 
			
		||||
        },
 | 
			
		||||
        "files": [
 | 
			
		||||
            "config/packages/cache.yaml",
 | 
			
		||||
            "config/packages/framework.yaml",
 | 
			
		||||
            "config/preload.php",
 | 
			
		||||
            "config/routes/framework.yaml",
 | 
			
		||||
            "config/services.yaml",
 | 
			
		||||
            "public/index.php",
 | 
			
		||||
            "src/Controller/.gitignore",
 | 
			
		||||
            "src/Kernel.php"
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "symfony/routing": {
 | 
			
		||||
        "version": "6.2",
 | 
			
		||||
        "recipe": {
 | 
			
		||||
            "repo": "github.com/symfony/recipes",
 | 
			
		||||
            "branch": "main",
 | 
			
		||||
            "version": "6.2",
 | 
			
		||||
            "ref": "e0a11b4ccb8c9e70b574ff5ad3dfdcd41dec5aa6"
 | 
			
		||||
        },
 | 
			
		||||
        "files": [
 | 
			
		||||
            "config/packages/routing.yaml",
 | 
			
		||||
            "config/routes.yaml"
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user