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.
Related
I try to create a small webserver on my raspberry pi with docker.
This is my docker-compose file:
version: "3.6"
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- /home/pi/testData/code:/var/www/html
- /home/pi/testData/site.conf:/etc/nginx/conf.d/site.conf
depends_on:
- php
php:
image: php:7.4-fpm
volumes:
- /home/pi/testData/code:/var/www/html
And this my site.conf
server {
index index.html index.php;
listen 80;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Inside of the folder /home/pi/testData/code is a file named index.php which just echos a Hello World.
So this file will be mapped into the Docker Container into the path /var/www/html/ and inside of the site.conf is the root mentioned also to /var/www/html.
I also checked if the files are really available inside of the nginx container - both are.
So as I understand it: If I put an index-file inside of the /var/www/html folder of my nginx docker container, then this file should be displayed if I call the IP of my Raspberry pi on Port 8080.
But unfortunately I only receive the Welcome to Nginx Page.
Did I miss something or did I something wrong?
Nginx will load configuration files found in /etc/nginx/conf.d/ and their names ends with .conf as suffix in alphabetical order.
Your configuration does have conflicting server name with the default configuration file of nginx. /etc/nginx/conf.d/default.conf
you can check that by exec into nginx container and run nginx -t command to check the configuration for warnings and errors.
you should see something like:
[warn] 502#502: conflicting server name "localhost" on 0.0.0.0:80, ignored
nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored
you should rename the default file to a something like default.conf.old or you can simply overwrite its contents with your configuration.
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
This seems to be a common issue when people setup a Docker Container to serve a Laravel App using the container.
My setup is mostly this (I removed some of the other services because I do no think they apply here)
#docker-compose up --build
version: "2"
services:
nginx:
image: nginx
depends_on: [pacs-1,mysql_db]
restart: unless-stopped
ports: ["443:443"]
volumes:
- ./nginx-home:/nginx-home
- ./tls:/etc/nginx/tls
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
php-fpm:
build: php-fpm
volumes:
- ./nginx-home:/nginx-home
The default.conf for nginx for Laravel project is:
server {
# implement the TLS
listen 443 ssl;
server_name dockerlaravel.medical.ky;
root /nginx-home/PortalRads/public;
access_log /nginx-home/logs/PortalRads-access.log;
error_log /nginx-home/logs/PortalRads-error.log info;
index index.php index.html index.htm;
client_max_body_size 4000M;
client_body_buffer_size 4000M;
# skip favicon.ico
#
#location = /favicon.ico {
#access_log off;
return 444;
#
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
error_page 404 /error_pages/404.php;
error_page 403 /error_pages/403.php;
error_page 401 /error_pages/401.php;
error_page 500 502 503 504 /errors/50x.html;
}
}
Everything actually seems to work OK once I get it all setup. Composer is installed globally on the host, and I use composer update on the host side to update the package. It does not seem like it is necessary to install composer on Docker with the setup that I have since the php container has php and the artisan binary is at the root of my Laravel app.
The problem that I am having is that the symlink from public/storage to the storage folder does not seem to be working. I have tried various methods to create the link. I actually have separate containers for nginx and php, so artisan will not run in the nginx container.
Since I am using nginx as a webserver, wondering if it might just be possible to have another location block or server block that will basically create that connection on the server side so that I do not have to fiddle around the the symlink created by artisan ?
location /storage/ {
root . . .
. . .
}
I can get into those containers from the CLI using:
sudo docker exec -it orthanc-docker-dev_ris_php-fpm_1 /bin/bash
sudo docker exec -it orthanc-docker-dev_ris_nginx_1 /bin/bash
and I've tried created the symlink from within the container(s) and that does not seem to work either.
As an example, I am using JetStream with Livewire in Laravel and the profile photos there map to:
https://dockerlaravel.medical.ky/storage/profile-photos/image.png
But that gives a 404 error because the symlink must not be setup correctly.
There are quite a few posts about that issue. Just wondering what the "best" solution is, preferably one that can be automated during the build of the containers so the user does not have to worry about that.
Thanks.
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 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).