Serve static files using docker, nginx, php-fpm - php

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

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

host not found in upstream "php-fpm" in /etc/nginx/conf.d/default.conf

I have got this error when I tried to run docker-compose up :
Error: host not found in upstream "php-fpm" in /etc/nginx/conf.d/default.conf
Below is the code which I am using in docker-compose.yml.
docker-composer version: '3.7'
services:
ngnix:
build:
args:
VERSION: $NGINX_VERSION
context: .
dockerfile: ./docker/nginx/Dockerfile
target: dev
volumes:
- .:/app
depends_on:
- php-fpm
links:
- php-fpm
ports:
- 81:80
networks:
- inluccnetwork
php-fpm:
build:
args:
VERSION: $PHP_VERSION
context: .
dockerfile: ./docker/php-fpm/Dockerfile
target: dev
volumes:
- .:/app
networks :
- inluccnetwork
command: sh -c 'composer install --no-interaction --optimize-autoloader && php-fpm'
networks:
inluccnetwork :
driver: bridge
Nginx config file code at /etc/nginx/conf.d/default.conf:
server {
listen 80;
root /app/web;
include mime.types;
index app_dev.php index.html index.htm;
location / {
try_files $uri #rewriteapp;
}
location #rewriteapp {
rewrite ^(.*)$ /app_dev.php/$1 last;
}
# DEV
# This rule should only be placed on your development environment
# In production, don't include this and don't deploy app_dev.php or config.php
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
internal;
}
# PROD
location ~ ^/app\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
location /test {
return 200 '<h1>ok</h1>';
}
error_log syslog;
access_log syslog;
location ~ /\.ht {
deny all;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|mp4|ogg|ogv|webm|htc)$ {
access_log off;
root /app/web;
add_header Cache-Control "max-age=2592000";
expires max;
log_not_found off;
}
# CSS and Javascript
location ~* \.(?:css|js)$ {
add_header Cache-Control "max-age=31536000";
access_log off;
expires max;
log_not_found off;
}
}
Code I am using in my docker file for Nginx:
ARG VERSION
# Dev image
FROM nginx:1.15-alpine as dev
# Copy nginx config
COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf
# Prod image
FROM dev as prod
# Copy assets
COPY ./assets /app/web
I have error not know php-fpm in file default.php and also I add option links in docker-compose but also error

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;
}
}

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!

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