Docker - NGINX Container forward to PHP-FPM Container - php

I am running NGINX, PHP-FPM and DB in separate container.
Inside PHP-FPM is mounting a Laravel project from my local machine.
I've successfully forward the PHP request to PHP-FPM container (port 9000) while accessing 127.0.0.1:8000. Unfortunately, the requests with assets extension (e.g. .css, .js) has ran into 403 forbidden.
Following are my NGINX configuration script.
server {
listen 80;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass fpm:9000;
fastcgi_param SCRIPT_FILENAME /app/public$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(css|js|gif|ico|jpeg|jpg|png)$ {
fastcgi_pass fpm:9000;
fastcgi_param SCRIPT_FILENAME /app/public$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
}
The request and response header for app.css file.
Not sure if anyone has ran into similar problems and have solution for this?

You're forward everything to PHP FPM, meanwhile, by default in PHP-FPM process config file, it only allows .php file to be served.
You can check in /usr/local/etc/php-fpm.d/www.conf inside php-fpm container, and search for security.limit_extensions, you'll see.
So here you have 2 solutions
Solution 1: map your project source into container where you're running Nginx, like this:
# docker-compose.yml
webserver:
image: nginx:1.17-alpine
restart: unless-stopped
ports:
- "8000:80"
volumes:
- ./:/var/www/html
By doing this Nginx can easily find your static files and serve them. Note that /var/www/html is your root project path which you defined in your Nginx config file. For example, Nginx config file for Laravel project usually looks like:
server {
listen 80;
index index.php index.html;
root /var/www/html/public;
...
Solution 2: add .css, .js to PHP-FPM process config file, with this solution, you'll override PHP-FPM config file and add your static files to list file extensions that PHP-FPM allows. Check my demo here. This solution won't require you to map your project into Nginx container. But in reality it's not good for production like solution 1

Related

How do I configure nginx container to serve with traefik in a docker compose

I have the following docker-compose with traefik and a service (https://github.com/Okazanta/Dockerized) that uses nginx to serve its web files
service:
image: my.registry.service
expose:
- "8000"
labels:
- traefik.enable=true
- traefik.http.routers.service.middlewares=strip-prefix#file
- traefik.http.routers.service.rule=PathPrefix(`/status`)
- traefik.http.routers.service.tls=true
- traefik.http.services.service.loadbalancer.server.port=8000
The service is a web application made with php and served with the following nginx configuration:
server {
listen 8000 default; ## Listen for ipv4; this line is default and implied
listen [::]:8000 default; ## Listen for ipv6
# Make site accessible from http://localhost/
server_name localhost;
root /var/www/html/public;
index index.php;
charset utf-8;
location / {
try_files $uri /index.php$is_args$args;
}
# Cache images
location ~* .(jpg|jpeg|png|gif|ico|css|js|ttf|svg)$ {
expires 365d;
}
# Pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
fastcgi_pass_header Set-Cookie;
fastcgi_pass_header Cookie;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_cache_bypass 1;
fastcgi_no_cache 1;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_keep_conn on;
}
location ~ /\.ht {
deny all;
}
}
When I make the request to myhost.com/status, only the first request reaches the service. All other requests are made without the /status prefix, so it gets a 404 response. Looking at the browser network tab I see the requests made:
myhost.com/status # 200
myhost.com/dist/css.... # 404, it should be myhost.com/status/dist/css...
myhost.com/dist/js.... # 404, it should be myhost.com/status/dist/js...
....
Log of nginx when I open https://myhost.com/status:
"GET / HTTP/1.1" 200 14321 "-"
Nothing more
I don't understand what is removing the /status prefix for other requests

Laravel app with separate php-fpm and nginx servers

Is it possible to run a Laravel app on two separated server, one with NGINX, another with PHP-FPM?
I wanted to create an upstream of PHP-FPM servers for load balancing. I've tried some NGINX configurations but it seems that both NGINX and PHP-FPM needs Laravel app files.
Note: I have separate server for static files.
[user] -request-> [nginx without laravel files] -> [php-fpm upstream with laravel files]
UPDATE
upstream php_pool {
server 192.168.1.1:9000;
}
server {
listen 80;
server_name www.example.com;
index index.php;
access_log /var/log/nginx/q_access.log;
error_log /var/log/nginx/q_error.log info;
location / {
try_files $uri $uri/index.php /index.php;
}
location ~ \.php$ {
index index.php;
fastcgi_pass php_pool;
fastcgi_index index.php;
include fastcgi_params;
}
}
I don't know what should i set for root directory cause there isn't any Laravel app files in that server. And how config \.php$ location properly?
We found solution for our scenario. PHP location should be like this:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php_pool;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/app/public$fastcgi_script_name;
}
With this change (SCRIPT_FILENAME) there isn't need for Laravel app files to be on the NGINX server cause all PHP requests will proxied to PHP-FPM servers.

Cannot get index.php page to display in docker container

I have a docker container that I setup to display a php page, however it displays a 403 forbidden page. I have nginx running on my host machine and I enabled my site as well. The site is displaying html file but not php files. I also verified the following services are running.
nginx is running in the docker container
php-fpm service is running in the docker container.
the user www-data has permissions to execute files in the folder
server {
listen 443;
server_name af.oxygenweb.ca;
ssl_certificate /etc/letsencrypt/live/af.oxygenweb.ca/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/af.oxygenweb.ca/privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
location /.well-known {
alias /var/www/html/.well-known;
}
access_log /var/log/nginx/af/access.log;
error_log /var/log/nginx/af/error.log;
location / {
root /var/www/html;
index index.php;
proxy_pass http://172.17.0.2;
proxy_redirect http:// https://;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
#try_files $uri /index.html index.php;
}
# pass PHP scripts to FastCGI server
location ~* \.php$ {
# include snippets/fastcgi-php.conf;
# pass PHP scripts to FastCGI server
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}

Serve static files using docker, nginx, php-fpm

I'm working with containers in docker
Where I have one from PHP-FPM and another from Nginx.
But I'm having problems with Nginx to serve the static files (css, js)
Return Status Code: 404 Not Found
Nginx configuration
server {
# Set the port to listen on and the server name
listen 80;
listen [::]:80;
# Set the document root of the project
root /var/www/html;
# Set the directory index files
index index.php;
#Set server name
server_name myproject;
# Specify the default character set
charset utf-8;
# Specify the logging configuration
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Specify what happens when PHP files are requested
location ~* \.php$ {
#try_files $uri =404;
#try_files /index.php = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass myproject:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
index index.php;
try_files $uri $uri/ /index.php;
include /etc/nginx/mime.types;
}
location ~* \.(jpg|jpeg|png|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 360d;
add_header Cache-Control "public";
}
# Specify what happens what .ht files are requested
location ~ /\.ht {
deny all;
}
}
PHP Dockerfile
FROM php:7-fpm
RUN docker-php-ext-install pdo_mysql
COPY . /var/www/html/
EXPOSE 9000
Nginx Dockerfile
FROM nginx:1.12.2
COPY ./default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
I think the problem, cause service nginx can not find your web project. If you use docker-compose you can use volume, but if not you can add folder project in nginx Dockerfile to /var/www/html
nginx dockerfile
ROM nginx:1.12.2
COPY . /var/www/html/
COPY ./default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
for docker compose like this :
services:
nginx:
images: nginx:latest
...
...
volumes:
- ./:/var/www/html
php:
images: php
...
...
volumes:
- ./:/var/www/html

Docker machine users has no access to files on host

I have problem with setting up my docker environment on remote machine.
I prepared local docker machines. Problem is with nginx + php-fpm.
Nginx act as nginx user, php-fpm act as www-data user. Files on host machine (application files) are owned by user1. chmods are default for symfony2 application.
When I access my webserver it returns 404 error or just simple "file not found".
For a while exact same configuration works on my local Ubuntu 16.04, but fails on Debian Jessie on server. Right now it doesn't work on both. I tried everything, asked on sysops groups and googled for hours. Do you hve any idea?
Here is my vhost configuration
server {
listen 80;
server_name dev.xxxxx.co xxxxx.dev;
root /usr/share/www/co.xxxxx.dev/web;
index app_dev.php;
client_max_body_size 100M;
fastcgi_read_timeout 1800;
location / {
# try to serve file directly, fallback to app.php
try_files $uri $uri/ /app.php$is_args$args;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
access_log off;
}
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
location ~ \.php$ {
return 404;
}
}
nginx configuration
user root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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 main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
And my docker compose
version: '2'
services:
nginx:
image: nginx
ports:
- 8082:80
volumes:
- /home/konrad/Workspace:/usr/share/www:ro
- ./conf/nginx.conf:/etc/nginx/nginx.conf:ro
- ./sites:/etc/nginx/conf.d:ro
php-fpm:
image: php:fpm
ports:
- 9000:9000
volumes:
- /home/konrad/Workspace:/usr/share/www
- ./conf/www.conf:/etc/php/7.0/fpm/pool.d/www.conf
- ./conf/php.ini:/usr/local/etc/php/conf.d/90-php.ini:ro
On remote server files are accesible, visible as property of 1001:1001

Categories