From 5417ffaa00776fb2c65e5660bd186eeb73adad5e Mon Sep 17 00:00:00 2001 From: Philipp Date: Fri, 1 Mar 2024 23:00:03 +0100 Subject: [PATCH 1/2] Add opensocial.at as example --- .examples/docker-compose/opensocial.at/.env | 1 + .../docker-compose/opensocial.at/README.md | 50 ++++++ .../opensocial.at/app/Dockerfile | 15 ++ .../opensocial.at/avatar/Dockerfile | 18 +++ .../opensocial.at/avatar/cmd.sh | 8 + .../avatar/custom-error-page.conf | 5 + .../opensocial.at/avatar/error-page.html | 94 +++++++++++ .../opensocial.at/avatar/nginx.conf | 70 +++++++++ .../avatar/templates/server_name.template | 1 + .../opensocial.at/config/app/friendica.ini | 6 + .../config/app/www.overloaded.conf | 11 ++ .../config/secrets/mysql_database.txt | 1 + .../config/secrets/mysql_password.txt | 1 + .../config/secrets/mysql_root_password.txt | 1 + .../config/secrets/mysql_user.txt | 1 + .../opensocial.at/docker-compose.yml | 148 ++++++++++++++++++ .../opensocial.at/friendica.conf | 26 +++ .../opensocial.at/web/Dockerfile | 11 ++ .../docker-compose/opensocial.at/web/cmd.sh | 8 + .../opensocial.at/web/nginx.conf | 123 +++++++++++++++ .../web/templates/server_name.template | 1 + 21 files changed, 600 insertions(+) create mode 100644 .examples/docker-compose/opensocial.at/.env create mode 100644 .examples/docker-compose/opensocial.at/README.md create mode 100644 .examples/docker-compose/opensocial.at/app/Dockerfile create mode 100644 .examples/docker-compose/opensocial.at/avatar/Dockerfile create mode 100644 .examples/docker-compose/opensocial.at/avatar/cmd.sh create mode 100644 .examples/docker-compose/opensocial.at/avatar/custom-error-page.conf create mode 100644 .examples/docker-compose/opensocial.at/avatar/error-page.html create mode 100644 .examples/docker-compose/opensocial.at/avatar/nginx.conf create mode 100644 .examples/docker-compose/opensocial.at/avatar/templates/server_name.template create mode 100644 .examples/docker-compose/opensocial.at/config/app/friendica.ini create mode 100644 .examples/docker-compose/opensocial.at/config/app/www.overloaded.conf create mode 100644 .examples/docker-compose/opensocial.at/config/secrets/mysql_database.txt create mode 100644 .examples/docker-compose/opensocial.at/config/secrets/mysql_password.txt create mode 100644 .examples/docker-compose/opensocial.at/config/secrets/mysql_root_password.txt create mode 100644 .examples/docker-compose/opensocial.at/config/secrets/mysql_user.txt create mode 100644 .examples/docker-compose/opensocial.at/docker-compose.yml create mode 100644 .examples/docker-compose/opensocial.at/friendica.conf create mode 100644 .examples/docker-compose/opensocial.at/web/Dockerfile create mode 100644 .examples/docker-compose/opensocial.at/web/cmd.sh create mode 100644 .examples/docker-compose/opensocial.at/web/nginx.conf create mode 100644 .examples/docker-compose/opensocial.at/web/templates/server_name.template diff --git a/.examples/docker-compose/opensocial.at/.env b/.examples/docker-compose/opensocial.at/.env new file mode 100644 index 0000000..8142ad9 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/.env @@ -0,0 +1 @@ +./friendica.conf diff --git a/.examples/docker-compose/opensocial.at/README.md b/.examples/docker-compose/opensocial.at/README.md new file mode 100644 index 0000000..3bc6778 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/README.md @@ -0,0 +1,50 @@ +# Opensocial.at setup + +This example of the current opensocial.at configuration has to be seen as a possible "production-ready" environment. +The focus of this configuration is on performance and scalability. + +## Prerequisites + +This setup needs some configuration first to be fully usable. + +1. It uses an external, dedicated database, which is not included here (you can just add a `mariadb` service directly) +2. avatar caching needs to be enabled + 1. Enable the system-config `system.avatar_cache` + 2. Set `avatar_cache_path` to `/var/www/avatar` +3. It uses a traefik docker service as overall reverse proxy for the whole docker environment + 1. Otherwise, adaptations of the two services `web` and `avatar` are necessary + +## The setup + +The setup splits Friendica in as much (micro)services as possible. + +### Split Frontend & Daemon + +This setup splits the frontend services from the background Daemon. +So it's possible to scale different aspect from the frontend without harming states of the cronjob forks of the Daemon. + +### Redis + +Redis is a highly optimized, in-memory key-value storage. + +The current setup uses redis for two use-cases: +- Redis as PHP overall session handler +- Redis for Friendica specific session-state handling + +### [app](./app) (php-fpm) + +The frontend logic of each user-request is computed by a php-fpm instance. +Because of the distributed session handling, it's possible to scale as much php-fpm app-instances as you need. + +### [web](./web) (nginx) + +This nginx instance is a reverse proxy for the frontend logic to avoid direct access to the php-fpm. +And it delivers static resources directly without passing the request to the php-fpm instance. + +### [avatar](./avatar) (nginx) + +This stateless nginx instance delivers all avatar-pictures of this instance. + +### [cron](./app) (php-fpm) + +The background daemon, which is based on the same image as the app-image. diff --git a/.examples/docker-compose/opensocial.at/app/Dockerfile b/.examples/docker-compose/opensocial.at/app/Dockerfile new file mode 100644 index 0000000..56eb0a0 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/app/Dockerfile @@ -0,0 +1,15 @@ +FROM friendica:fpm-alpine + +ENV FRIENDICA_UPGRADE=true +ENV PHP_MEMORY_LIMIT 2G + +# Use the default production configuration +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +ENV FRIENDICA_PHP_OUT="/var/www/html/php.out" + +RUN set -ex; \ + touch ${FRIENDICA_PHP_OUT:-"php.out"}; \ + chown www-data:www-data ${FRIENDICA_PHP_OUT:-"php.out"}; + +RUN sed -i 's/access.log = \/proc\/self\/fd\/2/access.log = \/proc\/self\/fd\/1/g' /usr/local/etc/php-fpm.d/docker.conf diff --git a/.examples/docker-compose/opensocial.at/avatar/Dockerfile b/.examples/docker-compose/opensocial.at/avatar/Dockerfile new file mode 100644 index 0000000..9c42d14 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/avatar/Dockerfile @@ -0,0 +1,18 @@ +FROM nginx:latest + +RUN usermod -u 82 www-data + +RUN set -ex; \ + mkdir -p /var/www/html; \ + mkdir -p /etc/nginx/snippets; + +COPY ./templates /etc/nginx/conf.d/templates +COPY nginx.conf /etc/nginx/nginx.conf + +COPY error-page.html /var/www/html/error-page.html +COPY custom-error-page.conf /etc/nginx/snippets/custom-error-page.conf + +COPY *.sh / +RUN chmod +x /*.sh + +CMD ["/cmd.sh"] diff --git a/.examples/docker-compose/opensocial.at/avatar/cmd.sh b/.examples/docker-compose/opensocial.at/avatar/cmd.sh new file mode 100644 index 0000000..dde131a --- /dev/null +++ b/.examples/docker-compose/opensocial.at/avatar/cmd.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -eu + +envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active +nginx -qt +until ping app -c1 > /dev/null; do sleep 1; done + +exec nginx -g 'daemon off;' diff --git a/.examples/docker-compose/opensocial.at/avatar/custom-error-page.conf b/.examples/docker-compose/opensocial.at/avatar/custom-error-page.conf new file mode 100644 index 0000000..5e8232c --- /dev/null +++ b/.examples/docker-compose/opensocial.at/avatar/custom-error-page.conf @@ -0,0 +1,5 @@ +error_page 404 403 500 503 /error-page.html; +location = /error-page.html { + root /var/www/html; + internal; +} diff --git a/.examples/docker-compose/opensocial.at/avatar/error-page.html b/.examples/docker-compose/opensocial.at/avatar/error-page.html new file mode 100644 index 0000000..3b7ea51 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/avatar/error-page.html @@ -0,0 +1,94 @@ + + + + + + + +
+
+

