Skip to content

Instantly share code, notes, and snippets.

@ryumada
Last active November 12, 2025 03:35
Show Gist options
  • Save ryumada/67004fbc20bc932c5e9dc3ea9ca8bf0d to your computer and use it in GitHub Desktop.
Save ryumada/67004fbc20bc932c5e9dc3ea9ca8bf0d to your computer and use it in GitHub Desktop.
Nginx Configuration to run PHP GetSimple CMS
# use ctrl + f and find 'enter' keyword to find out which section should be changed.
# This upstream block defines the location of your PHP-FPM service.
upstream enter_your_domain_or_upstream_name {
# This is the IP and port of your PHP-FPM container.
# ex: 127.0.0.1:9000 or php-fpm_container_name:9000
server enter_php_fpm_ip:port;
}
# This server block listens on port 80 and redirects all HTTP traffic to HTTPS.
server {
listen 80;
server_name enter_your_domain_or_upstream_name;
# This security check ensures that only requests for your domain are processed.
if ($host != "enter_your_domain_or_upstream_name") {
return 403;
}
return 301 https://$host$request_uri;
}
# This is the main server block for handling HTTPS traffic.
server {
listen 443 ssl http2;
server_name enter_your_domain_or_upstream_name;
# --- Security Hardening ---
# Hide Nginx Version
server_tokens off;
# HSTS Header (Uncomment when you are sure SSL is stable)
# WARNING: Once enabled, browsers will refuse HTTP for the 'max-age' duration.
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header X-XSS-Protection "1; mode=block" always;
# Limit HTTP methods to only common ones
if ($request_method !~ ^(GET|POST|HEAD)$ ) {
return 405;
}
# --- End Security Hardening ---
# Another security check for HTTPS.
if ($host != "enter_your_domain_or_upstream_name") {
return 403;
}
# The 'root' directive MUST point to the full path of your website's files
# on the host machine's filesystem.
# ex enter: /opt/mywebsite/app/httpdocs
root enter_path_to_your_host_web_root;
index index.php index.html index.htm;
# SSL configuration, replace these with your own certificate paths.
ssl_certificate /etc/letsencrypt/live/enter_your_domain_or_upstream_name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/enter_your_domain_or_upstream_name/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Proxy logs, adjust the path and filename as needed.
access_log /var/log/nginx/enter_your_domain_or_upstream_name.access.log;
error_log /var/log/nginx/enter_your_domain_or_upstream_name.error.log;
# --- Gzip and Charset (from .htaccess) ---
charset utf-8;
autoindex off;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# --- End Gzip ---
# ErrorDocument 404 /404.php
error_page 404 /404.php;
# --- Location Blocks ---
# This is the new main location block.
# It replaces your old `location /` block.
location / {
try_files $uri $uri/ @getsimple;
}
# This new named location handles all the GetSimple rewrites
location @getsimple {
# RewriteRule ^(bm|cn)/(.*?/)?([A-Za-z0-9-]+)/?$ index.php?id=$3&lang=$1 [QSA,L]
rewrite ^/(bm|cn)/(.*?/)?([A-Za-z0-9-]+)/?$ /index.php?id=$3&lang=$1&$args last;
# RewriteRule ^(bm|cn)/?$ index.php?lang=$1 [QSA,L]
rewrite ^/(bm|cn)/?$ /index.php?lang=$1&$args last;
# RewriteRule ^(.*?/)?([A-Za-z0-9-]+)/?$ index.php?id=$2&lang=en [QSA,L]
rewrite ^/(.*?/)?([A-Za-z0-9-]+)/?$ /index.php?id=$2&lang=en&$args last;
# Fallback for homepage or other requests that don't match
rewrite ^/ /index.php?$args last;
}
# This location block handles all PHP files by passing them to PHP-FPM.
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass enter_your_domain_or_upstream_name;
fastcgi_index index.php;
include fastcgi_params;
# The SCRIPT_FILENAME MUST be the path to the website's files
# as seen from INSIDE the Docker container's filesystem.
# ex enter: /var/www/html/httpdocs$fastcgi_script_name
fastcgi_param SCRIPT_FILENAME enter_path_inside_container_to_web_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
# --- Security File Restrictions ---
# Deny access to GetSimple config file
location = /gsconfig.php {
deny all;
}
# Global restrictions for security.
location ~ /\. {
deny all;
}
# Deny PHP execution in upload folders
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
# Allow sitemap.xml
location = /sitemap.xml {
allow all;
log_not_found off;
}
# Block all other .xml files
location ~ \.xml$ {
deny all;
}
# This block handles all requests for static files, like images, CSS, and JS.
# It's a performance optimization to enable long-term browser caching.
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|eot|otf|ttf|woff|woff2|map)$ {
expires 30d;
log_not_found off;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment