diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..dba097a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,83 @@ +version: '3.9' +services: + db: + container_name: db + image: mysql:8.0.22 + command: ["--default-authentication-plugin=mysql_native_password"] + ports: + - "${MYSQL_PORT}:3306" + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ClusterCockpit + MYSQL_USER: symfony + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + volumes: + - ./sql:/var/lib/mysql + + influxdb: + container_name: influxdb + image: influxdb + command: ["--reporting-disabled"] + ports: + - "${INFLUXDB_PORT}:8086" + environment: + DOCKER_INFLUXDB_INIT_MODE: setup + DOCKER_INFLUXDB_INIT_USERNAME: symfony + DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_PASSWORD} + DOCKER_INFLUXDB_INIT_ORG: ClusterCockpit + DOCKER_INFLUXDB_INIT_BUCKET: ClusterCockpit + DOCKER_INFLUXDB_INIT_RETENTION: 2w + DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: ${INFLUXDB_ADMIN_TOKEN} + volumes: + - ./influxdb/data:/var/lib/influxdb2 + - ./influxdb/config:/etc/influxdb2 + + php: + container_name: php-fpm + build: + context: ./php-fpm + args: + PHP_XDEBUG_MODE: ${PHP_XDEBUG_MODE} + PHP_XDEBUG_CLIENT_PORT: ${PHP_XDEBUG_CLIENT_PORT} + PHP_XDEBUG_CLIENT_HOST: ${PHP_XDEBUG_CLIENT_HOST} + SYMFONY_CLI_VERSION: 4.23.2 + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + INFLUXDB_PASSWORD: ${INFLUXDB_PASSWORD} + ports: + - "${PHP_PORT}:9001" + volumes: + - ./logs/symfony:/var/www/symfony/var/log + - ./symfony:/var/www/symfony + depends_on: + - db + - influxdb + + phpmyadmin: + image: phpmyadmin + container_name: phpmyadmin + environment: + - PMA_HOST=db + - PMA_USER=root + - PMA_PASSWORD=${MYSQL_ROOT_PASSWORD} + ports: + - "${PHPMYADMIN_PORT}:80" + restart: always + + nginx: + container_name: nginx + build: + context: ./nginx + args: + NGINX_SYMFONY_SERVER_NAME: ${NGINX_SYMFONY_SERVER_NAME} + ports: + - "${NGINX_PORT}:80" + depends_on: + - php + environment: + - NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx/conf.d + - NGINX_ENVSUBST_TEMPLATE_DIR=/etc/nginx/templates + - NGINX_ENVSUBST_TEMPLATE_SUFFIX=.template + - NGINX_SYMFONY_SERVER_NAME=${NGINX_SYMFONY_SERVER_NAME} + volumes: + - ./logs/nginx:/var/log/nginx:cached + - ./symfony:/var/www/symfony:cached diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000..3ffd6fd --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,20 @@ +FROM nginx:1.19.6 + +LABEL maintainer="Vincent Composieux " + +RUN mkdir -p /etc/nginx/templates \ + mkdir -p /tmp/nginx + +COPY nginx.conf /etc/nginx/ +COPY templates/* /etc/nginx/templates/ +COPY html/index.html.template /tmp/nginx/ + +ARG NGINX_SYMFONY_SERVER_NAME +ARG KIBANA_PORT +RUN envsubst < /tmp/nginx/index.html.template > /usr/share/nginx/html/index.html; \ + rm -fR /tmp/nginx + +CMD ["nginx"] + +EXPOSE 80 +EXPOSE 443 diff --git a/nginx/html/index.html.template b/nginx/html/index.html.template new file mode 100644 index 0000000..4acab25 --- /dev/null +++ b/nginx/html/index.html.template @@ -0,0 +1,23 @@ + + + + docker-symfony + + +

+ docker-symfony +

+

+ A complete stack for running Symfony 5 (latest version), PHP8 and ELK stack using docker-compose tool.
+

+

+ Note
+ Remember to add ${NGINX_SYMFONY_SERVER_NAME} in your /etc/hosts file.
+

+

Index

+ + + diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..9514032 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,32 @@ +user www-data; +worker_processes 4; +pid /run/nginx.pid; + +events { + worker_connections 2048; + multi_accept on; + use epoll; +} + +http { + server_tokens off; + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 15; + types_hash_max_size 2048; + include /etc/nginx/mime.types; + default_type application/octet-stream; + access_log off; + error_log off; + gzip on; + gzip_disable "msie6"; + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; + open_file_cache max=100; + client_body_temp_path /tmp 1 2; + client_body_buffer_size 256k; + client_body_in_file_only off; +} + +daemon off; diff --git a/nginx/templates/php-upstream.conf.template b/nginx/templates/php-upstream.conf.template new file mode 100644 index 0000000..7d2c126 --- /dev/null +++ b/nginx/templates/php-upstream.conf.template @@ -0,0 +1,3 @@ +upstream php-upstream { + server php:9001; +} diff --git a/nginx/templates/symfony.conf.template b/nginx/templates/symfony.conf.template new file mode 100644 index 0000000..21a06cb --- /dev/null +++ b/nginx/templates/symfony.conf.template @@ -0,0 +1,24 @@ +server { + server_name ${NGINX_SYMFONY_SERVER_NAME}; + root /var/www/symfony/public; + + + location / { + try_files $uri @rewriteapp; + } + + location @rewriteapp { + rewrite ^(.*)$ /index.php/$1 last; + } + + location ~ ^/index\.php(/|$) { + fastcgi_pass php-upstream; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param HTTPS off; + } + + error_log /var/log/nginx/symfony_error.log; + access_log /var/log/nginx/symfony_access.log; +} diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile new file mode 100644 index 0000000..79a8aa6 --- /dev/null +++ b/php-fpm/Dockerfile @@ -0,0 +1,86 @@ +FROM alpine:3.13 + +LABEL maintainer="Vincent Composieux " + +RUN apk add --no-cache \ + coreutils \ + gettext \ + php8-fpm \ + php8-ctype \ + php8-curl \ + php8-dom \ + php8-gd \ + php8-iconv \ + php8-json \ + php8-intl \ + php8-fileinfo\ + php8-mbstring \ + php8-opcache \ + php8-openssl \ + php8-pdo \ + php8-pdo_mysql \ + php8-mysqli \ + php8-xml \ + php8-xsl \ + php8-zlib \ + php8-phar \ + php8-tokenizer \ + php8-session \ + php8-simplexml \ + php8-zip \ + php8-xmlwriter \ + php8-sodium \ + php8-pecl-apcu \ + php8-ldap \ + bash \ + make \ + git \ + curl + +# Enable php8-xdebug if $PHP_XDEBUG_MODE is not empty +ARG PHP_XDEBUG_MODE=off +ARG PHP_XDEBUG_CLIENT_PORT=5902 +ARG PHP_XDEBUG_CLIENT_HOST=host.docker.internal +COPY xdebug.ini /etc/php8/conf.d/xdebug.ini.template +RUN if [[ "$PHP_XDEBUG_MODE" != "" ]]; then \ + apk add --no-cache php8-pecl-xdebug; \ + export PHP_XDEBUG_MODE=$PHP_XDEBUG_MODE; \ + export PHP_XDEBUG_CLIENT_PORT=$PHP_XDEBUG_CLIENT_PORT; \ + export PHP_XDEBUG_CLIENT_HOST=$PHP_XDEBUG_CLIENT_HOST; \ + envsubst < /etc/php8/conf.d/xdebug.ini.template > /etc/php8/conf.d/xdebug.ini; \ + fi +RUN rm -f /etc/php8/conf.d/xdebug.ini.template + +RUN curl -sS https://getcomposer.org/installer | tee composer-setup.php \ + && php8 composer-setup.php && rm composer-setup.php* \ + && chmod +x composer.phar && mv composer.phar /usr/bin/composer \ + && ln -s /usr/bin/php8 /usr/local/bin/php + +ARG SYMFONY_CLI_VERSION +RUN wget https://github.com/symfony/cli/releases/download/v$SYMFONY_CLI_VERSION/symfony_linux_amd64.gz \ + && gzip -d symfony_linux_amd64.gz \ + && mv symfony_linux_amd64 symfony \ + && chmod +x symfony \ + && mv symfony /usr/local/bin/ + +RUN apk add --update nodejs npm \ + && npm install --global yarn + +COPY symfony.ini /etc/php8/conf.d/ +COPY symfony.ini /etc/php8/cli/conf.d/ + +COPY symfony.pool.conf /etc/php8/php-fpm.d/ +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENV APP_ENV=prod +ENV APP_DEBUG=0 +ARG INFLUXDB_PASSWORD +ARG MYSQL_PASSWORD +ENV INFLUXDB_URL=influxdb://symfony:${INFLUXDB_PASSWORD}@influxdb:8086/ClusterCockpit +ENV DATABASE_URL=mysql://symfony:${MYSQL_PASSWORD}@db:3306/ClusterCockpit +ENV CORS_ALLOW_ORIGIN=^https?://(localhost|127\\.0\\.0\\.1)(:[0-9]+)?$ + +EXPOSE 9001 +CMD ["php-fpm8", "-F"] +ENTRYPOINT ["/entrypoint.sh"] diff --git a/php-fpm/entrypoint.sh b/php-fpm/entrypoint.sh new file mode 100755 index 0000000..538c467 --- /dev/null +++ b/php-fpm/entrypoint.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +git clone https://github.com/ClusterCockpit/ClusterCockpit.git /var/www/symfony/. +cd /var/www/symfony +git checkout feature-47-introduce-graphql-api +composer install --no-dev --optimize-autoloader +yarn install +yarn encore production +# bin/console doc:mig:mig --no-interaction +# bin/console doc:fix:load --no-interaction + +exec "$@" diff --git a/php-fpm/symfony.ini b/php-fpm/symfony.ini new file mode 100644 index 0000000..c3d7967 --- /dev/null +++ b/php-fpm/symfony.ini @@ -0,0 +1 @@ +date.timezone = UTC diff --git a/php-fpm/symfony.pool.conf b/php-fpm/symfony.pool.conf new file mode 100644 index 0000000..c0bb18e --- /dev/null +++ b/php-fpm/symfony.pool.conf @@ -0,0 +1,81 @@ +; Start a new pool named 'symfony'. +; the variable $pool can be used in any directive and will be replaced by the +; pool name ('symfony' here) +[symfony] + +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = nobody +group = nobody + +; The address on which to accept FastCGI requests. +; Valid syntaxes are: +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses on a +; specific port; +; '/path/to/unix/socket' - to listen on a unix socket. +; Note: This value is mandatory. +listen = 0.0.0.0:9001 + +; Choose how the process manager will control the number of child processes. +; Possible Values: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives. With this process management, there will be +; always at least 1 children. +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; ondemand - no children are created at startup. Children will be forked when +; new requests will connect. The following parameter are used: +; pm.max_children - the maximum number of children that +; can be alive at the same time. +; pm.process_idle_timeout - The number of seconds after which +; an idle process will be killed. +; Note: This value is mandatory. +pm = dynamic + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. The below defaults are based on a server without much resources. Don't +; forget to tweak pm.* to fit your needs. +; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' +; Note: This value is mandatory. +pm.max_children = 20 + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 +pm.start_servers = 2 + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = 1 + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = 3 + +;--------------------- + +; Make specific Docker environment variables available to PHP +env[DB_1_ENV_MYSQL_DATABASE] = $DB_1_ENV_MYSQL_DATABASE +env[DB_1_ENV_MYSQL_USER] = $DB_1_ENV_MYSQL_USER +env[DB_1_ENV_MYSQL_PASSWORD] = $DB_1_ENV_MYSQL_PASSWORD + +catch_workers_output = yes diff --git a/php-fpm/xdebug.ini b/php-fpm/xdebug.ini new file mode 100644 index 0000000..013ad3f --- /dev/null +++ b/php-fpm/xdebug.ini @@ -0,0 +1,6 @@ +zend_extension=xdebug.so + +[Xdebug] +xdebug.mode=${PHP_XDEBUG_MODE} +xdebug.client_port=${PHP_XDEBUG_CLIENT_PORT} +xdebug.client_host=${PHP_XDEBUG_CLIENT_HOST} \ No newline at end of file