├── .dockerignore ├── .env.sample ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── docker-compose.yaml ├── docker ├── caddy │ ├── Caddyfile │ └── Dockerfile ├── php-fpm │ ├── Dockerfile │ └── entrypoint.sh └── phpmyadmin │ └── Dockerfile └── run.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | # https://github.com/dunglas/symfony-docker/blob/main/.dockerignore 2 | 3 | **/*.log 4 | **/*.md 5 | **/*.php~ 6 | **/._* 7 | **/.dockerignore 8 | **/.DS_Store 9 | **/.git/ 10 | **/.gitattributes 11 | **/.gitignore 12 | **/.gitmodules 13 | **/docker-compose.*.yaml 14 | **/docker-compose.*.yml 15 | **/docker-compose.yaml 16 | **/docker-compose.yml 17 | **/Dockerfile 18 | **/Thumbs.db 19 | .editorconfig 20 | .env.*.local 21 | .env.local 22 | .env.local.php 23 | .php_cs.cache 24 | bin/* 25 | !bin/console 26 | public/bundles/ 27 | var/ 28 | vendor/ 29 | run.sh 30 | LICENSE 31 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | # SYMFONY (Defaults => SYMFONY_VERSION : Last version | PORT_SYMFONY : 443) 2 | SYMFONY_VERSION= 3 | 4 | # DATABASE (Default => MYSQL_DATABASE : symfony) 5 | MYSQL_DATABASE= 6 | 7 | # DATABASE AND PHPMYADMIN (Defaults => MYSQL_ROOT_PASSWORD : symfony | MYSQL_USER : symfony | MYSQL_PASSWORD: symfony) 8 | MYSQL_ROOT_PASSWORD= 9 | MYSQL_USER= 10 | MYSQL_PASSWORD= 11 | 12 | # VERSIONS (Defaults => PHP_VERSION : 8 | MARIADB_VERSION : 10) 13 | MARIADB_VERSION= 14 | PHP_VERSION= 15 | 16 | # COMMENT THIS LINE IF NOT NEEDED 17 | DATABASE_URL=mysql://${MYSQL_USER:-symfony}:${MYSQL_PASSWORD:-symfony}@database/${MYSQL_DATABASE:-symfony}?serverVersion=mariadb-${MARIADB_VERSION:-10}&charset=utf8 # DO NOT TOUCH 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI Symfony Website Docker 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | build: 9 | name: Docker build 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | - name: Copy .env.sample to .env 15 | run: cp .env.sample .env 16 | - name: Pull images 17 | run: docker-compose pull 18 | - uses: satackey/action-docker-layer-caching@v0.0.11 19 | continue-on-error: true 20 | - name: Start services 21 | run: ./run.sh --build -d 22 | - name: Check Symfony HTTPS reachability 23 | run: curl -k https://localhost 24 | - name: Check phpMyAdmin reachability 25 | run: curl -k https://localhost:8888 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | out 4 | gen 5 | 6 | .env 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Théo Frison 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # I created [another project](https://github.com/Arkanii/symfovite) with all knowledge I learned on working on this project. I will focus on this one so I set this repository read-only. 2 | 3 | # Symfony Website Docker 4 | 5 | I learned Docker with [this](https://github.com/dunglas/symfony-docker) project, and I try to implement my own logic into this one. 6 | 7 | All your Symfony development environment in **HTTPS** with only 1 command ! :sunglasses: :exploding_head: 8 | 9 | ## Getting Started 10 | 11 | 1. If not already done, [install Docker Compose](https://docs.docker.com/compose/install/) 12 | 2. Copy `.env.sample` to `.env` and complete the information 13 | 3. Run `./run.sh -d` (or `./run.sh` to see all logs), it will create the [Symfony website skeleton](https://github.com/symfony/website-skeleton) automatically for you (it can take 1 or 2 minutes) 14 | 4. Open [https://localhost](https://localhost) in your favorite web browser and [accept the auto-generated TLS certificate](https://stackoverflow.com/a/15076602/1352334) 15 | 5. Let's code your Symfony website ! :tada: :man_technologist: :woman_technologist: 16 | 6. Open [https://localhost:8888](https://localhost:8888) to access to your phpMyAdmin 17 | 18 | _(All those localhost links are valid if you let the .env by default.)_ 19 | 20 | ## Whats's inside ? :monocle_face: 21 | 22 | - [Caddy](https://caddyserver.com/v2) 23 | - PHP-FPM 24 | - MariaDB 25 | - phpMyAdmin 26 | 27 | 28 | ## Variables available 29 | 30 | ### Database & phpMyAdmin 31 | 32 | - `MARIADB_VERSION` : Version of MariaDB. (Default: 10) 33 | - `MYSQL_DATABASE` : Name of the database. (Default: `symfony`) 34 | - `MYSQL_ROOT_PASSWORD` : Root's password. Please use a strong password. (Default: `symfony`) 35 | - `MYSQL_USER` : Name of the user. (Default: `symfony`) 36 | - `MYSQL_PASSWORD` : User's password. Please use a strong password. (Default: `symfony`) 37 | - `PORT_PHPMYADMIN` : Port used for browser ([https://localhost:8888](https://localhost:8888) for example). (Default: 8888) 38 | 39 | ### PHP & Symfony 40 | 41 | - `PHP_VERSION` : PHP version. (Default: 8) 42 | - `SYMFONY_VERSION` : Version of Symfony. 43 | - `PORT_SYMFONY` : Port used for browser ([https://localhost:443](https://localhost:443) for example). (Default: 443) 44 | 45 | ### GIT (If you want to use an existing Symfony project) 46 | 47 | - `CUSTOM_REPOSITORY` : Link of your git repository (git@github.com:Arkanii/symfony-website-docker.git or https://github.com/Arkanii/symfony-website-docker.git for example). 48 | - `CUSTOM_REPOSITORY_WITH_GIT_DIR` : If set to 1, this will replace the .git directory of the template by the .git directory located into the project located in the `CUSTOM_REPOSITORY` variable. (Default: 0) 49 | - `SSH_KEY_PATH` : Path of your SSH key. 50 | 51 | ### Others 52 | 53 | - `TIMEZONE` : Timezone to set the correct time on the containers. 54 | 55 | ## Q&A 56 | 57 | ### Why use a run.sh into this template ? 58 | 59 | Symfony uses [the .env file](https://symfony.com/doc/current/configuration.html#config-dot-env). 60 | Into their best practices, Symfony asks to [use environment variables](https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration) 61 | for obvious security reasons so as not to commit environment variables or passwords. 62 | 63 | However, Docker uses the .env file too, witch needs this file to get these secrets variables which are stored in .env.local file. 64 | That's why I created a `run.sh` in order to grab this information and run them into Symfony and Docker at the same time. 65 | 66 | This script is also used to avoid permissions issues between files that are on your computer, and those that are in the Docker service. 67 | 68 | If anyone has a better idea to avoid this file, don't hesitate to open a ticket ! 69 | 70 | ### Can I use [Symfony CLI](https://symfony.com/doc/current/setup/symfony_server.html) into my project when docker-compose is lunched ? 71 | 72 | Of course, you can ! 73 | Just lunch `symfony serve` after `./run.sh -d` and open [https://127.0.0.1:8000](https://127.0.0.1:8000). (by default) 74 | 75 | If you decide to not use Symfony CLI, you need to explain the exact version of [MariaDB](https://hub.docker.com/_/mariadb) you used in the `MARIADB_VERSION` variable. 76 | 77 | ### My web browser block my custom port ! 78 | 79 | Check these links and look if your custom port is not reserved by your web browser. 80 | 81 | - Restricted ports from Chrome : [here](https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/net/base/port_util.cc#68) 82 | - Restricted ports from Mozilla : [here](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist) 83 | 84 | ## Credits 85 | 86 | Created by Théo Frison, inspired and taken for some parts from [this project](https://github.com/dunglas/symfony-docker). 87 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | caddy: 3 | build: 4 | context: docker/caddy 5 | restart: unless-stopped 6 | ports: 7 | - "${PORT_SYMFONY:-443}:${PORT_SYMFONY:-443}" 8 | - "${PORT_PHPMYADMIN:-8888}:${PORT_PHPMYADMIN:-8888}" 9 | volumes: 10 | - $PWD/docker/caddy/Caddyfile:/etc/caddy/Caddyfile 11 | - $PWD:/srv 12 | - caddy_data:/data 13 | - caddy_config:/config 14 | environment: 15 | PORT_SYMFONY: ${PORT_SYMFONY:-443} 16 | PORT_PHPMYADMIN: ${PORT_PHPMYADMIN:-8888} 17 | TZ: ${TIMEZONE:-Europe/Paris} 18 | 19 | php-fpm: 20 | build: 21 | context: docker/php-fpm 22 | args: 23 | USER_ID: ${USER_ID} 24 | GROUP_ID: ${GROUP_ID} 25 | PHP_VERSION: ${PHP_VERSION:-8} 26 | environment: 27 | CUSTOM_REPOSITORY: ${CUSTOM_REPOSITORY:-} 28 | CUSTOM_REPOSITORY_WITH_GIT_DIR: ${CUSTOM_REPOSITORY_WITH_GIT_DIR:-0} 29 | SSH_KEY_PATH: ${SSH_KEY_PATH:-} 30 | SYMFONY_VERSION: ${SYMFONY_VERSION:-} 31 | TZ: ${TIMEZONE:-Europe/Paris} 32 | depends_on: 33 | - database 34 | volumes: 35 | - $PWD:/srv 36 | - ${SSH_KEY_PATH:-/dev/null}:/home/www-data/.ssh/id_rsa 37 | links: 38 | - database 39 | 40 | database: 41 | image: "mariadb:${MARIADB_VERSION:-10}" 42 | restart: always 43 | ports: 44 | - '3306' 45 | environment: 46 | MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-symfony} 47 | MYSQL_DATABASE: ${MYSQL_DATABASE:-symfony} 48 | MYSQL_USER: ${MYSQL_USER:-symfony} 49 | MYSQL_PASSWORD: ${MYSQL_PASSWORD:-symfony} 50 | TZ: ${TIMEZONE:-Europe/Paris} 51 | 52 | phpmyadmin: 53 | build: 54 | context: docker/phpmyadmin 55 | restart: always 56 | environment: 57 | MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root} 58 | MYSQL_USER: ${MYSQL_USER:-symfony} 59 | MYSQL_PASSWORD: ${MYSQL_PASSWORD:-symfony} 60 | PMA_HOST: database 61 | UPLOAD_LIMIT: 50M 62 | TZ: ${TIMEZONE:-Europe/Paris} 63 | depends_on: 64 | - database 65 | links: 66 | - database 67 | 68 | volumes: 69 | caddy_data: 70 | caddy_config: 71 | -------------------------------------------------------------------------------- /docker/caddy/Caddyfile: -------------------------------------------------------------------------------- 1 | # The Caddyfile is an easy way to configure your Caddy web server. 2 | # 3 | # Unless the file starts with a global options block, the first 4 | # uncommented line is always the address of your site. 5 | # 6 | # To use your own domain name (with automatic HTTPS), first make 7 | # sure your domain's A/AAAA DNS records are properly pointed to 8 | # this machine's public IP, then replace the line below with your 9 | # domain name. 10 | 11 | localhost:{$PORT_SYMFONY} { 12 | # Enable access logging (to the console) 13 | log 14 | 15 | # Set this path to your site's directory. 16 | root * /srv/public 17 | 18 | # Encodes responses using Gzip compression 19 | encode gzip 20 | 21 | # Use Caddy's internal, locally-trusted CA to produce certificates for this site. 22 | tls internal 23 | 24 | # Push content to the client using HTTP/2 server push 25 | push 26 | 27 | # Enable the static file server. 28 | file_server 29 | 30 | # Another common task is to set up a reverse proxy: 31 | # reverse_proxy localhost:8080 32 | 33 | # Or serve a PHP site through php-fpm: 34 | php_fastcgi php-fpm:9000 35 | 36 | # Refer to the Caddy docs for more information: 37 | # https://caddyserver.com/docs/caddyfile 38 | } 39 | 40 | localhost:{$PORT_PHPMYADMIN} { 41 | # Enable access logging (to the console) 42 | log 43 | 44 | # Set this path to your site's directory. 45 | root * /var/www/html 46 | 47 | # Encodes responses using Gzip compression 48 | encode gzip 49 | 50 | # Use Caddy's internal, locally-trusted CA to produce certificates for this site. 51 | tls internal 52 | 53 | # Push content to the client using HTTP/2 server push 54 | push 55 | 56 | # Enable the static file server. 57 | file_server 58 | 59 | reverse_proxy phpmyadmin:80 60 | 61 | # Refer to the Caddy docs for more information: 62 | # https://caddyserver.com/docs/caddyfile 63 | } 64 | -------------------------------------------------------------------------------- /docker/caddy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM caddy:alpine 2 | 3 | RUN apk add --no-cache tzdata 4 | COPY Caddyfile /etc/caddy/Caddyfile 5 | -------------------------------------------------------------------------------- /docker/php-fpm/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PHP_VERSION 2 | FROM php:${PHP_VERSION}-fpm-alpine 3 | 4 | COPY --from=composer:latest /usr/bin/composer /usr/bin/composer 5 | ENV COMPOSER_ALLOW_SUPERUSER=1 6 | ENV PATH="${PATH}:/root/.composer/vendor/bin" 7 | 8 | # https://github.com/dunglas/symfony-docker/blob/main/Dockerfile 9 | # persistent / runtime deps 10 | RUN apk add --update --no-cache \ 11 | acl \ 12 | fcgi \ 13 | file \ 14 | gettext \ 15 | git \ 16 | jq \ 17 | postgresql \ 18 | bash \ 19 | shadow \ 20 | npm \ 21 | yarn \ 22 | openssh \ 23 | ; 24 | 25 | RUN npm install -g npm@latest 26 | 27 | ARG APCU_VERSION=5.1.20 28 | RUN set -eux; \ 29 | apk add --no-cache --virtual .build-deps \ 30 | $PHPIZE_DEPS \ 31 | icu-dev \ 32 | libzip-dev \ 33 | zlib-dev \ 34 | oniguruma-dev \ 35 | mysql-dev \ 36 | ; \ 37 | \ 38 | docker-php-ext-configure zip; \ 39 | docker-php-ext-install -j$(nproc) \ 40 | bcmath \ 41 | intl \ 42 | mbstring \ 43 | pcntl \ 44 | pdo_mysql \ 45 | mysqli \ 46 | shmop \ 47 | zip \ 48 | ; \ 49 | pecl install \ 50 | apcu-${APCU_VERSION} \ 51 | ; \ 52 | pecl clear-cache; \ 53 | docker-php-ext-enable \ 54 | apcu \ 55 | opcache \ 56 | ; \ 57 | \ 58 | runDeps="$( \ 59 | scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \ 60 | | tr ',' '\n' \ 61 | | sort -u \ 62 | | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \ 63 | )"; \ 64 | apk add --no-cache --virtual .phpexts-rundeps $runDeps; \ 65 | \ 66 | apk del .build-deps 67 | ### 68 | 69 | RUN wget https://get.symfony.com/cli/installer -O - | bash 70 | RUN mv /root/.symfony/bin/symfony /usr/local/bin/symfony 71 | 72 | COPY entrypoint.sh /usr/local/bin/entrypoint 73 | RUN chmod +x /usr/local/bin/entrypoint 74 | 75 | ARG USER_ID 76 | ARG GROUP_ID 77 | 78 | RUN if [ ${USER_ID:-0} -ne 0 ] && [ ${GROUP_ID:-0} -ne 0 ]; then \ 79 | userdel -f www-data &&\ 80 | if getent group www-data ; then groupdel www-data; fi &&\ 81 | groupadd -g ${GROUP_ID} www-data &&\ 82 | useradd -l -u ${USER_ID} -g www-data www-data &&\ 83 | install -d -m 0755 -o www-data -g www-data /home/www-data &&\ 84 | chown --changes --silent --no-dereference --recursive \ 85 | ${USER_ID}:${GROUP_ID} \ 86 | /srv \ 87 | ;fi 88 | 89 | RUN mkdir /home/www-data/.ssh 90 | RUN chown -R www-data:www-data /home/www-data 91 | 92 | WORKDIR /srv 93 | USER www-data 94 | 95 | ENTRYPOINT ["entrypoint"] 96 | CMD ["php-fpm"] 97 | 98 | EXPOSE 9000 99 | -------------------------------------------------------------------------------- /docker/php-fpm/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ ! -f composer.json ]; then 5 | ENV=$(cat .env) 6 | 7 | if [ "$CUSTOM_REPOSITORY" != "" ]; then 8 | ISGIT=$(echo "${CUSTOM_REPOSITORY}" | head -c4) 9 | 10 | if [ "$ISGIT" = "git@" ]; then 11 | SSHKEYHOST=$(echo "${CUSTOM_REPOSITORY}" | sed 's/.*@\(.*\):.*/\1/' ); 12 | touch /home/www-data/.ssh/known_hosts 13 | ssh-keyscan $SSHKEYHOST >> /home/www-data/.ssh/known_hosts 14 | fi 15 | 16 | git clone $CUSTOM_REPOSITORY tmp 17 | 18 | if [ "$CUSTOM_REPOSITORY_WITH_GIT_DIR" != "1" ]; then 19 | rm -rf tmp/.git 20 | fi 21 | else 22 | VERSION="" 23 | 24 | if [ "$SYMFONY_VERSION" != "" ]; then 25 | VERSION="--version=$SYMFONY_VERSION" 26 | fi 27 | 28 | symfony new tmp --full --no-git $VERSION 29 | fi 30 | 31 | jq '.extra.symfony.docker=true' tmp/composer.json >tmp/composer.tmp.json 32 | rm tmp/composer.json 33 | mv tmp/composer.tmp.json tmp/composer.json 34 | 35 | touch .env.local 36 | echo "$ENV" >.env.local 37 | 38 | cp -Rp tmp/. . 39 | rm -Rf tmp/ 40 | 41 | if [ "$CUSTOM_REPOSITORY" = "" ]; then 42 | sed -i 's/DATABASE_URL="postgresql/# DATABASE_URL="postgresql/' .env 43 | else 44 | if [ -f composer.json ]; then 45 | symfony composer install --no-progress --no-interaction -q 46 | fi 47 | 48 | if [ -f package.json ]; then 49 | if [ -f yarn.lock ]; then 50 | yarn install --silent 51 | elif [ -f package-lock.json ]; then 52 | npm install --silent 53 | fi 54 | fi 55 | 56 | symfony console d:s:u -f 57 | fi 58 | 59 | elif [ "$APP_ENV" != 'prod' ]; then 60 | rm -f .env.local.php 61 | symfony composer install --prefer-dist --no-progress --no-interaction -q 62 | fi 63 | 64 | exec docker-php-entrypoint "$@" 65 | -------------------------------------------------------------------------------- /docker/phpmyadmin/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM phpmyadmin/phpmyadmin:latest 2 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -o allexport 4 | 5 | if [ -f .env.local ]; then 6 | source ./.env.local 7 | elif [ -f .env ]; then 8 | source ./.env 9 | else 10 | echo "No .env or .env.local found !" 11 | exit 12 | fi 13 | 14 | declare USER_ID 15 | # shellcheck disable=SC2034 16 | USER_ID=$(id -u) 17 | 18 | declare GROUP_ID 19 | # shellcheck disable=SC2034 20 | GROUP_ID=$(id -u) 21 | 22 | options="" 23 | 24 | while [[ "$#" -gt 0 ]]; do 25 | options="$options $1" 26 | shift 27 | done 28 | 29 | docker-compose up ${options} 30 | 31 | set +o allexport 32 | --------------------------------------------------------------------------------