QNAP jako hosting strony WWW - nginx, php-fpm, mariadb

Jak wiadomo jestem od dawna zwolennikiem nginx. Niestety QNAP podaje strony z wykorzystaniem Apache. Jednak tutaj z pomocą przychodzi nam docker oraz Container Station (który uprzednio musimy mieć zainstalowany).
Docker został stworzony do „separacji”/uruchamiania tylko aplikacji, nie cały systemów, jednak można je linkować. Dzięki temu tworzymy aplikację która składa się z kilku osobnych kontenerów.
Zatem w pierwszej kolejności trzeba przygotować strukturę:

Czyli całość (pliki strony, bazy, konfiguracyjne oraz logi) będą trzymane na QNAP w /share/Web. Tworzę katalog 8px.pl jako domenę a w nim katalogi:
- app – pliki strony
- database – pliki MariaDB
- fpm – pliki konfiguracyjne PHP-FPM
- logs – logi nginx
- nginx – konfiguracja serwera www
Teraz musimy przygotować wspomniane pliki konfiguracyjne, i tak PHP-FPM /share/Web/8px.pl/fpm/pool.conf
[www.8px.pl] user = www-data group = www-data listen 127.0.0.1:9000 listen.owner = www-data listen.group = www-data listen.mode = 0666 listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200 ;pm.status_path = /status ;ping.path = /ping ;ping.response = pong ;access.log = /web/www.8px.pl/log/php-access.log ;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" ;slowlog = log/$pool.log.slow ;request_slowlog_timeout = 0 request_terminate_timeout = 120s rlimit_files = 131072 rlimit_core = 2 chdir = /web/www.8px.pl/app security.limit_extensions = .php env[HOSTNAME] = www.8px.pl env[PATH] = /usr/local/bin:/usr/bin:/bin env[HOME] = /web/www.8px.pl/app env[USER] = www.8px.pl php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f [email protected] php_flag[display_errors] = off php_admin_value[error_log] = /web/www.8px.pl/log/php-error.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 64M php_admin_value[disable_functions] = dl,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source php_admin_flag[opcache.enable] = on
Jak widać instancja nazywa się www.8px.pl, będzie działać na porcie 9000 z wykorzystaniem usera www-data. Sama konfiguracja nie jest domyślną.
Teraz serwer WWW i tak /share/Web/8px.pl/nginx/nginx.conf
user www-data; worker_processes auto; pid /var/run/nginx.pid; worker_rlimit_nofile 100000; working_directory /tmp/; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 4000; multi_accept on; use epoll; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 30; keepalive_requests 100000; types_hash_max_size 2048; server_tokens off; client_max_body_size 40m; client_body_timeout 10; client_header_timeout 10; client_body_buffer_size 256k; client_header_buffer_size 8k; large_client_header_buffers 4 16k; send_timeout 2; reset_timedout_connection on; charset utf-8; server_names_hash_max_size 8192; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; resolver 8.8.8.8 ipv6=off; include /etc/nginx/mime.types; default_type application/octet-stream; access_log off; error_log /var/log/nginx/error.log; gzip on; gzip_http_version 1.1; gzip_comp_level 6; gzip_proxied expired no-cache no-store private auth; gzip_static on; gzip_min_length 1100; gzip_buffers 16 8k; gzip_disable "MSIE [1-6]\."; gzip_vary on; gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype application/vnd.ms-fontobject image/svg+xml; fastcgi_send_timeout 10; fastcgi_read_timeout 10; fastcgi_buffer_size 16k; fastcgi_buffers 4 16k; add_header X-Hoster "8px.pl"; limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; log_format postlog $request_body; index index.php index.htm index.html; include /etc/nginx/conf.d/*.conf; }
To też nie jest konfiguracja domyślna, proszę też pamiętać aby wykonać modyfikację pod swoje wymagania. Jeszcze ostatni plik z deklaracjami vhost /share/Web/8px.pl/nginx/default.conf
server { index index.php index.html; server_name www.8px.pl; error_log /web/www.8px.pl/logs/error.log; access_log /web/www.8px.pl/logs/access.log; root /web/www.8px.pl/app; location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }
Teraz pozostaje nam uruchomić całe środowisko. Zatem wybieramy tworzenie nowego kontenera w CS na QNAP i tym razem nic nie szukamy, a klikamy tworzenie aplikacji:

Teraz w oknie dodajemy plik dla docker-compose który wykona zadanie:

version: '3' services: php: image: php:7.2-fpm restart: always volumes: - /share/Web/8px.pl/fpm/pool.conf:/etc/php/7.2/fpm/pool.d/pool.conf - /share/Web/8px.pl/app/:/web/www.8px.pl/app ports: - "9000:9000" links: - db hostname: www.8px.pl web: image: nginx restart: always volumes: - /share/Web/8px.pl/nginx/nginx.conf:/etc/nginx/nginx.conf - /share/Web/8px.pl/nginx/default.conf:/etc/nginx/conf.d/default.conf - /share/Web/8px.pl/logs/:/web/www.8px.pl/logs - /share/Web/8px.pl/app/:/web/www.8px.pl/app ports: - "88:80" - "4443:443" links: - php db: image: mariadb restart: always environment: - MYSQL_ROOT_PASSWORD=yourpassword volumes: - /share/Web/8px.pl/database:/var/lib/mysql
Jaka widać mamy zdefiniowane usługi które mają być zainstalowane, voluminy do zamontowania oraz na końcu hasło do bazy SQL – proszę podać swoje, należy też ustawić porty serwera WWW.
Gotowa aplikacja:

Wynik phpinfo dla takiej aplikacji.

Tutaj tylko dodam, iż to jest dobry początek do dalszych prac, warto w przyszłości bliskiej pomyśleć o SSL/HTTP2 z wykorzystaniem nginx jako revers proxy dla kontenerów, letsencrypt