diff --git a/docker-compose.yml b/docker-compose.yml index 0008c064..98e93884 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,23 +1,31 @@ services: #nginx webserver + php 8.x web: - image: nginx:1.25.3-alpine + build: + context: . + dockerfile: ./docker/nginx/Dockerfile ports: - "8080:80" depends_on: - db volumes: - ./:/code - - ./site.conf:/etc/nginx/conf.d/default.conf + - ./docker/nginx/leftypol.conf:/etc/nginx/conf.d/default.conf + - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf + - ./docker/nginx/proxy.conf:/etc/nginx/conf.d/proxy.conf networks: leftchan_net: ipv4_address: 172.20.0.3 links: - php php: - build: . + build: + context: . + dockerfile: ./docker/php/Dockerfile volumes: - ./:/code + - ./docker/php/custom.ini:/usr/local/etc/php/conf.d/custom.ini + - ./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf networks: leftchan_net: ipv4_address: 172.20.0.4 @@ -42,4 +50,4 @@ networks: ipam: driver: default config: - - subnet: 172.20.0.0/16 \ No newline at end of file + - subnet: 172.20.0.0/16 diff --git a/docker/common-setup.sh b/docker/common-setup.sh new file mode 100755 index 00000000..c7ea147e --- /dev/null +++ b/docker/common-setup.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +# not exactly elegant, but one container is Debian, the other is Alpine +useradd -MU leftypol +addgroup leftypol +adduser -DHG leftypol leftypol + +set -eu + +install -m 775 -o leftypol -g leftypol -d /var/www-leftypol +ln -s \ + /code/banners/ \ + /code/static/ \ + /code/stylesheets/ \ + /code/tools/ \ + /code/walls/ \ + /code/*.php \ + /code/404.html \ + /code/LICENSE.* \ + /code/robots.txt \ + /code/install.sql \ + /var/www-leftypol/ + +install -m 775 -o leftypol -g leftypol -d /var/www/js +ln -s /code/js/* /var/www/js/ + +install -m 775 -o leftypol -g leftypol -d /var/www-leftypol/templates +install -m 775 -o leftypol -g leftypol -d /var/www-leftypol/templates/cache +ln -s /code/templates/* /var/www-leftypol/templates/ + +install -m 775 -o leftypol -g leftypol -d /var/www-leftypol/inc +ln -s /code/inc/* /var/www-leftypol/inc/ diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 00000000..9c2392b2 --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +1,8 @@ +FROM nginx:1.25.3-alpine + +COPY . /code +RUN /code/docker/common-setup.sh + + +CMD ["nginx", "-g", "daemon off;"] +EXPOSE 80 443 \ No newline at end of file diff --git a/docker/nginx/leftypol.conf b/docker/nginx/leftypol.conf new file mode 100644 index 00000000..a825fea7 --- /dev/null +++ b/docker/nginx/leftypol.conf @@ -0,0 +1,68 @@ +upstream php-upstream { + server php:9000; +} + +server { + listen 80 default_server; + listen [::]:80 default_server ipv6only=on; + server_name leftypol; + root /var/www-leftypol; + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.html index.php; + + charset utf-8; + + location ~ ^([^.\?]*[^\/])$ { + try_files $uri @addslash; + } + + # Expire rules for static content + # Media: images, icons, video, audio, HTC + location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { + expires 1M; + access_log off; + log_not_found off; + add_header Cache-Control "public"; + } + # CSS and Javascript + location ~* \.(?:css|js)$ { + expires 1y; + access_log off; + log_not_found off; + add_header Cache-Control "public"; + } + + location ~* \.(html)$ { + expires -1; + } + + location @addslash { + return 301 $uri/; + } + + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + + client_max_body_size 2G; + + location ~ \.php$ { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Request-Id $x_request_id; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header Forwarded-Request-Id $x_request_id; + fastcgi_pass php-upstream; + fastcgi_index index.php; + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + fastcgi_read_timeout 600; + include fastcgi_params; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } +} \ No newline at end of file diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf new file mode 100644 index 00000000..8a42dee3 --- /dev/null +++ b/docker/nginx/nginx.conf @@ -0,0 +1,33 @@ +# This and proxy.conf are based on +# https://github.com/dead-guru/devichan/blob/master/nginx/nginx.conf + +user leftypol; +worker_processes 4; +# daemon off; +# error_log /var/log/nginx/error.log warn; +error_log /dev/stdout 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; + # Switch logging to console out to view via Docker + access_log /dev/stdout; + error_log /dev/stdout warn; + sendfile on; + keepalive_timeout 5; + + gzip on; + gzip_http_version 1.0; + gzip_vary on; + gzip_comp_level 6; + gzip_types text/xml text/plain text/css application/xhtml+xml application/xml application/rss+xml application/atom_xml application/x-javascript application/x-httpd-php; + gzip_disable "MSIE [1-6]\."; + + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-available/*.conf; +} \ No newline at end of file diff --git a/docker/nginx/proxy.conf b/docker/nginx/proxy.conf new file mode 100644 index 00000000..bc22ea34 --- /dev/null +++ b/docker/nginx/proxy.conf @@ -0,0 +1,40 @@ +proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=czone:4m max_size=50m inactive=120m; +proxy_temp_path /var/tmp/nginx; +proxy_cache_key "$scheme://$host$request_uri"; + + +map $http_forwarded_request_id $x_request_id { + "" $request_id; + default $http_forwarded_request_id; +} + +map $http_forwarded_forwarded_host $forwardedhost { + "" $host; + default $http_forwarded_forwarded_host; +} + + +map $http_x_forwarded_proto $fcgi_https { + default ""; + https on; +} + +map $http_x_forwarded_proto $real_scheme { + default $scheme; + https https; +} + +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-Host $host; +proxy_set_header X-Forwarded-Server $host; + +real_ip_header X-Forwarded-For; + +set_real_ip_from 10.0.0.0/8; +set_real_ip_from 172.16.0.0/12; +set_real_ip_from 172.18.0.0/12; +set_real_ip_from 192.168.0.0/24; +set_real_ip_from 127.0.0.0/8; + +real_ip_recursive on; \ No newline at end of file diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 00000000..2db11415 --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,44 @@ +# Based on https://github.com/dead-guru/devichan/blob/master/php-fpm/Dockerfile + +FROM composer AS composer +FROM php:8.1-fpm-bullseye +COPY --from=composer /usr/bin/composer /usr/bin/composer +COPY . /code + +RUN apt-get update && apt-get upgrade -y && apt-get install -y \ + zlib1g-dev libicu-dev g++ \ + libjpeg62-turbo-dev \ + libzip-dev \ + libpng-dev \ + libwebp-dev \ + libfreetype6-dev \ + libxml2-dev \ + git \ + zip \ + ffmpeg \ + libonig-dev \ + unzip \ + libcurl4-openssl-dev \ + libmagickwand-dev \ + gifsicle \ + graphicsmagick \ + gettext \ + imagemagick \ + locales locales-all \ + libmagickwand-dev \ + libmcrypt-dev \ + && docker-php-ext-configure gd \ + --with-webp=/usr/include/webp \ + --with-jpeg=/usr/include \ + --with-freetype=/usr/include/freetype2/ \ + && pecl install redis \ + && pecl install imagick \ + && pecl install -o -f igbinary \ + && docker-php-ext-install gd zip opcache intl pdo pdo_mysql mysqli bcmath gettext iconv mbstring curl \ + && docker-php-ext-enable igbinary redis imagick + + +RUN /code/docker/common-setup.sh +WORKDIR "/var/www-leftypol" +CMD ["php-fpm"] +EXPOSE 9000 \ No newline at end of file diff --git a/docker/php/custom.ini b/docker/php/custom.ini new file mode 100644 index 00000000..aacb2d72 --- /dev/null +++ b/docker/php/custom.ini @@ -0,0 +1,15 @@ +; based on https://github.com/dead-guru/devichan/blob/master/php-fpm/custom.ini + +memory_limit = 2G +max_execution_time = 30 +upload_max_filesize = 2G +post_max_size = 2G +pm = dynamic +pm.max_children = 20 +pm.start_servers = 5 +pm.min_spare_servers = 3 +pm.max_spare_servers = 10 + +extension = igbinary.so +extension = redis.so +extension = imagick.so \ No newline at end of file diff --git a/docker/php/www.conf b/docker/php/www.conf new file mode 100644 index 00000000..f6c4f00e --- /dev/null +++ b/docker/php/www.conf @@ -0,0 +1,10 @@ +[www] +user = leftypol +group = leftypol +listen = 127.0.0.1:9000 +pm = dynamic +pm.max_children = 200 +pm.start_servers = 10 +pm.min_spare_servers = 1 +pm.max_spare_servers = 20 +pm.max_requests = 20000