Nginx sebagai Proksi Songsang untuk Pelbagai Backend
Arch Linux

Rajah: Aliran trafik daripada Nginx ke backend seperti Apache, Flask, dan Laravel.
Dalam pembangunan perisian moden, kita jarang bergantung kepada satu teknologi sahaja. Saya sediakan catatan ini bagi memaparkan bagaimana Nginx
boleh digunakan sebagai proksi songsang untuk menyatukan pelbagai pelayan latar; Apache
, Flask
(melalui Gunicorn
), dan Laravel
(melalui PHP-FPM
), dalam satu mesin pembangunan berasaskan Arch Linux
.
Sebelum melangkah lebih jauh, pastikan anda telah menyediakan konfigurasi asas seperti yang diterangkan dalam catatan saya terdahulu: Konfigurasi LEMP dalam Arch Linux.
Saya tak pastilah penyusunan konfigurasi untuk distribusi selain Arch Linux
, tapi mungkin tidak jauh beza pun.
Senibina Pelayan
Berikut ialah senarai pelayan yang digunakan dalam sistem ini:
Pelayan | Konfigurasi Server | Domain | Port Mapping | Catatan |
---|---|---|---|---|
localhost | Nginx | localhost | 80 | Akar direktori untuk pembangunan umum |
audio-server | Nginx → Gunicorn + Flask | audio.loc | 80 → 5000 | Aplikasi pelayan audio dengan Flask |
laravel | Nginx → Laravel + PHP-FPM | localhost | 80 → 8000 | Laravel dengan frontend Vite1 |
webakaun | Nginx → Apache + PHP-FPM | localhost | 81 → 8100 | Aplikasi PHP + MariaDB yang dibina sendiri |
composer run dev
, yang memanggil pelayan Vite.localhost
dikekalkan untuk beberapa pelayan aplikasi bagi mengelakkan isu seperti cookie
tidak diterima pelayar, amaran keselamatan, atau masalah keserasian dalam mod pembangunan.Kenapa Gunakan Nginx sebagai Proksi Songsang?
Prestasi tinggi: Sesuai untuk mengendalikan sambungan selari.
Fleksibel: Boleh mengarah permintaan ke pelbagai pelayan latar (Apache, Flask, Node.js dsb).
Kefungsian caching dan pengendalian statik secara efisien.
Kawalan penuh: Boleh digabungkan dengan pengesahan, log, penghalaan pintar dan sekuriti.
Apache & PHP-FPM
Pemasangan pakej
sudo pacman -S apache php-fpm
Sunting fail utama Apache
/etc/httpd/conf/httpd.conf
# Tukar port kepada 8100:
Listen 8100
# Nyahkomen modul-modul yang diperlukan:
LoadModule headers_module modules/mod_headers.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
# Sertakan fail konfigurasi tambahan:
Include conf/extra/httpd-vhosts.conf
Include conf/extra/php-fpm.conf
Konfigurasi untuk Virtual Host Apache
/etc/httpd/conf/extra/httpd-vhosts.conf
<VirtualHost *:8100>
ServerAdmin webmaster@localhost
DocumentRoot "/srv/http/webakaun"
ErrorLog "/var/log/httpd/webakaun-error_log"
CustomLog "/var/log/httpd/webkaun-access_log" common
<Directory "/srv/http/webakaun">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Konfigurasi PHP-FPM
Tambahkan fail berikut:
bash
touch /etc/httpd/conf/extra/php-fpm.conf
/etc/httpd/conf/extra/php-fpm.conf
DirectoryIndex index.php index.html
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
</FilesMatch>
Nota: Pastikan php-fpm
dikonfigurasikan untuk mendengar pada soket UNIX
.
Nginx
Tambah baris berikut ke dalam fail konfigurasi utama nginx
pada blok http
:
/etc/nginx/nginx.conf
http {
...
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_disable "msie6";
gzip_types
application/javascript
application/json
application/xml
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/font-woff2
font/woff
font/woff2
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component
text/xml
text/javascript;
}
Untuk mengoptimumkan prestasi pelayan web,
Nginx
boleh dikonfigurasi untuk memampatkan respons HTTP
menggunakan gzip
. Hal ini membantu mempercepat pemuatan halaman dan mengurangkan penggunaan jalur lebar, terutamanya untuk fail-fail seperti JavaScript, CSS, JSON, SVG
dan jenis MIME
lain.Contoh Konfigurasi Pelayan Nginx (tanpa SSL)
localhost
Sedikit perubahan kepada konfigurasi asal:
/etc/nginx/sites-available/localhost
server {
listen 80 default_server;
server_name localhost;
# < Salin semua blok seterusnya dari konfigurasi server dalam catatan lama saya,
# "https://wraihan.com/posts/konfigurasi-lemp-dalam-arch-linux#server-localhost" >
error_log /var/log/nginx/localhost_error.log;
access_log /var/log/nginx/localhost_access.log;
}
audio-server
/etc/nginx/sites-available/audio-server
server {
listen 80;
server_name audio.loc;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "no-referrer-when-downgrade";
# Serve static files (CSS/JS)
location /static/ {
alias /home/<user>/webdev/python/audio-server/static/;
access_log off;
autoindex off;
expires 30d;
add_header Cache-Control "public";
}
# Media files (MP3s)
location /media/ {
alias /home/<user>/webdev/python/audio-server/media/;
access_log off;
autoindex off;
expires 30d;
add_header Cache-Control "public";
add_header Accept-Ranges bytes;
}
# Proxy everything else to Flask
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_log /var/log/nginx/audio-server_error.log;
access_log /var/log/nginx/audio-server_access.log;
}
/etc/hosts
:127.0.0.1 audio.loc
laravel
Nota: Laravel menggunakan index.php
sebagai titik masuk. Nginx perlu menggunakan try_files
untuk menyemak kewujudan fail atau folder sebelum menyerahkan ke index.php
. Jika menggunakan Vite semasa pembangunan, gunakan pelayan Vite pada port 8000 untuk frontend.
/etc/nginx/sites-available/laravel
server {
listen 80;
server_name _;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "no-referrer-when-downgrade";
root /home/<user>/webdev/php_sql/Laravel/inertia/public;
index index.php;
# Serve static files with cache headers
location ~* \.(?:css|js|woff2?|eot|ttf|otf|svg|jpg|jpeg|png|gif|ico|webp)$ {
expires 30d;
access_log off;
add_header Cache-Control "public, immutable";
}
# Laravel routes
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP handling
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
}
# Prevent access to .env and hidden files
location ~ /\.(?!well-known).* {
deny all;
}
error_log /var/log/nginx/laravel_error.log;
access_log /var/log/nginx/laravel_access.log;
}
Tips untuk edit CSS / JS:
- Jalankan “
php artisan optimize:clear
” untuk pastikan semua betul-betul bersih; - Kemudian bina semula dengan “
npm run build
” ; - dan laksanakan percubaan akhir dengan perintah “
composer run dev
”.
webakaun
Merupakan proksi songsang ke Apache. Rujuk konfigurasi “/etc/http/conf/extra/httpd-vhosts.conf
” di atas.
/etc/nginx/sites-available/webakaun
server {
listen 81;
server_name _;
# Proxy to Apache or other backend (listening on port 8100)
location / {
proxy_pass http://127.0.0.1:8100;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_log /var/log/nginx/webakaun_error.log;
access_log /var/log/nginx/webakaun_access.log;
}

Penggunaan Nginx
sebagai proksi songsang bukan sekadar solusi pembangunan, tetapi satu pendekatan sistematik untuk mengurus pelbagai aplikasi moden dalam persekitaran yang seragam, selamat, dan produktif.
Jana Sijil HTTPS untuk domain-domain “localhost”
Saya ikuti tutorial “How to create an HTTPS certificate for localhost domains” untuk mengaplikasikan keselamatan pada domain localhost
, audio.loc
dan laravel.loc
.
Untuk itu, saya simpan kesemua fail berkait pensijilan di dalam satu direktori i.e. $HOME/SSL
. Ikut sahaja turutan tutorial:
Jana
RootCA.pem
,RootCA.key
&RootCA.crt
;Cipta fail berikut ;
domains.ext
... [alt_names] DNS.1 = localhost DNS.2 = audio.loc DNS.3 = laravel.loc
Pastikan kemas kini DNS sebagaimana berikut:
bash
127.0.0.1 localhost audio.loc laravel.loc
Jana
localhost.key
,localhost.csr
, andlocalhost.crt
;Direktori
$HOME/SSL
akan mengandungi fail-fail berikut:Dan kemudian buat sahaja dua perkara ini:
"There are two ways to get the CA trusted in Firefox.
The simplest is to make Firefox use the Windows trusted Root CAs by going toabout:config
, and settingsecurity.enterprise_roots.enabled
totrue
.
The other way is to import the certificate by going toabout:preferences#privacy
>Certificats
>Import
>RootCA.pem
>Confirm for websites
."
Contoh Konfigurasi Pelayan Nginx (SSL/HTTPS)
nginx
dengan perintah "sudo systemctl reload nginx
" setiap kali ada perubahan pada fail konfigurasi pelayan.localhost
/etc/nginx/sites-available/localhost
server {
listen 80 default_server;
server_name localhost;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name localhost;
ssl_certificate /home/<user>/SSL/localhost.crt;
ssl_certificate_key /home/<user>/SSL/localhost.key;
# SSL Hardening
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# < Alihkan kesemua blok bermula dari "Security Headers"
# sehingga baris akhir ke sini >
add_header ...
...
error_log /var/log/nginx/localhost_error.log;
access_log /var/log/nginx/localhost_access.log;
}
audio-server
/etc/nginx/sites-available/audio-server
server {
listen 80;
server_name audio.loc;
# Redirect HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name audio.loc;
ssl_certificate /home/<user>/SSL/localhost.crt;
ssl_certificate_key /home/<user>/SSL/localhost.key;
# SSL Hardening
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# < Alihkan kesemua blok bermula dari "Security Headers"
# sehingga baris akhir ke sini >
add_header ...
...
error_log /var/log/nginx/audio-server_error.log;
access_log /var/log/nginx/audio-server_access.log;
}

laravel
/etc/nginx/sites-available/laravel
server {
listen 80;
server_name laravel.loc;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name laravel.loc;
ssl_certificate /home/<user>/SSL/localhost.crt;
ssl_certificate_key /home/<user>/SSL/localhost.key;
# SSL hardening
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# < Alihkan kesemua blok bermula dari "Security Headers"
# sehingga baris akhir ke sini >
add_header ...
...
error_log /var/log/nginx/laravel_error.log;
access_log /var/log/nginx/laravel_access.log;
}
Tetapan .env
yang penting:
.env
APP_ENV=production
APP_URL=https://laravel.loc
VITE_APP_URL="${APP_URL}"
