Docker Nginx connect to PHP-FPM on private docker network - php

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

Related

docker-compose with nginx and php:8-fpm

I try to add php support to my nginx running inside docker. But starting of the service fails.
That is my docker-compose.yml
version: "2.4"
services:
nginxproxy:
image: nginx:mainline-alpine
command: "/bin/sh -c 'while :; do sleep 48h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
environment:
- TZ=${TZ}
volumes:
- ./data/nginx/conf:/etc/nginx/conf.d/:ro
- ./data/nginx/websites:/var/www/
depends_on:
- php-fpm
links:
- php-fpm
restart: always
network_mode: "host"
php-fpm:
image: php:8-fpm
ports:
- 9001:9000
volumes:
- ./data/nginx/websites:/var/www/
./data/nginx/websites containes severall webroots of different vhosts.
When I try to bring everything up, nginx is able to start, but php:8-fpm fails to start.
docker-compose logs does only show "Attaching to"
I am not able to find out more error messages oder whats wrong here.
I have similar issue before. It found out my php-fpm was a problem. in my default.conf. I change the default fastcgi_pass to fastcgi_pass 127.0.0.1:9000;
Here is my config
server {
listen *:80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /usr/share/nginx/html/project;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Article Reference: How to setup PHP 8, NGINX, PHP-FPM and Alpine with Docker

How to do routing without .php extension with nginx and php

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

Resource interpreted as Stylesheet but transferred with MIME (localhost vs domain)

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

Nginx Docker Container - forwarding php-file requests to php-fpm container

I already asked the same question on superuser (https://superuser.com/questions/1298776/nginx-execute-php-files-in-different-docker-container) but it was not possible to get an answer, maybe this problem is too specific for SU.
I am using an automated docker-image for php-fpm and nginx (https://hub.docker.com/r/tobi312/rpi-php/ and https://hub.docker.com/r/tobi312/rpi-nginx/ ) running on a raspberry pi with with libreelec on top.
The php container successfully starts with port 9000 open by running the following command:
docker run --name php -v /var/www/restTools:/var/www/html -d 3dd6ff8c0d58
After that I started the nginx-container like this:
docker run --name nginx -d -p 8081:80 --link php:9000 -v /var/www/restTools:/var/www/html 0d90cc6eb00f
Both containers are running but the nginx is not executing php files, it's just offering them for download.
After a while I tried to commit the connections details to the php-container trough a default.conf by adding -v /var/www/.config/nginx:/etc/nginx/conf.d:ro to the command.
Excerpt from default.conf:
root /var/www/html;
location / {
root /var/www/html;
index index.html index.htm index.php;
}
location ~ \.php$ {
root /var/www/html;
fastcgi_pass php:9000;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
}
What am I missing?
You are trying to use the (deprecated!!) "link" option of docker, this is not a problem itself, but you have to respect the syntax
--link <name or id>:alias
so, you have to substitute your
--link php:9000
with the correct
--link php
you do not need an alias because you named the fpm container the same as you referred it in default.conf.
The other important thing is to mount the php files folder in the fpm container but you already did this right.

Why php-fpm from official Docker image doesn't work for me?

I try to run a new container from php:fpm:
docker run --name fpmtest -d -p 80:9000 php:fpm
By default, it exposes port 9000 in its Dockerfile.
Then I log in into container and create index.html file:
$ docker exec -i -t fpmtest bash
root#2fb39dd6a40b:/var/www/html# echo "Hello, World!" > index.html
And inside the container I try to get this content with curl:
# curl localhost:9000
curl: (56) Recv failure: Connection reset by peer
Outside the container I get another error:
$ curl localhost
curl: (52) Empty reply from server
I think you misunderstood the purpose of that container. There is not a web server listening.
The port 9000 of the container is a socket that a web server can use to communicate with the php interpreter.
In the parent folder of the git repository you linked, there is another folder which runs an apache container, it seems to be there to work together with the fpm container.
I guess in your case you should do:
docker run -it --rm --name my-apache-php-app -v /PATH/TO/WEB-FILES:/var/www/html php:5.6-apache
Here is the official documentation to work with php docker images:
https://registry.hub.docker.com/_/php/
As an example, let's say we want to use that php-fpm container with another container running the nginx web server.
First, create a directory with the php files, for example:
mkdir content
echo '<?php echo "Hello World!"?>' > content/index.php
Then, create another directory conf.d, and inside it create a default.conf file with this content:
server {
server_name localhost;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.html;
}
location ~ \.php$ {
try_files $uri =404;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass fpmtestdocker:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Note the fastcgi_pass param value. Well, with this scenario, we run first:
docker run --name fpmtest -d -p 9000:9000 -v $PWD/content:/var/www/html php:fpm
And then:
docker run --name nginxtest -p 80:80 --link fpmtest:fpmtestdocker -v $PWD/content:/var/www/html -v $PWD/conf.d:/etc/nginx/conf.d -d nginx
And that's it. We can go to http://localhost and see the results.
To take into account:
Both containers needs access to the same /var/www/html directory. They shares paths to the app files.
--link fpmtest:fpmtestdocker param so that the fpm container is visible from the nginx container. Then we can add the fastcgi_pass fpmtestdocker:9000; config directive in the nginx server config.
This is untested, but loosely based on md5's excellent gist. To use this image with nginx, your Dockerfile for that image look like this:
Dockerfile
FROM nginx:1.7
COPY php-fpm.conf /etc/nginx.conf.d/default.conf
An example of the nginx.conf that you copy over might look like this.
php-fpm.conf
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_pass fpmtest:9000;
fastcgi_index index.php;
}
}
Note fastcgi_pass references your container name (fpmtest).

Categories