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

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

Related

Docker - NGINX Container forward to PHP-FPM Container

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

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

How to resolve a PHP-FPM Primary script unknown with a PHP-FPM and an Nginx Docker container?

My situation is this, I have two Docker containers:
Runs PHP-FPM on port 9000
Runs nginx and has PHP files (should the PHP-FPM container have access to the files?)
I keep getting the following error:
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 172.17.0.1, ser
ver: _, request: "GET / HTTP/1.1", upstream: "fastcgi://172.17.0.2:9000", host: "172.17.0.3"
I read here that this is "always related to a wrongly set SCRIPT_FILENAME in the nginx fastcgi_param directive."
The problem is, I don't know how to resolve it :-P
Config in Container 2:
server {
listen 80 default_server;
listen [::]:80 default_server;
charset UTF-8;
root /var/www/WordPress;
index index.php index.html index.htm;
server_name _;
location / {
try_files $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass 172.17.0.2:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/WordPress$fastcgi_script_name;
# set headers
add_header Cache-Control $cc;
access_log off;
expires $ex;
}
location ~* \.(js|css|svg|png|jpg|jpeg|gif|ico|eot|otf|ttf|woff)$ {
add_header Access-Control-Allow-Origin *;
add_header Cache-Control "public";
access_log off;
log_not_found off;
expires 1y;
}
location ~ /\.ht {
deny all;
}
}
Change root line to: root /var/www/WordPress/; for the $fastcgi_script_name doesn't include /
I'm no nginx expert, but literally every instance of fastcgi_param SCRIPT_FILENAME in the docs ends with $fastcgi_script_name, and yours doesn't.
I broke my brain trying to figure out why it is not working.
As usual, it's a matter of inattention.
So, in my nginx.conf I have lines:
set $root "/var/www/html/web";
root $root;
set $bootstrap "index.php";
index $bootstrap;
location / {
index index.html $bootstrap;
try_files $uri $uri/ /$bootstrap?$args;
expires -1;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+.php)(.*)$;
set $fsn /$bootstrap;
if (-f $document_root$fastcgi_script_name) {
set $fsn $fastcgi_script_name;
}
fastcgi_pass php:9000;
fastcgi_index $bootstrap;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fsn;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fsn;
try_files $fsn =404;
expires -1;
}
include defaults.conf;
Very important to pay attention to line if (-f $document_root$fastcgi_script_name) {, because it is a check for existence.
In my docker-compose.yml I had different mounts in the nginx-container and the php-container:
php:
image: aspendigital/octobercms:php7.2-fpm
container_name: "${PROJECT_NAME}_php"
volumes:
- ./web:/var/www/html # <- this line is incorrect! Mounts MUST be identical!
nginx:
image: wodby/nginx:$NGINX_TAG
container_name: "${PROJECT_NAME}_nginx"
depends_on:
- php
environment:
NGINX_STATIC_OPEN_FILE_CACHE: "off"
NGINX_ERROR_LOG_LEVEL: debug
NGINX_BACKEND_HOST: php
NGINX_SERVER_ROOT: /var/www/html/web/
NGINX_CONF_INCLUDE: /var/www/html/nginx/*.conf
volumes:
- ./:/var/www/html:cached
So, replaсing in php-part the volume to the same as in the nginx-part solved my problem.
Be careful!

Symfony + nginx virtual host configuration not working

Created a virtualhost for symfony application in local system
Here is the nginx config file
server {
listen 80;
server_name local.symfony;
root /home/guest/symfony_demo/web;
rewrite ^/app\.php/?(.*)$ /$1 permanent;
try_files $uri #rewriteapp;
location #rewriteapp {
rewrite ^(.*)$ /app.php/$1 last;
}
# Deny all . files
location ~ /\. {
deny all;
}
location ~ ^/(app|app_dev)\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
fastcgi_index app.php;
send_timeout 1800;
fastcgi_read_timeout 1800;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
# Statics
location /(bundles|media) {
access_log off;
expires 30d;
try_files $uri #rewriteapp;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
On load of app in browser its throwing an error
502 Bad Gateway Error:No input file specified.
Error caught from error.log file:
FastCGI sent in stderr: "Unable to open primary script: /home/guest/symfony_demo/web/app.php (No such file or directory)" while reading response header from upstream, client: 127.0.0.1, server: local.symfony, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "local.symfony"
Can anyone help me to configure symfony app to app_dev config file.
Any thoughts??
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
This line is the problem. If you remove it, your error disappears. You may then have Opcache problems due to Symfony using symlinks to the current project.
With $realpath_root$fastcgi_script_name, the web server looks at the "real" path for the PHP script based on the root definition in your server block. Nginx must have read permissions to the path for this to work. Your code is in /home/guest/, if nginx is running as "www-data" give it permissions to your directories, or run nginx as the "guest" user (ignoring the security implications of this).
Why don't you start with configuration from official documentation (http://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html#nginx) and when that works, you can try to add your custom configuration (caching of sttaic files ...) ?
This should work:
server {
listen 80;
server_name local.symfony;
root /home/guest/symfony_demo/web;
location / {
try_files $uri /app_dev.php$is_args$args;
}
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
This error happens when nginx is not able to find the php-fpm.sock file.
Can you make sure that the php-fpm.sock file is in the path as mentioned. I had to update fastcgi_pass like below
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
as my php-fpm.sock was there

Categories