From 734e43004e5b24f54cc8083550844afc38e22bd2 Mon Sep 17 00:00:00 2001 From: lucas-at-3x-eye <112706698+lucas-at-3x-eye@users.noreply.github.com> Date: Fri, 4 Sep 2026 12:39:17 +0000 Subject: [PATCH] Fix/poznote - 1st party Docker parity (#17011) * fix(poznote): align nginx config with upstream Docker defaults * fix(poznote): run init.sh on install and update, not just in Docker * fix(poznote): add systemd units for the reminder-email and s3-backup workers * fix(poznote): retrofit nginx config and worker services on update, sanitize timeout comment * fix(poznote): silence init.sh output and consolidate worker enable/start * fix(poznote): update ct/poznote.sh to use new default bootstrapper --- ct/poznote.sh | 171 +++++++++++++++++++++++++++++++++++++ install/poznote-install.sh | 138 +++++++++++++++++++++++++++++- 2 files changed, 307 insertions(+), 2 deletions(-) diff --git a/ct/poznote.sh b/ct/poznote.sh index bf469c252..88ab00237 100644 --- a/ct/poznote.sh +++ b/ct/poznote.sh @@ -35,6 +35,7 @@ function update_script() { if check_for_gh_release "poznote" "timothepoznanski/poznote"; then msg_info "Stopping Service" systemctl stop nginx + systemctl stop poznote-reminder-worker poznote-s3-backup-worker 2>/dev/null || true msg_ok "Stopped Service" create_backup /var/www/html/data @@ -48,8 +49,178 @@ function update_script() { restore_backup + msg_info "Running Poznote Initialization" + chmod +x /opt/poznote/init.sh + $STD /opt/poznote/init.sh + msg_ok "Initialized Poznote Data Directory" + + msg_info "Updating Nginx Configuration" + [[ -f /etc/nginx/sites-available/poznote ]] && cp /etc/nginx/sites-available/poznote /etc/nginx/sites-available/poznote.bak + PHP_SOCK=$(get_php_fpm_socket) + cat </etc/nginx/sites-available/poznote +# The Excalidraw editor must keep its window.opener relationship with +# libraries.excalidraw.com so "Add to Excalidraw" can hand the chosen library +# back to the already-open editor tab; COOP same-origin would sever it. +map \$uri \$poznote_coop { + default "same-origin"; + /excalidraw_editor.php "unsafe-none"; +} + +server { + listen 8040; + root /var/www/html; + index index.php index.html; + + gzip on; + gzip_comp_level 5; + gzip_min_length 1024; + gzip_vary on; + gzip_proxied any; + gzip_types text/css application/javascript text/javascript application/json + image/svg+xml application/manifest+json font/ttf font/otf; + + location ~* \.webmanifest$ { + default_type application/manifest+json; + try_files \$uri =404; + } + + client_max_body_size 800M; + + location /api/v1 { + try_files \$uri \$uri/ /api/v1/index.php?\$query_string; + } + + location = /api/health { + rewrite ^ /api_health.php last; + } + + location = /api/info { + rewrite ^ /api_health.php last; + } + + location / { + try_files \$uri \$uri/ @poznote_public; + } + + location @poznote_public { + rewrite ^/folder/([^/]+)/?$ /public_folder.php?token=\$1 last; + rewrite ^/workspace/([^/]+)/?$ /public_note.php?token=\$1 last; + rewrite ^/([^/]+)/?$ /public_slug.php?slug=\$1 last; + } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Cross-Origin-Opener-Policy \$poznote_coop always; + add_header Cross-Origin-Resource-Policy "same-origin" always; + add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always; + + location ~* ^/data/.*\.(php[0-9]?|phtml|phar|pht)$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_pass unix:${PHP_SOCK}; + fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT \$document_root; + fastcgi_param PATH_INFO \$fastcgi_path_info; + + fastcgi_param HTTP_X_FORWARDED_FOR \$http_x_forwarded_for; + fastcgi_param HTTP_X_FORWARDED_PROTO \$http_x_forwarded_proto; + fastcgi_param HTTP_X_FORWARDED_HOST \$http_x_forwarded_host; + fastcgi_param HTTP_X_FORWARDED_PORT \$http_x_forwarded_port; + fastcgi_param HTTP_X_REAL_IP \$http_x_real_ip; + fastcgi_param HTTPS \$https if_not_empty; + + # fastcgi_read_timeout 600; + # fastcgi_send_timeout 600; + # Left at nginx's 60s default, not Docker's 600s: + # a stalled git-sync request can hold the PHP session lock, otherwise + } + + location ~ /\. { + deny all; + } + + location ~ ^/data/users/[0-9]+/backgrounds/ { + try_files \$uri =404; + } + + location ~ ^/data/css/[A-Za-z0-9._-]+\.css$ { + try_files \$uri =404; + } + + location ~ ^/(data|config)/ { + deny all; + } + + location ~* ^/pwa/poznote(-[0-9]+)?\.png$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header X-Content-Type-Options "nosniff" always; + add_header Cross-Origin-Resource-Policy "cross-origin" always; + try_files \$uri =404; + } + + location ~* \.(?:js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|otf|eot|webp|webmanifest)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header X-Content-Type-Options "nosniff" always; + add_header Cross-Origin-Resource-Policy "same-origin" always; + try_files \$uri =404; + } +} +EOF + msg_ok "Updated Nginx Configuration" + + if [[ ! -f /etc/systemd/system/poznote-reminder-worker.service ]]; then + msg_info "Creating Reminder Worker Service" + cat </etc/systemd/system/poznote-reminder-worker.service +[Unit] +Description=Poznote Reminder Email Worker +After=network.target + +[Service] +Type=simple +User=www-data +Group=www-data +Restart=always +ExecStart=/usr/bin/php /var/www/html/workers/reminder-email-worker.php +WorkingDirectory=/var/www/html + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + msg_ok "Created Reminder Worker Service" + fi + + if [[ ! -f /etc/systemd/system/poznote-s3-backup-worker.service ]]; then + msg_info "Creating S3 Backup Worker Service" + cat </etc/systemd/system/poznote-s3-backup-worker.service +[Unit] +Description=Poznote S3 Backup Worker +After=network.target + +[Service] +Type=simple +User=www-data +Group=www-data +Restart=always +ExecStart=/usr/bin/php /var/www/html/workers/s3-backup-worker.php +WorkingDirectory=/var/www/html + +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + msg_ok "Created S3 Backup Worker Service" + fi + msg_info "Starting Service" systemctl start nginx + systemctl enable -q --now poznote-reminder-worker poznote-s3-backup-worker msg_ok "Started Service" msg_ok "Updated successfully!" fi diff --git a/install/poznote-install.sh b/install/poznote-install.sh index 4f0f16314..55021480d 100644 --- a/install/poznote-install.sh +++ b/install/poznote-install.sh @@ -28,16 +28,73 @@ touch /var/www/html/data/database/poznote.db chown -R www-data:www-data /var/www/html msg_ok "Deployed Poznote" +msg_info "Running Poznote Initialization" +chmod +x /opt/poznote/init.sh +$STD /opt/poznote/init.sh +msg_ok "Initialized Poznote Data Directory" + msg_info "Configuring Nginx" PHP_SOCK=$(get_php_fpm_socket) cat </etc/nginx/sites-available/poznote +# The Excalidraw editor must keep its window.opener relationship with +# libraries.excalidraw.com so "Add to Excalidraw" can hand the chosen library +# back to the already-open editor tab; COOP same-origin would sever it. +map \$uri \$poznote_coop { + default "same-origin"; + /excalidraw_editor.php "unsafe-none"; +} + server { listen 8040; root /var/www/html; index index.php index.html; + gzip on; + gzip_comp_level 5; + gzip_min_length 1024; + gzip_vary on; + gzip_proxied any; + gzip_types text/css application/javascript text/javascript application/json + image/svg+xml application/manifest+json font/ttf font/otf; + + location ~* \.webmanifest$ { + default_type application/manifest+json; + try_files \$uri =404; + } + + client_max_body_size 800M; + + location /api/v1 { + try_files \$uri \$uri/ /api/v1/index.php?\$query_string; + } + + location = /api/health { + rewrite ^ /api_health.php last; + } + + location = /api/info { + rewrite ^ /api_health.php last; + } + location / { - try_files \$uri \$uri/ /index.php?\$query_string; + try_files \$uri \$uri/ @poznote_public; + } + + location @poznote_public { + rewrite ^/folder/([^/]+)/?$ /public_folder.php?token=\$1 last; + rewrite ^/workspace/([^/]+)/?$ /public_note.php?token=\$1 last; + rewrite ^/([^/]+)/?$ /public_slug.php?slug=\$1 last; + } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Cross-Origin-Opener-Policy \$poznote_coop always; + add_header Cross-Origin-Resource-Policy "same-origin" always; + add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always; + + location ~* ^/data/.*\.(php[0-9]?|phtml|phar|pht)$ { + deny all; } location ~ \.php$ { @@ -45,16 +102,93 @@ server { fastcgi_pass unix:${PHP_SOCK}; fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT \$document_root; + fastcgi_param PATH_INFO \$fastcgi_path_info; + + fastcgi_param HTTP_X_FORWARDED_FOR \$http_x_forwarded_for; + fastcgi_param HTTP_X_FORWARDED_PROTO \$http_x_forwarded_proto; + fastcgi_param HTTP_X_FORWARDED_HOST \$http_x_forwarded_host; + fastcgi_param HTTP_X_FORWARDED_PORT \$http_x_forwarded_port; + fastcgi_param HTTP_X_REAL_IP \$http_x_real_ip; + fastcgi_param HTTPS \$https if_not_empty; + + # fastcgi_read_timeout 600; + # fastcgi_send_timeout 600; + # Left at nginx's 60s default, not Docker's 600s: + # a stalled git-sync request can hold the PHP session lock, otherwise } - location ~ /\.ht { + location ~ /\. { deny all; } + + location ~ ^/data/users/[0-9]+/backgrounds/ { + try_files \$uri =404; + } + + location ~ ^/data/css/[A-Za-z0-9._-]+\.css$ { + try_files \$uri =404; + } + + location ~ ^/(data|config)/ { + deny all; + } + + location ~* ^/pwa/poznote(-[0-9]+)?\.png$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header X-Content-Type-Options "nosniff" always; + add_header Cross-Origin-Resource-Policy "cross-origin" always; + try_files \$uri =404; + } + + location ~* \.(?:js|css|png|jpg|jpeg|gif|svg|ico|woff2?|ttf|otf|eot|webp|webmanifest)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + add_header X-Content-Type-Options "nosniff" always; + add_header Cross-Origin-Resource-Policy "same-origin" always; + try_files \$uri =404; + } } EOF nginx_enable_site poznote msg_ok "Configured Nginx" +msg_info "Creating Background Worker Services" +cat </etc/systemd/system/poznote-reminder-worker.service +[Unit] +Description=Poznote Reminder Email Worker +After=network.target + +[Service] +Type=simple +User=www-data +Group=www-data +Restart=always +ExecStart=/usr/bin/php /var/www/html/workers/reminder-email-worker.php +WorkingDirectory=/var/www/html + +[Install] +WantedBy=multi-user.target +EOF +cat </etc/systemd/system/poznote-s3-backup-worker.service +[Unit] +Description=Poznote S3 Backup Worker +After=network.target + +[Service] +Type=simple +User=www-data +Group=www-data +Restart=always +ExecStart=/usr/bin/php /var/www/html/workers/s3-backup-worker.php +WorkingDirectory=/var/www/html + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now poznote-reminder-worker poznote-s3-backup-worker +msg_ok "Created Background Worker Services" + motd_ssh customize cleanup_lxc