Sorry the page can't be loaded!

+
+

Contact the site's administrator or support for assistance.

+
+
+
+ + diff --git a/.examples/docker-compose/opensocial.at/avatar/nginx.conf b/.examples/docker-compose/opensocial.at/avatar/nginx.conf new file mode 100644 index 0000000..e12c831 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/avatar/nginx.conf @@ -0,0 +1,70 @@ +## +# Friendica Nginx configuration +# by Olaf Conradi, modified by Philipp Holzer +# +worker_processes 4; + +events { + worker_connections 1024; +} + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +http { + map $request_id $formatted_id { + "~*(?[0-9a-f]{8})(?[0-9a-f]{4})(?[0-9a-f]{4})(?[0-9a-f]{4})(?.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}"; + } + + map $http_x_request_id $uuid { + default "${request_id}"; + ~* "${http_x_request_id}"; + } + + charset utf-8; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format logger-json escape=json '{"source": "nginx", "time": $msec, "resp_body_size": $body_bytes_sent, "host": "$http_host", "address": "$remote_addr", "request_length": $request_length, "method": "$request_method", "uri": "$request_uri", "status": $status, "user_agent": "$http_user_agent", "resp_time": $request_time, "upstream_addr": "$upstream_addr", "request_id": "$uuid"}'; + + 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 logger-json; + log_not_found off; + + # If behind reverse proxy, forwards the correct IP + set_real_ip_from 10.0.0.0/8; + set_real_ip_from 172.16.0.0/12; + set_real_ip_from 192.168.0.0/16; + set_real_ip_from fc00::/7; + real_ip_header X-Real-IP; + + server { + listen 80; + include /etc/nginx/conf.d/server_name.active; + include /etc/nginx/snippets/custom-error-page.conf; + #Uncomment the following line to include a standard configuration file + #Note that the most specific rule wins and your standard configuration + #will therefore *add* to this file, but not override it. + #include standard.conf + # allow uploads up to 20MB in size + client_max_body_size 20m; + client_body_buffer_size 128k; + + add_header X-Request-ID $uuid; + + location /avatar/ { + root /var/www/; + } + + include mime.types; + + # deny access to all dot files + location ~ /\. { + deny all; + } + } +} diff --git a/.examples/docker-compose/opensocial.at/avatar/templates/server_name.template b/.examples/docker-compose/opensocial.at/avatar/templates/server_name.template new file mode 100644 index 0000000..5b9c2bd --- /dev/null +++ b/.examples/docker-compose/opensocial.at/avatar/templates/server_name.template @@ -0,0 +1 @@ +server_name ${HOSTNAME}; diff --git a/.examples/docker-compose/opensocial.at/config/app/friendica.ini b/.examples/docker-compose/opensocial.at/config/app/friendica.ini new file mode 100644 index 0000000..c13e030 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/config/app/friendica.ini @@ -0,0 +1,6 @@ +[PHP] +memory_limit = 8G +upload_max_filesize= 10G +post_max_size = 11G +max_execution_time = 3600 +max_input_time = 3600 diff --git a/.examples/docker-compose/opensocial.at/config/app/www.overloaded.conf b/.examples/docker-compose/opensocial.at/config/app/www.overloaded.conf new file mode 100644 index 0000000..3dfad7a --- /dev/null +++ b/.examples/docker-compose/opensocial.at/config/app/www.overloaded.conf @@ -0,0 +1,11 @@ +[www] +pm = dynamic +pm.max_children=100 +pm.start_servers=10 +pm.min_spare_servers = 4 +pm.max_spare_servers = 10 +;pm.process_idle_timeout = 10s; +;pm.max_requests = 1000 + +clear_env = no +catch_workers_output = yes diff --git a/.examples/docker-compose/opensocial.at/config/secrets/mysql_database.txt b/.examples/docker-compose/opensocial.at/config/secrets/mysql_database.txt new file mode 100644 index 0000000..ce3a79c --- /dev/null +++ b/.examples/docker-compose/opensocial.at/config/secrets/mysql_database.txt @@ -0,0 +1 @@ +friendica diff --git a/.examples/docker-compose/opensocial.at/config/secrets/mysql_password.txt b/.examples/docker-compose/opensocial.at/config/secrets/mysql_password.txt new file mode 100644 index 0000000..d4e0464 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/config/secrets/mysql_password.txt @@ -0,0 +1 @@ +PLEASE_CHANGE_ME diff --git a/.examples/docker-compose/opensocial.at/config/secrets/mysql_root_password.txt b/.examples/docker-compose/opensocial.at/config/secrets/mysql_root_password.txt new file mode 100644 index 0000000..d4e0464 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/config/secrets/mysql_root_password.txt @@ -0,0 +1 @@ +PLEASE_CHANGE_ME diff --git a/.examples/docker-compose/opensocial.at/config/secrets/mysql_user.txt b/.examples/docker-compose/opensocial.at/config/secrets/mysql_user.txt new file mode 100644 index 0000000..6564da0 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/config/secrets/mysql_user.txt @@ -0,0 +1 @@ +friendica-user diff --git a/.examples/docker-compose/opensocial.at/docker-compose.yml b/.examples/docker-compose/opensocial.at/docker-compose.yml new file mode 100644 index 0000000..7e8d4b7 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/docker-compose.yml @@ -0,0 +1,148 @@ +version: '3' +services: + + redis: + image: redis + restart: always + volumes: + - friendica-redis-vol-1:/data + command: + - --save 60 1 + - --loglevel warning + + app: + build: ./app + restart: always + command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" + deploy: + replicas: 3 + resources: + limits: + cpus: '5.00' + memory: '10g' + reservations: + cpus: '1.00' + memory: '1.5g' + depends_on: + - redis + volumes: + - friendica-vol-1:/var/www/html + - friendica-avatar-1:/var/www/avatar + - ./config/app/www.overload.conf:/usr/local/etc/php-fpm.d/www.overload.conf:ro + - ./config/app/friendica.ini:/usr/local/etc/php/conf.d/friendica.ini:ro + environment: + - MYSQL_USER_FILE=/run/secrets/mysql_user + - MYSQL_PASSWORD_FILE=/run/secrets/mysql_password + - MYSQL_DATABASE_FILE=/run/secrets/mysql_database + - MYSQL_HOST=${DBHOST} + - MYSQL_PORT=${DBPORT} + - FRIENDICA_ADMIN_MAIL=${MAILNAME} + - FRIENDICA_TZ=${TZ} + - FRIENDICA_LANG=${LANGUAGE} + - FRIENDICA_UPDATE=true + - SITENAME=${SITENAME} + - SMTP=${SMTP} + - SMTP_DOMAIN=${SMTP_DOMAIN} + - SMTP_AUTH_USER=${SMTP_AUTH_USER} + - SMTP_AUTH_PASS=${SMTP_AUTH_PASS} + - SMTP_TLS=${SMTP_TLS} + - SMTP_STARTTLS=${SMTP_STARTTLS} + - REDIS_HOST=redis + - FRIENDICA_DISTRIBUTED_CACHE_DRIVER=redis + - FRIENDICA_LOGGER=syslog + - FRIENDICA_SYSLOG_FLAGS=39 + - FRIENDICA_DATA=Filesystem + - FRIENDICA_DEBUGGING=true + secrets: + - mysql_database + - mysql_user + - mysql_password + + cron: + build: ./app + restart: always + volumes: + - friendica-vol-1:/var/www/html + - friendica-avatar-1:/var/www/avatar + - ./config/app/www.overloaded.conf:/usr/local/etc/php-fpm.d/www.overloaded.conf:ro + - ./config/app/friendica.ini:/usr/local/etc/php/conf.d/friendica.ini:ro + environment: + - SITENAME=${SITENAME} + - SMTP=${SMTP} + - SMTP_DOMAIN=${SMTP_DOMAIN} + - SMTP_AUTH_USER=${SMTP_AUTH_USER} + - SMTP_AUTH_PASS=${SMTP_AUTH_PASS} + - SMTP_TLS=${SMTP_TLS} + - SMTP_STARTTLS=${SMTP_STARTTLS} + - MYSQL_HOST=${DBHOST} + - MYSQL_PORT=${DBPORT} + - MYSQL_USERNAME=${DBUSER} + - MYSQL_PASSWORD=${DBPASS} + - MYSQL_DATABASE=${DBDATA} + - FRIENDICA_ADMIN_MAIL=${MAILNAME} + - FRIENDICA_DISTRIBUTED_CACHE_DRIVER=redis + - FRIENDICA_DEBUGGING=true + - FRIENDICA_LOGLEVEL=notice + - FRIENDICA_LOGGER=syslog + - FRIENDICA_SYSLOG_FLAGS=39 + depends_on: + - app + entrypoint: /cron.sh + + avatar: + build: ./avatar + deploy: + replicas: 3 + restart: on-failure:3 + volumes: + - friendica-avatar-1:/var/www/avatar:ro + environment: + - HOSTNAME=${HOSTNAME} + networks: + - web + labels: + - "traefik.enable=true" + - "traefik.http.routers.avatar.entrypoints=websecure" + - "traefik.http.routers.domain.rule=(Host(`www.your.domain`) || Host(`your.domain`)) && PathPrefix(`/avatar`)" + - "traefik.http.routers.domain.middlewares=https-chain@file" + - "traefik.http.routers.domain.tls=true" + - "traefik.http.routers.domain.tls.certresolver=default" + + web: + build: ./web + restart: always + deploy: + replicas: 3 + volumes: + - friendica-vol-1:/var/www/html:ro + environment: + - HOSTNAME=${HOSTNAME} + depends_on: + - app + networks: + - web + - default + labels: + - "traefik.enable=true" + - "traefik.http.routers.yourdomain.entrypoints=websecure" + - "traefik.http.routers.yourdomain.rule=Host(`www.your.domain`) || Host(`your.domain`)" + - "traefik.http.routers.yourdomain.middlewares=https-chain@file" + - "traefik.http.routers.yourdomain.tls=true" + - "traefik.http.routers.yourdomain.tls.certresolver=default" + +secrets: + mysql_database: + file: ./config/secrets/mysql_database.txt + mysql_user: + file: ./config/secrets/mysql_user.txt + mysql_password: + file: ./config/secrets/mysql_password.txt + +volumes: + friendica-avatar-1: + friendica-vol-1: + friendica-redis-vol-1: + +networks: + web: + external: true diff --git a/.examples/docker-compose/opensocial.at/friendica.conf b/.examples/docker-compose/opensocial.at/friendica.conf new file mode 100644 index 0000000..427de65 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/friendica.conf @@ -0,0 +1,26 @@ +# ------------------------------ +# friendica configuration +# ------------------------------ +# example.org is _not_ a valid hostname, use a fqdn here. +HOSTNAME=example.org +# ------------------------------ +# SQL database configuration +# ------------------------------ +DBHOST=db +DBPORT=3306 + +SITENAME="My SiteName" + +# Your timezone +TZ=Europe/Berlin + +MAILNAME=admin@philipp.info + +SMTP=mail +SMTP_DOMAIN=my.domain +SMTP_AUTH_USER=smtp_user +SMTP_AUTH_PASS=smpt_pass +SMTP_TLS=true +SMTP_STARTTLS=true + +LANGUAGE=de diff --git a/.examples/docker-compose/opensocial.at/web/Dockerfile b/.examples/docker-compose/opensocial.at/web/Dockerfile new file mode 100644 index 0000000..94d93f2 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/web/Dockerfile @@ -0,0 +1,11 @@ +FROM nginx:latest + +RUN usermod -u 82 www-data + +COPY ./templates /etc/nginx/conf.d/templates +COPY nginx.conf /etc/nginx/nginx.conf + +COPY *.sh / +RUN chmod +x /*.sh + +CMD ["/cmd.sh"] diff --git a/.examples/docker-compose/opensocial.at/web/cmd.sh b/.examples/docker-compose/opensocial.at/web/cmd.sh new file mode 100644 index 0000000..dde131a --- /dev/null +++ b/.examples/docker-compose/opensocial.at/web/cmd.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -eu + +envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active +nginx -qt +until ping app -c1 > /dev/null; do sleep 1; done + +exec nginx -g 'daemon off;' diff --git a/.examples/docker-compose/opensocial.at/web/nginx.conf b/.examples/docker-compose/opensocial.at/web/nginx.conf new file mode 100644 index 0000000..e139d24 --- /dev/null +++ b/.examples/docker-compose/opensocial.at/web/nginx.conf @@ -0,0 +1,123 @@ +## +# Friendica Nginx configuration +# by Olaf Conradi, modified by Philipp Holzer +# +#worker_processes 4; + +events { + worker_connections 1024; +} + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +http { + map $request_id $formatted_id { + "~*(?[0-9a-f]{8})(?[0-9a-f]{4})(?[0-9a-f]{4})(?[0-9a-f]{4})(?.*)$" "${p1}-${p2}-${p3}-${p4}-${p5}"; + } + + map $http_x_request_id $uuid { + default "${request_id}"; + ~* "${http_x_request_id}"; + } + + charset utf-8; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format logger-json escape=json '{"source": "nginx", "time": $msec, "resp_body_size": $body_bytes_sent, "host": "$http_host", "address": "$remote_addr", "request_length": $request_length, "method": "$request_method", "uri": "$request_uri", "status": $status, "user_agent": "$http_user_agent", "resp_time": $request_time, "upstream_addr": "$upstream_addr", "request_id": "$uuid"}'; + + 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 logger-json; + + # If behind reverse proxy, forwards the correct IP + set_real_ip_from 10.0.0.0/8; + set_real_ip_from 172.16.0.0/12; + set_real_ip_from 192.168.0.0/16; + set_real_ip_from fc00::/7; + real_ip_header X-Real-IP; + + upstream php-handler { + server app:9000; + } + + server { + listen 80; + include /etc/nginx/conf.d/server_name.active; + + index index.php; + + root /var/www/html; + #Uncomment the following line to include a standard configuration file + #Note that the most specific rule wins and your standard configuration + #will therefore *add* to this file, but not override it. + #include standard.conf + # allow uploads up to 20MB in size + client_max_body_size 20m; + client_body_buffer_size 128k; + + proxy_set_header X-Request-ID $uuid; + add_header X-Request-ID $uuid; + + # rewrite to front controller as default rule + location / { + try_files $uri /index.php?pagename=$uri&$args; + } + + # make sure webfinger and other well known services aren't blocked + # by denying dot files and rewrite request to the front controller + location ^~ /.well-known/ { + allow all; + try_files $uri /index.php?pagename=$uri&$args; + } + + # statically serve these file types when possible + # otherwise fall back to front controller + # allow browser to cache them + # added .htm for advanced source code editor library + #location ~* \.(jpg|jpeg|gif|png|ico|css|js|htm|html|ttf|woff|svg)$ { + # expires 30d; + # try_files $uri /index.php?pagename=$uri&$args; + #} + + include mime.types; + + # block these file types + location ~* \.(tpl|md|tgz|log|out)$ { + deny all; + } + + # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 + # or a unix socket + location ~* \.php$ { + # Zero-day exploit defense. + # http://forum.nginx.org/read.php?2,88845,page=3 + # Won't work properly (404 error) if the file is not stored on this + # server, which is entirely possible with php-fpm/php-fcgi. + # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on + # another machine. And then cross your fingers that you won't get hacked. + try_files $uri =404; + + # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini + fastcgi_split_path_info ^(.+\.php)(/.+)$; + + fastcgi_pass php-handler; + + fastcgi_read_timeout 300; + + include fastcgi_params; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param HTTP_X_REQUEST_ID $uuid; + } + + # deny access to all dot files + location ~ /\. { + deny all; + } + } +} diff --git a/.examples/docker-compose/opensocial.at/web/templates/server_name.template b/.examples/docker-compose/opensocial.at/web/templates/server_name.template new file mode 100644 index 0000000..5b9c2bd --- /dev/null +++ b/.examples/docker-compose/opensocial.at/web/templates/server_name.template @@ -0,0 +1 @@ +server_name ${HOSTNAME}; From 4b63f129278e2238a6000d320b8851f3f7d8bd99 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sat, 2 Mar 2024 09:29:47 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Hypolite Petovan --- .../docker-compose/opensocial.at/README.md | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/.examples/docker-compose/opensocial.at/README.md b/.examples/docker-compose/opensocial.at/README.md index 3bc6778..6a5dc46 100644 --- a/.examples/docker-compose/opensocial.at/README.md +++ b/.examples/docker-compose/opensocial.at/README.md @@ -1,49 +1,48 @@ # Opensocial.at setup -This example of the current opensocial.at configuration has to be seen as a possible "production-ready" environment. -The focus of this configuration is on performance and scalability. +This configuration running at https://opensocial.at is an example of "production-ready" environment. +It focuses on performance and scalability. ## Prerequisites -This setup needs some configuration first to be fully usable. +This setup needs some configuration first to be usable as-is. -1. It uses an external, dedicated database, which is not included here (you can just add a `mariadb` service directly) -2. avatar caching needs to be enabled - 1. Enable the system-config `system.avatar_cache` - 2. Set `avatar_cache_path` to `/var/www/avatar` -3. It uses a traefik docker service as overall reverse proxy for the whole docker environment - 1. Otherwise, adaptations of the two services `web` and `avatar` are necessary +1. It uses an external, dedicated database, which is not included here (you can just add a `mariadb` service directly). +2. Avatar caching needs to be enabled + 1. Enable the system-config `system.avatar_cache`. + 2. Set `avatar_cache_path` to `/var/www/avatar`. +3. It uses a Traefik Docker service as overall reverse proxy for the whole Docker environment. + 1. Otherwise, adaptations of the two services `web` and `avatar` are necessary. ## The setup -The setup splits Friendica in as much (micro)services as possible. +The setup splits Friendica in as many services as possible. ### Split Frontend & Daemon -This setup splits the frontend services from the background Daemon. -So it's possible to scale different aspect from the frontend without harming states of the cronjob forks of the Daemon. +This setup splits the frontend services from the background daemon so that it's possible to scale the different aspects of the frontend without harming the state of the cronjob forks of the daemon. ### Redis Redis is a highly optimized, in-memory key-value storage. -The current setup uses redis for two use-cases: -- Redis as PHP overall session handler -- Redis for Friendica specific session-state handling +The current setup uses Redis for two features: +- PHP native session handling. +- Friendica-specific session handling. ### [app](./app) (php-fpm) -The frontend logic of each user-request is computed by a php-fpm instance. -Because of the distributed session handling, it's possible to scale as much php-fpm app-instances as you need. +Each incoming HTTP request is processed by a php-fpm instance. +Thanks to the distributed session handling, it's possible to spawn as many `app` instances as you need. ### [web](./web) (nginx) -This nginx instance is a reverse proxy for the frontend logic to avoid direct access to the php-fpm. -And it delivers static resources directly without passing the request to the php-fpm instance. +This nginx instance is a reverse proxy for incoming HTTP requests. +It serves static resources directly and passes the script requests to the php-fpm instance. ### [avatar](./avatar) (nginx) -This stateless nginx instance delivers all avatar-pictures of this instance. +This stateless nginx instance serves all avatar pictures of this Friendica node. ### [cron](./app) (php-fpm)