diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..9f856a0 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,64 @@ +name: Docker CI + +on: + pull_request: + paths: + - 'docker/**' + - 'docker-compose*.yml' + - '.github/workflows/docker.yml' + push: + paths: + - 'docker/**' + - 'docker-compose*.yml' + - '.github/workflows/docker.yml' + +jobs: + test-apache: + runs-on: ubuntu-latest + + steps: + - name: Checkout. + uses: actions/checkout@v4 + + - name: Install docker compose. + run: | + sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + docker-compose --version + + - name: Build and start containers. + run: docker-compose build --no-cache && docker-compose up -d + + - name: Update vendor packages. + run: docker exec yii2-apache composer update --prefer-dist -vvv + + - name: Codeceptcion build. + run: docker exec yii2-apache vendor/bin/codecept build + + - name: Run codeception tests. + run: docker exec yii2-apache vendor/bin/codecept run + + test-nginx: + runs-on: ubuntu-latest + + steps: + - name: Checkout. + uses: actions/checkout@v4 + + - name: Install docker Compose. + run: | + sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + docker-compose --version + + - name: Build and start containers. + run: docker-compose -f docker-compose.nginx.yml build --no-cache && docker-compose -f docker-compose.nginx.yml up -d + + - name: Update vendor packages. + run: docker exec yii2-nginx composer update --prefer-dist -vvv + + - name: Codeception build. + run: docker exec yii2-nginx vendor/bin/codecept build + + - name: Run codeception build and tests. + run: docker exec yii2-nginx vendor/bin/codecept run diff --git a/composer.lock b/composer.lock index 8719093..93e003f 100644 --- a/composer.lock +++ b/composer.lock @@ -6493,16 +6493,16 @@ }, { "name": "rector/rector", - "version": "2.1.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "d513dea45a94394b660e15c155d1fa27826f8e30" + "reference": "d0917c069bb0d9bb06ed111cf052510f609015a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/d513dea45a94394b660e15c155d1fa27826f8e30", - "reference": "d513dea45a94394b660e15c155d1fa27826f8e30", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/d0917c069bb0d9bb06ed111cf052510f609015a4", + "reference": "d0917c069bb0d9bb06ed111cf052510f609015a4", "shasum": "" }, "require": { @@ -6541,7 +6541,7 @@ ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/2.1.0" + "source": "https://github.com/rectorphp/rector/tree/2.1.1" }, "funding": [ { @@ -6549,7 +6549,7 @@ "type": "github" } ], - "time": "2025-06-24T20:26:57+00:00" + "time": "2025-07-10T11:31:31+00:00" }, { "name": "sebastian/cli-parser", diff --git a/docker-compose.nginx.yml b/docker-compose.nginx.yml new file mode 100644 index 0000000..ca2708d --- /dev/null +++ b/docker-compose.nginx.yml @@ -0,0 +1,15 @@ + +services: + yii2-nginx: + build: + dockerfile: docker/nginx/Dockerfile + container_name: yii2-nginx + restart: always + working_dir: /app + volumes: + - ./:/app + - ~/.composer-docker/cache:/root/.composer/cache:delegated + ports: + - '8081:80' + environment: + TZ: "UTC" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..819629d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + yii2-apache: + build: + dockerfile: docker/apache/Dockerfile + container_name: yii2-apache + image: yii2-apache:84 + restart: always + working_dir: /app + volumes: + - ./:/app + - ~/.composer-docker/cache:/root/.composer/cache:delegated + ports: + - '8080:80' + environment: + TZ: "UTC" diff --git a/docker/apache/Dockerfile b/docker/apache/Dockerfile new file mode 100644 index 0000000..3944a98 --- /dev/null +++ b/docker/apache/Dockerfile @@ -0,0 +1,30 @@ +FROM yiisoftware/yii2-php:8.4-apache + +# change web server config +COPY docker/apache/apache.conf /etc/apache2/apache2.conf +COPY docker/apache/vhost.conf /etc/apache2/sites-available/000-default.conf + +# change PHP config +COPY docker/php/php.ini /usr/local/etc/php/conf.d/base.ini + +# install supervisord and Node.js (includes npm) +RUN apt-get update && apt-get install -y \ + supervisor \ + curl \ + --no-install-recommends \ + && curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \ + && apt-get install -y nodejs \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# copy supervisord config +COPY docker/apache/supervisord/supervisord.conf /etc/supervisor/supervisord.conf + +# copy supervisord program configs +COPY docker/apache/supervisord/conf.d/apache2.conf /etc/supervisor/conf.d/apache2.conf + +# copy queue worker config uncommented for use with yii2-queue +#COPY docker/apache/supervisord/conf.d/queue.conf /etc/supervisor/conf.d/queue.conf + +# run supervisord +CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/docker/apache/apache.conf b/docker/apache/apache.conf new file mode 100644 index 0000000..413858f --- /dev/null +++ b/docker/apache/apache.conf @@ -0,0 +1,234 @@ +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See http://httpd.apache.org/docs/2.4/ for detailed information about +# the directives and /usr/share/doc/apache2/README.Debian about Debian specific +# hints. +# +# +# Summary of how the Apache 2 configuration works in Debian: +# The Apache 2 web server configuration in Debian is quite different to +# upstream's suggested way to configure the web server. This is because Debian's +# default Apache2 installation attempts to make adding and removing modules, +# virtual hosts, and extra configuration directives as flexible as possible, in +# order to make automating the changes and administering the server as easy as +# possible. + +# It is split into several files forming the configuration hierarchy outlined +# below, all located in the /etc/apache2/ directory: +# +# /etc/apache2/ +# |-- apache2.conf +# | `-- ports.conf +# |-- mods-enabled +# | |-- *.load +# | `-- *.conf +# |-- conf-enabled +# | `-- *.conf +# `-- sites-enabled +# `-- *.conf +# +# +# * apache2.conf is the main configuration file (this file). It puts the pieces +# together by including all remaining configuration files when starting up the +# web server. +# +# * ports.conf is always included from the main configuration file. It is +# supposed to determine listening ports for incoming connections which can be +# customized anytime. +# +# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ +# directories contain particular configuration snippets which manage modules, +# global configuration fragments, or virtual host configurations, +# respectively. +# +# They are activated by symlinking available configuration files from their +# respective *-available/ counterparts. These should be managed by using our +# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See +# their respective man pages for detailed information. +# +# * The binary is called apache2. Due to the use of environment variables, in +# the default configuration, apache2 needs to be started/stopped with +# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not +# work with the default configuration. + + +# Global configuration +# + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the Mutex documentation (available +# at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +#ServerRoot "/etc/apache2" + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# +#Mutex file:${APACHE_LOCK_DIR} default + +# +# The directory where shm and other runtime files will be stored. +# + +DefaultRuntimeDir ${APACHE_RUN_DIR} + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# This needs to be set in /etc/apache2/envvars +# +PidFile ${APACHE_PID_FILE} + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 500 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 5 + + +# These need to be set in /etc/apache2/envvars +User ${APACHE_RUN_USER} +Group ${APACHE_RUN_GROUP} + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog ${APACHE_LOG_DIR}/error.log + +# +# LogLevel: Control the severity of messages logged to the error_log. +# Available values: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the log level for particular modules, e.g. +# "LogLevel info ssl:warn" +# +LogLevel warn + +# Include module configuration: +IncludeOptional mods-enabled/*.load +IncludeOptional mods-enabled/*.conf + +# Include list of ports to listen on +Include ports.conf + + +# Sets the default security model of the Apache2 HTTPD server. It does +# not allow access to the root filesystem outside of /usr/share and /var/www. +# The former is used by web applications packaged in Debian, +# the latter may be used for local directories served by the web server. If +# your system is serving content from a sub-directory in /srv you must allow +# access here, or in any related virtual host. + + Options FollowSymLinks + AllowOverride None + Require all denied + + + + AllowOverride None + Require all granted + + + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + +# +# Options Indexes FollowSymLinks +# AllowOverride None +# Require all granted +# + + +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# +AccessFileName .htaccess + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + + +# +# The following directives define some format nicknames for use with +# a CustomLog directive. +# +# These deviate from the Common Log Format definitions in that they use %O +# (the actual bytes sent including headers) instead of %b (the size of the +# requested file), because the latter makes it impossible to detect partial +# requests. +# +# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. +# Use mod_remoteip instead. +# +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# Include of directories ignores editors' and dpkg's backup files, +# see README.Debian for details. + +# Include generic snippets of statements +IncludeOptional conf-enabled/*.conf + +# Include the virtual host configurations: +IncludeOptional sites-enabled/*.conf + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet + +ServerTokens ProductOnly +ServerSignature Off + +TraceEnable Off + + + Require all denied + \ No newline at end of file diff --git a/docker/apache/supervisord/conf.d/apache2.conf b/docker/apache/supervisord/conf.d/apache2.conf new file mode 100644 index 0000000..0d42f1e --- /dev/null +++ b/docker/apache/supervisord/conf.d/apache2.conf @@ -0,0 +1,4 @@ +[program:apache2] +command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND" +autostart=true +autorestart=true \ No newline at end of file diff --git a/docker/apache/supervisord/conf.d/queue.conf b/docker/apache/supervisord/conf.d/queue.conf new file mode 100644 index 0000000..5ee7012 --- /dev/null +++ b/docker/apache/supervisord/conf.d/queue.conf @@ -0,0 +1,9 @@ +[program:yii-queue-worker] +process_name=%(program_name)s_%(process_num)02d +command=/usr/local/bin/php /app/yii queue/listen --verbose=1 --color=0 +autostart=true +autorestart=true +user=www-data +numprocs=4 +redirect_stderr=true +stdout_logfile=/app/docker/apache/supervisord/log/yii-queue-worker.log diff --git a/docker/apache/supervisord/log/.gitignore b/docker/apache/supervisord/log/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/docker/apache/supervisord/log/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/docker/apache/supervisord/supervisord.conf b/docker/apache/supervisord/supervisord.conf new file mode 100644 index 0000000..649e117 --- /dev/null +++ b/docker/apache/supervisord/supervisord.conf @@ -0,0 +1,15 @@ + +[supervisord] +logfile = /proc/self/fd/1 +logfile_maxbytes = 0 +loglevel = info +pidfile = /var/run/supervisord.pid +nodaemon = true +user = root +silent = true + +[include] +files = /etc/supervisor/conf.d/*.conf + +[supervisorctl] +serverurl = unix:///var/run/supervisor.sock diff --git a/docker/apache/vhost.conf b/docker/apache/vhost.conf new file mode 100644 index 0000000..cf6f1ff --- /dev/null +++ b/docker/apache/vhost.conf @@ -0,0 +1,36 @@ + + Options FollowSymLinks + AllowOverride All + Require all granted + + + + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + #ServerName example.com + #ServerAlias www.example.com + + ServerAdmin webmaster@localhost + DocumentRoot /app/public + + # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, + # error, crit, alert, emerg. + # It is also possible to configure the loglevel for particular + # modules, e.g. + #LogLevel info ssl:warn + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + # For most configuration files from conf-available/, which are + # enabled or disabled at a global level, it is possible to + # include a line for only one particular virtual host. For example the + # following line enables the CGI configuration for this host only + # after it has been globally disabled with "a2disconf". + #Include conf-available/serve-cgi-bin.conf + \ No newline at end of file diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 0000000..8d215ff --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +1,31 @@ +FROM yiisoftware/yii2-php:8.4-fpm-nginx + +# change nginx config +COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf +COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf + +# change PHP config (same as Apache) +COPY docker/php/php.ini /usr/local/etc/php/conf.d/base.ini + +# install supervisord and Node.js (includes npm) +RUN apt-get update && apt-get install -y \ + supervisor \ + curl \ + --no-install-recommends \ + && curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \ + && apt-get install -y nodejs \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# copy supervisord config +COPY docker/nginx/supervisord/supervisord.conf /etc/supervisor/supervisord.conf + +# copy supervisord program configs +COPY docker/nginx/supervisord/conf.d/nginx.conf /etc/supervisor/conf.d/nginx.conf +COPY docker/nginx/supervisord/conf.d/php-fpm.conf /etc/supervisor/conf.d/php-fpm.conf + +# copy queue worker config uncommented for use with yii2-queue +#COPY docker/apache/supervisord/conf.d/queue.conf /etc/supervisor/conf.d/queue.conf + +# run supervisord +CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"] diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf new file mode 100644 index 0000000..d82fe08 --- /dev/null +++ b/docker/nginx/default.conf @@ -0,0 +1,71 @@ +server { + charset utf-8; + client_max_body_size 128M; + listen 80; + server_name localhost; + + # document root and index file + root /app/public; + index index.php; + + # security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + + # logging + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + # Yii URL rewriting (CRITICAL for Yii2) + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + + # deny PHP execution in /assets before the generic handler (Yii2 security) + location ~ ^/assets/.*\.php$ { + deny all; + return 403; + } + + # PHP handling via PHP-FPM + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + try_files $uri =404; + + # PHP execution settings + fastcgi_read_timeout 300; + fastcgi_buffer_size 128k; + fastcgi_buffers 4 256k; + fastcgi_busy_buffers_size 256k; + } + + # block access to sensitive files + location ~ /\.git { + deny all; + } + + location ~ /\.ht { + deny all; + } + + # block access to hidden files/directories + location ~* /\. { + deny all; + } + + # static files handling with caching + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # deny access to PHP files in specific directories (ajustado a tu estructura) + location ~ ^/(vendor|runtime)/.+\.php$ { + deny all; + return 404; + } +} diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf new file mode 100644 index 0000000..af7722a --- /dev/null +++ b/docker/nginx/nginx.conf @@ -0,0 +1,59 @@ +user www-data; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + multi_accept on; + use epoll; +} + +http { + # Basic Settings + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + # Security headers + server_tokens off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # SSL Settings + ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM'; + ssl_ecdh_curve X25519:P-256; + ssl_prefer_server_ciphers on; + ssl_dhparam /etc/ssl/certs/dhparam.pem; + + # Logging Settings + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + error_log /var/log/nginx/error.log warn; + + # Gzip Settings + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/json + application/javascript + application/xml+rss + application/atom+xml + image/svg+xml; + + # Virtual Host Configs + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} diff --git a/docker/nginx/supervisord/conf.d/nginx.conf b/docker/nginx/supervisord/conf.d/nginx.conf new file mode 100644 index 0000000..3df5802 --- /dev/null +++ b/docker/nginx/supervisord/conf.d/nginx.conf @@ -0,0 +1,12 @@ +[program:nginx] +command=/usr/sbin/nginx -g "daemon off;" +autostart=true +autorestart=true +priority=10 +killasgroup=true +stopasgroup=true +stopsignal=QUIT +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 diff --git a/docker/nginx/supervisord/conf.d/php-fpm.conf b/docker/nginx/supervisord/conf.d/php-fpm.conf new file mode 100644 index 0000000..39399ab --- /dev/null +++ b/docker/nginx/supervisord/conf.d/php-fpm.conf @@ -0,0 +1,13 @@ + +[program:php-fpm] +command=/usr/local/sbin/php-fpm --nodaemonize +autorestart=true +autostart=true +killasgroup=true +priority=5 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stopasgroup=true +stopsignal=QUIT diff --git a/docker/nginx/supervisord/conf.d/queue.conf b/docker/nginx/supervisord/conf.d/queue.conf new file mode 100644 index 0000000..b27b6bb --- /dev/null +++ b/docker/nginx/supervisord/conf.d/queue.conf @@ -0,0 +1,14 @@ +[program:yii-queue-worker] +process_name=%(program_name)s_%(process_num)02d +command=/usr/local/bin/php /app/yii queue/listen --verbose=1 --color=0 +autorestart=true +autostart=true +killasgroup=true +numprocs=4 +redirect_stderr=true +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stopasgroup=true +user=www-data diff --git a/docker/nginx/supervisord/log/.gitignore b/docker/nginx/supervisord/log/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/docker/nginx/supervisord/log/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/docker/nginx/supervisord/supervisord.conf b/docker/nginx/supervisord/supervisord.conf new file mode 100644 index 0000000..f2bbee4 --- /dev/null +++ b/docker/nginx/supervisord/supervisord.conf @@ -0,0 +1,14 @@ +[supervisord] +logfile = /proc/self/fd/1 +logfile_maxbytes = 0 +loglevel = info +pidfile = /var/run/supervisord.pid +nodaemon = true +user = root +silent = true + +[include] +files = /etc/supervisor/conf.d/*.conf + +[supervisorctl] +serverurl = unix:///var/run/supervisor.sock diff --git a/docker/php/php.ini b/docker/php/php.ini new file mode 100644 index 0000000..4f7adf6 --- /dev/null +++ b/docker/php/php.ini @@ -0,0 +1,18 @@ +;apc.enable_cli = 1 +date.timezone = UTC +session.auto_start = Off +short_open_tag = Off +expose_php = Off +upload_max_filesize = 15M +post_max_size = 150M +memory_limit = 512M +display_errors = Off + +# https://symfony.com/doc/current/performance.html +opcache.interned_strings_buffer = 16 +opcache.max_accelerated_files = 20000 +opcache.memory_consumption = 256 +opcache.validate_timestamps = 0 +realpath_cache_size = 4096K +realpath_cache_ttl = 600 +opcache.preload_user = www-data \ No newline at end of file diff --git a/src/framework/resource/css/site.css b/src/framework/resource/css/site.css index 09cba52..fe627e9 100644 --- a/src/framework/resource/css/site.css +++ b/src/framework/resource/css/site.css @@ -43,7 +43,6 @@ html, body { } [data-bs-theme=dark] #contactform-verifycode-image { - background-color: var(--bs-secondary-bg); border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 1px 3px rgba(0,0,0,0.3); filter: invert(1) hue-rotate(180deg); diff --git a/tests/Unit/ContactControllerTest.php b/tests/Unit/ContactControllerTest.php index 21ed7ac..89670c5 100644 --- a/tests/Unit/ContactControllerTest.php +++ b/tests/Unit/ContactControllerTest.php @@ -15,7 +15,10 @@ final class ContactControllerTest extends Unit { - public mixed $tester = null; + /** + * @phpstan-var Yii2|null + */ + public $tester = null; public function testEmailIsSentOnContact(): void { @@ -31,10 +34,8 @@ public function testEmailIsSentOnContact(): void ]; verify($controller->sendEmail($form))->notEmpty(); - assert( - $this->tester instanceof Yii2, - '\'Yii2\' module should be available in the tester', - ); + + self::assertNotNull($this->tester, 'Yii2 module is not initialized'); $this->tester->seeEmailIsSent(); $emailMessage = $this->tester->grabLastSentEmail();