Before I start, I know there are many solutions in StackOverflow regarding this issue but they are not working for my case.
I set up a docker container running Nginx instance with PHP. When I enter such URL, myapp.com/somefile without .php at the end, it cannot find the file. I need to browse this URL to make it work myapp.com/somefile.php.
Here is my configuration with Dockerfile and Nginx config.
Dockerfile
FROM php:7.4.8-fpm
RUN apt-get update -y \
&& apt-get install -y nginx
# PHP_CPPFLAGS are used by the docker-php-ext-* scripts
ENV PHP_CPPFLAGS="$PHP_CPPFLAGS -std=c++11"
RUN docker-php-ext-install pdo_mysql \
&& docker-php-ext-install opcache \
&& apt-get install libicu-dev -y \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl \
&& apt-get remove libicu-dev icu-devtools -y
RUN { \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
echo 'opcache.enable_cli=1'; \
} > /usr/local/etc/php/conf.d/php-opocache-cfg.ini
COPY nginx-site.conf /etc/nginx/sites-enabled/default
COPY entrypoint.sh /etc/entrypoint.sh
COPY --chown=www-data:www-data . /var/www/html
WORKDIR /var/www/html
EXPOSE 80 443
ENTRYPOINT ["sh", "/etc/entrypoint.sh"]
nginx-site.conf
server {
root /var/www/html;
include /etc/nginx/default.d/*.conf;
index index.php index.html index.htm;
client_max_body_size 30m;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
How can I solve this issue? Any help would be appreciated!
Note: I tried to add this lines of code to the nginx config but i ended up downloading files instead of executing them :
location / {
try_files $uri $uri.html $uri/ #extensionless-php;
index index.html index.htm index.php;
}
location ~ \.php$ {
try_files $uri =404;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
Yes, you cannot force nginx to force serving PHP script via PHP location handler with something like try_files $uri $uri.php .... You can try this config instead (yes, I know that some if blocks are evil, but don't worry, this one isn't):
location / {
index index.html index.htm index.php;
try_files $uri $uri.html $uri/ #extensionless-php;
}
location ~ \.php$ {
# default PHP handler here
...
}
location #extensionless-php {
if ( -f $document_root$uri.php ) {
rewrite ^ $uri.php last;
}
return 404;
}
If you want to redirect all the not found requests to index.php, use this one instead:
location #extensionless-php {
if ( -f $document_root$uri.php ) {
rewrite ^ $uri.php last;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi.conf;
}
Related
I am trying to add worker_processes into my nginx.conf file on my docker-environment, but whenever I try, it fails to restart or load. I believe I'm missing some key concept here- anyway:
This is my nginx.conf file (everything works here):
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/src;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ ^/wp-json/ {
rewrite ^/wp-json/(.*?)$ /?rest_route=/$1 last;
}
}
I have tried to add the following below the server brackets, but that results in nginx not loading. The error from enginx is is: "worker_processes" directive is not allowed here in /etc/nginx/conf.d/nginx.conf:1
:
worker_processes: 8;
server {
listen 80;
index index.php index.html;
etc. etc. etc.
This is my folder structure:
And this is currently my Dockerfile:
FROM php:7.4.15-fpm
# Arguments defined in docker-compose.yml
ARG user
ARG uid
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install mysqli pdo_mysql mbstring exif pcntl bcmath g
# Set working directory
WORKDIR /var/www
USER $user
Your config located at /etc/nginx/conf.d/nginx.conf is likely being imported by the default configuration file /etc/nginx/nginx.conf with the statement include /etc/nginx/conf.d/*.conf;.
As such your config lives within the http context, which does not allow the worker_processes directive. You need to edit the existing statement that should already be defined in /etc/nginx/nginx.conf, by default it should be set to worker_processes auto;.
Note: There is no colon required so just change this to worker_processes 8;
An answer for the same root problem is https://stackoverflow.com/a/41681414/11296166
I am running my php code in docker with Nginx and fastcgi
I am exposing port 9999 of my docker container
So to invoke my application I do:
http://localhost:9999/index.php
I also have a localdomain: example.com which is pointing to 127.0.0.1 in /etc/hosts.
So I can invoke my application using example.com:9999/index.php
Strange thing I noticed is, when I use localhost url, I am getting an error on my browser
Resource interpreted as Stylesheet but transferred with MIME type application/octet-stream: "http://localhost:9999/css/login.css?v=1".
I don't get the above error if I inovke it using example.com
Can somebody explain why is the strange behavior happening?
The nginx config is as follows:
events {
multi_accept on;
worker_connections 65535;
}
http {
# MIME
default_type application/octet-stream;
include /etc/nginx/mime.types;
# logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
server {
listen 80 default_server;
server_name _;
index index.php;
root /code/Public;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
}
This is my Dockerfile config:
FROM phpdockerio/php73-fpm
RUN apt-get update
RUN apt-get install -y php7.3-memcache
RUN apt-get install -y php7.3-curl
RUN apt-get install -y nginx
ADD docker/nginx.conf /etc/nginx/
CMD ["sh", "-c", "service nginx restart ; /usr/sbin/php-fpm7.3 -O"]
FYI: I am using slim-framework. here is the reference doc for setting up nginx
I am trying to connect my docker nginx container to my docker php7 container. I have both connected to a private bridge network, because I want my php engine offline. When starting my nginx container I get the error:
nginx: [emerg] host not found in upstream "php7" in
etc/nginx/conf.d/default.conf:11
My php container command (run first):
docker run -d \
--name php7 \
-v /php7:/usr/local/etc \
-v /www_data:/www \
--network=priv-bridge-net \
-p 9000:9000 \
php:7.0.24-fpm
My nginx command:
docker run -d \
--name nginx \
-v /nginx_conf:/etc/nginx \
-v /www_data:/usr/share/nginx/html \
--network=priv-bridge-net \
nginx:1.13.5
My nginx config:
server {
index index.php index.html;
server_name test;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /usr/share/nginx/html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php7:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Please help me figure out what I am doing wrong. Thanks!
Second question, can I eliminate the -p 9000:9000 from the php container, because it is on the same bridge network on as the nginx server.
Ok, so my above question IS the correct answer. I was just having trouble with the order of starting containers (I also have reverse proxies and others in play, it got a bit confusing).
For anyone who wants to connect docker nginx to a docker php, this is correct setup:
My php container command (run first):
docker run -d \
--name php7 \
-v /php7:/usr/local/etc \
-v /www_data:/www \
--network=priv-bridge-net \
-p 9000:9000 \
php:7.0.24-fpm
My nginx command:
docker run -d \
--name nginx \
-v /nginx_conf:/etc/nginx \
-v /www_data:/usr/share/nginx/html \
--network=priv-bridge-net \
nginx:1.13.5
My nginx config:
server {
index index.php index.html;
server_name test;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /usr/share/nginx/html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php7:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
I'm trying to get basic FastCGI caching to work, but am running into trouble after following this tutorial.
On a fresh installation of Ubuntu 16.04, I ran the following commands:
apt-get update
apt-get install -y nginx
apt-get install -y php-fpm
I then changed /etc/nginx/sites-available/default to:
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
include snippets/fastcgi-php.conf;
# fastcgi_cache MYAPP;
# fastcgi_cache_valid 200 60m;
}
}
After adding a file called time.php in the server document root (/var/www/html) with the following contents:
<?php echo time();
and navigating IP/time.php, the file executes and displays a timestamp. On reloads, fresh timestamps are displayed.
If I uncomment the above lines, only a blank screen with <html><body></body></html> loads.
Why does adding:
fastcgi_cache MYAPP;
fastcgi_cache_valid 200 60m;
result in a blank html page? How can this be fixed to cache time.php and serve the cached version to future requests?
Note: I did see that /etc/nginx/cache was created and does contain data. I changed the directory to 777 permissions to eliminate permission issues.
$ sudo mkdir -p /var/cache/nginxfastcgi
$ chown www-data: /var/cache/nginxfastcgi
THEN IN YOUR CONFIG
fastcgi_cache_path /var/cache/nginxfastcgi levels=1:2 keys_zone=fastcgicache:10m inactive=10m max_size=64m;
fastcgi_cache_key $scheme$request_method$host$request_uri;
fastcgi_cache_lock on;
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
fastcgi_cache_valid 5m;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
server {
listen 80;
root **************;
index index.php index.html index.htm;
server_name *************;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
add_header X-Cache $upstream_cache_status;
fastcgi_cache fastcgicache;
}
}
Trying to setup docker with nginx and php5. Here's my Dockerfile
FROM nginx:1.9.9
RUN apt-get update
RUN apt-get -y install php5-fpm php5-mysql php-apc php5-imagick\
php5-imap php5-mcrypt php5-curl php5-cli php5-gd php5-pgsql\
php5-common php-pear curl php5-json
ADD index.html /usr/share/nginx/html/index.html
ADD index.php /usr/share/nginx/html/index.php
ADD default /etc/nginx/sites-available/default
RUN /etc/init.d/php5-fpm restart
I am able to build this just fine with the following command:
sudo docker build -t myuser/nginx-php5:0.1 .
And then I launch it as follows:
sudo docker run -d -P myuser/nginx-php5:0.1
The nginx deamon is running, I can indeed see my index.html, yet, index.php gets 'downloaded' rather than served. This indicates that PHP is not properly set...
My default file:
server {
listen 80;
root /var/www;
index index.php index.html;
server_name localhost;
access_log /var/log/nginx/localhost.com-access.log;
error_log /var/log/nginx/localhost.com-error.log error;
charset utf-8;
location / {
try_files $uri $uri/ /index.html /index.php?$query_string;
}
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
include fastcgi.conf;
fastcgi_param HTTPS off;
}
location ~ /\.ht {
deny all;
}
}
Any ideas what am I doing wrong? I guess the problem is that I am not doing the proper things to keep php5-fpm running.. but how to fix this?
I think php-fpm didn't run, so nginx just returns php file instead of passing to php-fpm to process.
You should create an "entrypoint.sh" file to launch nginx and php-fpm when run the container. Besides you must correctly set user and group for php-fpm worker processes.