DEV Community

slns
slns

Posted on

Symfony 6 with docker

In this project the intention is to create a project in symfony 6, with docker, mariadb, phpmyadmin.

To begin with, we will create a page structure similar to the image:
folder struct

Make the folders, and some files:

mkdir symfony-6-docker && touch .env && touch .gitignore 
&& touch docker-compose.yml && touch README.md 
&& mkdir docker && cd docker && mkdir database 
&& mkdir logs && mkdir nginx && mkdir php-fpm 
&& cd database && mkdir data && touch Dockerfile  
&& touch init.sql && cd ../logs && mkdir nginx 
&& cd nginx && touch access.log && touch error.log 
&& touch .gitignore && cd ../../nginx && touch Dockerfile 
&& touch nginx.conf && mkdir conf.d && mkdir sites 
&& cd  conf.d && touch default.conf && cd ../sites 
&& touch default.conf && cd ../../php-fpm 
&& touch wait-for-it.sh && touch Dockerfile && cd ../..
Enter fullscreen mode Exit fullscreen mode

After that, it is necessary to verify that we have everything necessary to create a symfony 6 project.
For this we run the command.

symfony check:requirements
Enter fullscreen mode Exit fullscreen mode

When you get the same answer as the picture, it means that everything is fine.

approve requirements

Having everything ok, we create the project in the project root.

 symfony new symfony --version="6.1.*"
Enter fullscreen mode Exit fullscreen mode

With your preferred IDE, open the project in the root, and copy the contents of the files.

  • docker-composer.yml
# docker-composer.yml
version: '3'

services:
  database:
    build:
      context: ./docker/database
    environment:
      - MYSQL_DATABASE=${DATABASE_NAME}
      - MYSQL_USER=${DATABASE_USER}
      - MYSQL_PASSWORD=${DATABASE_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DATABASE_ROOT_PASSWORD}
    ports:
      - "3309:3306"
    volumes:
      - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
      - ./docker/database/data:/var/lib/mysql

  phpmyadmin:
        depends_on:
            - database
        image: phpmyadmin
        links:
          - database
        restart: always
        ports:
            - 8080:80
        environment:
            PMA_HOST: database
            PMA_PORT: 3306
            PMA_ARBITRARY: 1

  php-fpm:
    build:
      context: ./docker/php-fpm
    depends_on:
      - database
    environment:
      - APP_ENV=${APP_ENV}
      - APP_SECRET=${APP_SECRET}
      - DATABASE_URL=mysql://${DATABASE_USER}:${DATABASE_PASSWORD}@database:3306/${DATABASE_NAME}?serverVersion=5.7
    volumes:
      - ./symfony:/var/www

  nginx:
    build:
      context: ./docker/nginx
    volumes:
      - ./symfony:/var/www
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./docker/nginx/sites/:/etc/nginx/sites-available
      - ./docker/nginx/conf.d/:/etc/nginx/conf.d
      - ./docker/logs:/var/log
    depends_on:
      - php-fpm
    ports:
      - "80:80"
      - "443:443"
Enter fullscreen mode Exit fullscreen mode
  • .env
DATABASE_NAME=symfony
DATABASE_USER=appuser
DATABASE_PASSWORD=apppassword
DATABASE_ROOT_PASSWORD=secret

APP_ENV=dev
APP_SECRET=change-to-your-secret-value
Enter fullscreen mode Exit fullscreen mode
  • docker/database/Dockerfile
FROM mariadb:latest

CMD ["mysqld"]

EXPOSE 3306
Enter fullscreen mode Exit fullscreen mode
  • docker/database/init.sql
CREATE DATABASE IF NOT EXISTS symfony;
USE symfony;
Enter fullscreen mode Exit fullscreen mode
  • docker/nginx/Dockerfile
FROM nginx:alpine

WORKDIR /var/www

CMD ["nginx"]

EXPOSE 80 443
Enter fullscreen mode Exit fullscreen mode
  • docker/nginx/nginx.conf
user  nginx;
worker_processes  4;
daemon off;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  /var/log/nginx/access.log;
    #access_log /dev/stdout;
    #error_log /dev/stderr;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-available/*.conf;
}
Enter fullscreen mode Exit fullscreen mode
  • docker/nginx/conf.d/default.conf
upstream php-upstream {
    server php-fpm:9000;
}
Enter fullscreen mode Exit fullscreen mode
  • docker/nginx/sites/default.conf
server {

    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name localhost;
    root /var/www/public;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }
}
Enter fullscreen mode Exit fullscreen mode
  • docker/php-fpm/Dockerfile
FROM php:fpm-alpine

COPY wait-for-it.sh /usr/bin/wait-for-it

RUN chmod +x /usr/bin/wait-for-it

RUN apk --update --no-cache add git

RUN apk add bash

RUN docker-php-ext-install pdo_mysql

COPY --from=composer /usr/bin/composer /usr/bin/composer

WORKDIR /var/www

CMD composer install ; wait-for-it database:3306 -- bin/console doctrine:migrations:migrate ;  php-fpm 

EXPOSE 9000
Enter fullscreen mode Exit fullscreen mode
  • docker/php-fpm/wait-for-it.sh
#!/bin/sh

TIMEOUT=15
QUIET=0

echoerr() {
  if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
}

usage() {
  exitcode="$1"
  cat << USAGE >&2
Usage:
  $cmdname host:port [-t timeout] [-- command args]
  -q | --quiet                        Do not output any status messages
  -t TIMEOUT | --timeout=timeout      Timeout in seconds, zero for no timeout
  -- COMMAND ARGS                     Execute command with args after the test finishes
USAGE
  exit "$exitcode"
}

wait_for() {
  for i in `seq $TIMEOUT` ; do
    nc -z "$HOST" "$PORT" > /dev/null 2>&1

    result=$?
    if [ $result -eq 0 ] ; then
      if [ $# -gt 0 ] ; then
        exec "$@"
      fi
      exit 0
    fi
    sleep 1
  done
  echo "Operation timed out" >&2
  exit 1
}

while [ $# -gt 0 ]
do
  case "$1" in
    *:* )
    HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
    PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
    shift 1
    ;;
    -q | --quiet)
    QUIET=1
    shift 1
    ;;
    -t)
    TIMEOUT="$2"
    if [ "$TIMEOUT" = "" ]; then break; fi
    shift 2
    ;;
    --timeout=*)
    TIMEOUT="${1#*=}"
    shift 1
    ;;
    --)
    shift
    break
    ;;
    --help)
    usage 0
    ;;
    *)
    echoerr "Unknown argument: $1"
    usage 1
    ;;
  esac
done

if [ "$HOST" = "" -o "$PORT" = "" ]; then
  echoerr "Error: you need to provide a host and port to test."
  usage 2
fi

wait_for "$@"
Enter fullscreen mode Exit fullscreen mode

After copying all the files, go to the root of the project, and run:

docker-compose up -d

Link to the project:
symfony project

show symfony

Link to the phpmyadmin:
phpmyadmin

image phpmyadmin

The project link on GitHub is:
symfony-6-docker

Top comments (0)