Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,34 @@ jobs:
- run: docker logs $(docker ps -qn1)
if: ${{ always() }}

nginx-webserver:
nginx-reverse-proxy:
name: nginx (${{ matrix.config.name }})
runs-on: ubuntu-22.04
strategy:
matrix:
config:
- name: reverse proxy with files
path: nginx-reverse-proxy-public.conf
- name: minimal reverse proxy
path: nginx-reverse-proxy-minimal.conf
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: 8.3
- run: composer install -d tests/integration/
- run: docker build -f tests/integration/Dockerfile-basics tests/integration/
- run: docker run -d -p 8080:8080 -v "$PWD/composer.json":/app/composer.json $(docker images -q | head -n1)
- run: docker run -d --net=host -v "$PWD/tests/integration/":/home/framework-x/ -v "$PWD"/tests/integration/${{ matrix.config.path }}:/etc/nginx/conf.d/default.conf nginx:stable-alpine
- run: bash tests/await.sh http://localhost
- run: bash tests/integration.bash http://localhost
- run: docker stop $(docker ps -qn2)
- run: docker logs $(docker ps -qn1)
if: ${{ always() }}
- run: docker logs $(docker ps -qn2 | tail -n1)
if: ${{ always() }}

nginx-fpm:
name: nginx + PHP-FPM (PHP ${{ matrix.php }})
runs-on: ubuntu-22.04
strategy:
Expand Down
53 changes: 43 additions & 10 deletions docs/best-practices/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ server {
try_files $uri $uri/ /index.php$is_args$args;
}

# Optional: handle Apache config with Framework X if it exists in `public/`
error_page 403 = /index.php;
location ~ \.htaccess$ {
deny all;
}

location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
Expand Down Expand Up @@ -186,6 +192,9 @@ RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php

# Optional: handle `.htaccess` with Framework X instead of `403 Forbidden`
ErrorDocument 403 /%{REQUEST_URI}/../index.php

# This adds support for authorization header
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
```
Expand Down Expand Up @@ -412,20 +421,44 @@ all you need to do is to point the nginx' [`root`](http://nginx.org/en/docs/http
to instruct nginx to process any dynamic requests through X. This can be
achieved by using an nginx configuration with the following contents:

```
server {
root /home/alice/projects/acme/public;
index index.php index.html;
=== "nginx.conf (reverse proxy with static files)"

location / {
try_files $uri $uri/ @x;
```
server {
# Serve static files from `public/`, proxy dynamic requests to Framework X
location / {
location ~* \.php$ {
try_files /dev/null @x;
}
root /home/alice/projects/acme/public;
try_files $uri @x;
}

location @x {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header Connection "";
}

# Optional: handle Apache config with Framework X if it exists in `public/`
location ~ \.htaccess$ {
try_files /dev/null @x;
}
}
```

location @x {
proxy_pass http://localhost:8080;
=== "nginx.conf (minimal reverse proxy)"

```
server {
# Proxy all requests to Framework X
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header Connection "";
}
}
}
```
```

> ℹ️ **New to nginx?**
>
Expand Down
10 changes: 7 additions & 3 deletions tests/integration.bash
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ skipifnot() {
}

out=$(curl -v $base/ 2>&1); match "HTTP/.* 200" && match -iP "Content-Type: text/plain; charset=utf-8[\r\n]"
out=$(curl -v $base/invalid 2>&1); match "HTTP/.* 404" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]"
out=$(curl -v $base// 2>&1); match "HTTP/.* 404"
out=$(curl -v $base/ 2>&1 -X POST); match "HTTP/.* 405"
out=$(curl -v $base/ 2>&1 -X POST); match "HTTP/.* 405" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]"

out=$(curl -v $base/unknown 2>&1); match "HTTP/.* 404" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]"
out=$(curl -v $base/index.php 2>&1); match "HTTP/.* 404" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]"
out=$(curl -v $base/.htaccess 2>&1); match "HTTP/.* 404" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]"
out=$(curl -v $base// 2>&1); match "HTTP/.* 404" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]"

out=$(curl -v $base/error 2>&1); match "HTTP/.* 500" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]" && match "<code>Unable to load error</code>"
out=$(curl -v $base/error/null 2>&1); match "HTTP/.* 500" && match -iP "Content-Type: text/html; charset=utf-8[\r\n]"

Expand Down
6 changes: 6 additions & 0 deletions tests/integration/nginx-fpm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ server {
try_files $uri $uri/ /index.php$is_args$args;
}

# Optional: handle Apache config with Framework X if it exists in `public/`
error_page 403 = /index.php;
location ~ \.htaccess$ {
deny all;
}

location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/nginx-reverse-proxy-minimal.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
server {
# Proxy all requests to Framework X
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header Connection "";
}
}
21 changes: 21 additions & 0 deletions tests/integration/nginx-reverse-proxy-public.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
server {
# Serve static files from `public/`, proxy dynamic requests to Framework X
location / {
location ~* \.php$ {
try_files /dev/null @x;
}
root /home/framework-x/public;
try_files $uri @x;
}

location @x {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header Connection "";
}

# Optional: handle Apache config with Framework X if it exists in `public/`
location ~ \.htaccess$ {
try_files /dev/null @x;
}
}
3 changes: 3 additions & 0 deletions tests/integration/public/.htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php

# Optional: handle `.htaccess` with Framework X instead of `403 Forbidden`
ErrorDocument 403 /%{REQUEST_URI}/../index.php

# This adds support for authorization header
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0