Can the phpfpm inside the docker container be accessed from outside with nginx fastcgi_pass?
i have installed nginx on my ubuntu with apt install nginx and i'm want to configure nginx with phpfpm but phpfpm in docker container
docker-compose
version: "2"
services:
phpfpm:
image: bitnami/php-fpm:7.1
container_name: "phpfpm_7.1"
ports:
- 9000:9000
network_mode: "host"
volumes:
- ./tester/:/app
nginx config
location ~* \.php$ {
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_nam$
fastcgi_pass 127.0.0.1:9000;
}
try access file php in browser ,nginx say File not found.
finnaly its works im trying to change docker compose file to
version: "2"
services:
phpfpm7:
image: bitnami/php-fpm:7.1
container_name: "phpfpm_7.1"
volumes:
- /var/www/:/var/www/
networks:
vpcbr:
ipv4_address: 192.168.85.2
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: 192.168.85.0/24
nginx config :
fastcgi_pass 192.168.85.2:9000;
fastcgi_index index.php;
include fastcgi.conf;
Related
I have the following 4 containers:
php-fpm for Laravel API backend
node.js container for the Next.js frontend
nginx container
mysql container
I am able to call the Laravel API and get the correct JSON data from Postman using http://localhost:8088/api/products , but when I try from the Node container, I get FetchError: request to http://localhost:8088/api/ failed, reason: connect ECONNREFUSED 10.0.238.3:8088. I am not sure if it's the nginx configuration issue, or docker-compose.yml configuration issue.
I also tried to call the API from the node container using several other options (none of them worked):
http://php:8088/api/products
http://localhost:8088/api/products
http://php:9000/api/products - gives a different error: FetchError: request to http://php:9000/api/products/ failed, reason: read ECONNRESET
This is the docker-compose.yml:
networks:
laravel:
driver: bridge
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8088:80"
volumes:
- ./laravel-app:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
- mysql
- node
networks:
- laravel
mysql:
image: mysql
container_name: mysql
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
networks:
- laravel
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./laravel-app:/var/www/html
ports:
- "9000:9000"
networks:
- laravel
node:
build:
context: ./nextjs
dockerfile: Dockerfile
container_name: next
volumes:
- ./nextjs:/var/www/html
ports:
- "3000:3000"
- "49153:49153"
networks:
- laravel
And this is the nginx default.conf file:
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 /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
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;
}
}
If you want to reach your Laravel API from the node service, you must use http://nginx/your_api_endpoint.
Nginx acts as a reverse proxy here, it takes the traffic on the port 80 (listen 80;) and redirects it to your Laravel container (fastcgi_pass php:9000;).
So your target is not the Laravel container itself, it is nginx.
http://nginx/api/products/ should works if everything else is ok.
Can't resolve site nginx host inside docker nginx (and other in same network) container.
➜ dockerised-php git:(master) ✗ tree .
.
├── code
│ └── index.php
├── docker-compose.yml
├── README.md
└── site.conf
1 directory, 4 files
site.conf:
server {
listen 80;
index index.php index.html;
server_name docker-test.loc;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code;
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;
}
}
docker-compose
version: '2'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/default.conf
networks:
- code-network
php:
image: php:fpm
volumes:
- ./code:/code
networks:
- code-network
networks:
code-network:
docker-test.loc resolving from browser, but
docker exec -it dockerised-php_web_1 bash
nslookup docker-test.loc
# connection timed out; no servers could be reached
outside
➜ ~ nslookup docker-test.loc
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: docker-test.loc
Address: 127.0.0.1
docker container resolver:
➜ ~ docker exec -it dockerised-php_web_1 bash
root#6340952094ed:/# cat /etc/resolv.conf
search Dlink
nameserver 127.0.0.11
options ndots:0
I tried cat "127.0.0.1 docker-test.loc" >> /etc/hosts inside nginx container but it not helps.
What should I do to resolve docker-test.loc inside container?
You can edit docker-compose.yml file to add container_name for web service like that:
version: '2'
services:
web:
image: nginx:latest
ports:
- "8080:80"
container_name: docker-test.loc
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/default.conf
networks:
- code-network
php:
image: php:fpm
volumes:
- ./code:/code
networks:
- code-network
networks:
code-network:
Then all container in the code-network can resolve docker-test.loc as IP address of your web-service container in your docker compose.
EDIT
For more than one hostname(virtualhost) in your nginx container you can use external_links like that:
version: '2'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/default.conf
networks:
- code-network
php:
image: php:fpm
volumes:
- ./code:/code
networks:
- code-network
external_links:
- web:docker-test__1.loc
- web:docker-test__2.loc
- web:abcdef.vn
networks:
code-network:
Thanks.
I have two docker-compose.yml files
THe first one is a global one and am using it to configure nginx webserver and the other one am using it for holding the application code and below are their configurations
First one with nginx configuration
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: globaldocker
container_name: app
restart: unless-stopped
tty: true
working_dir: /var/www
volumes:
- ./:/var/www
- ./dockerconfig/php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- common_network
webserver:
image: nginx
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./dockerconfig/nginx/:/etc/nginx/conf.d/
networks:
- webserver_network
- common_network
networks:
common_network:
external: false
webserver_network:
external: false
The above creates two networks
global_docker_common_network, global_docker_webserver_network
On the docker config folder there is a nginx configuration like
server {
listen 80;
server_name pos.test www.pos.test;
index index.php index.html;
//other nginx configurations for pos.test
}
ON THE docker-compose configuration with php file
Now the one one holding the source code for pos.test i have the following configuration
app:
build:
context: .
dockerfile: Dockerfile
image: posapp/php
container_name: envanto_pos
restart: unless-stopped
tty: true
working_dir: /var/www/pos
volumes:
- ./:/var/www/pos
- ./dockerconfig/nginx/:/etc/nginx/conf.d/
networks:
- globaldocker_webserver_network
networks:
globaldocker_webserver_network:
external: true
Which i have added the external network
When i try accessing nginx pos.test it doesnt display the application but only shows the default nginx page
I have tried accessing the first docker nginx configuration bash and checked on the var/www/pos folder but i cant see the files from the second docker config(source code).
How do i share volumes with my nginx docker configuration container so that when i access docker via exposed port 80 am able to access my site pos.test
What am i missing out on this to make this work?
UPDATE
The two docker configuration files are located on different folders on my host machine
UPDATE ON THE QUESTION
This is my nginx config file
server {
listen 80;
server_name pos.test www.pos.test;
index index.php index.html;
error_log /var/log/nginx/pos_error.log;
access_log /var/log/nginx/pos_access.log;
root /var/www/pos/web;
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;
}
}
you are mounting the current directory of docker-compose file each. So the only that container will have the source code which resides in the same source code directory.
You need some common directory
First File
volumes:
- /path_to_sc/common:/var/www
Second File
volumes:
- /path_to_sc/common:/var/www/pos
When I try accessing Nginx pos.test it doesn't display the application
but only shows the default Nginx page
Probably you first File not picking correct configuration. Double-check ./dockerconfig/nginx/:/etc/nginx/conf.d/ or run the command inside docker to verify the correct configuration file.
docker exec nginx bash -c "cat /etc/nginx/conf.d/filename.conf`
I have tried accessing the first docker nginx configuration bash and
checked on the var/www/pos folder but i cant see the files from the
second docker config(source code).
Mount the common directory so that can accessible for both containers.
update:
From your comment, it seems like there is a syntax error in your docker-compose file. Take a look into this example
web:
image: nginx
volumes:
- ./data:/var/www/html/
ports:
- 80:80
command: [nginx-debug, '-g', 'daemon off;']
web2:
image: nginx
volumes:
- ./data:/var/www/html
command: [nginx-debug, '-g', 'daemon off;']
I have setup a global docker configuration which i expect to handle nginx,and database configuration. This has the following configuration
webserver:
image: nginx
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./dockerconfig/nginx/conf.d/:/etc/nginx/conf.d/
networks:
- common
networks:
common:
driver: bridge
on the folder dockerconfig/nginx/conf.d i have a file pos.test with the following nginx config
server {
listen 80;
server_name pos.test www.pos.test;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/web;
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;
}
}
ON THE SECOND DOCKER configuration file i have
Now i have another docker configuration with the following
app:
build:
context: .
dockerfile: Dockerfile
image: posapp/php
container_name: envanto_pos
restart: unless-stopped
tty: true
working_dir: /var/www/pos
volumes:
- ./:/var/www/pos
networks:
- common
networks:
common:
driver: bridge
Now after running both docker files via docker-compose up -d they both run without any issue but now i nginx cannot run the domain pos.test where the app code is executed on the second docker file
The idea behind this is to have one docker-compose configuration file handle nginx server while the other configuration to copy files is handled by the other docker configuration files
How can i make both docker configurations work as including the network part with a bridge fails to work.What am i missing out.
UPDATE
I know one of the way to solve this would be to add a single docker config file but i want to split the docker config files to different configuration files
You are most likely running the docker-compose command from different directories, and not overriding the compose project name. Docker compose will prefix objects created, like containers, volumes, and networks, with the project name, to allow different instances to be run in isolation from each other.
To solve this, you need a known name of the network, and you'll want to define it as external to at least one of your compose files. When the network is defined as external, compose will not try to create it, but will require that it was already created externally, either by a docker network create command or by the other compose file.
To create the network with a known name, you can specify the name value in newer versions of the docker compose file.
Here is the first compose file that would create the network with a known name:
version: '3.7'
services:
webserver:
image: nginx
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./dockerconfig/nginx/conf.d/:/etc/nginx/conf.d/
networks:
- common
networks:
common:
external: false
name: common
And the second compose file that would use the already created network:
version: '3.7'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: posapp/php
container_name: envanto_pos
restart: unless-stopped
tty: true
working_dir: /var/www/pos
volumes:
- ./:/var/www/pos
networks:
- common
networks:
common:
external: true
name: common
The problem is that you're redefining the common network.
You can define the 2 docker-compose.yml files as follow:
docker-compose.yml
networks:
common:
driver: bridge
services:
app:
build:
context: .
dockerfile: Dockerfile
image: posapp/php
container_name: envanto_pos
restart: unless-stopped
tty: true
working_dir: /var/www/pos
volumes:
- ./${AppPath}/:/var/www/pos
networks:
- common
and docker-compose.webserver.yml
services:
webserver:
image: nginx
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./${WebserverPath}/:/var/www
- ./${WebserverPath}/dockerconfig/nginx/conf.d/:/etc/nginx/conf.d/
networks:
- common
and start the application with:
docker-compose -f docker-compose.yml -f docker-compose.webserver.yml up -d
Trying to add varnish to nginx using a docker container name rather than IP address.
I've tried adding it directly set_real_ip_from site-varnish but that doesn't work.
Tried adding an upstream (below) and tried set_real_ip_from varnish_backend with no luck
upstream varnish_backend {
server site-varnish;
}
Any help would be appreciated. I've added below the current working conf for reference.
upstream fastcgi_backend {
server site-fpm;
}
server {
listen 80;
listen 443 ssl;
server_name localhost;
location = /ping {
set_real_ip_from 192.168.176.2;
real_ip_header X-Forwarded-For;
access_log off;
allow 127.0.0.1;
deny all;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass fastcgi_backend;
}
}
docker-compose.yml
version: "2"
services:
site-varnish:
build:
context: ./etc/varnish/
ports:
- 80
networks:
- frontend
site-web:
build:
context: ./etc/nginx/
volumes_from:
- site-appdata
env_file:
- ./global.env
restart: always
networks:
- backend
- frontend
site-fpm:
build:
context: ./etc/7.2-fpm/
ports:
- 9000
volumes_from:
- site-appdata
env_file:
- ./global.env
networks:
- backend
site-appdata:
image: tianon/true
volumes:
- ./html:/var/www/html
networks:
frontend:
external:
name: webproxy
backend:
external:
name: backbone
I've updated the nginx version based upon #LinPy suggestion, to > 1.13.1 and am able to use set_real_ip_from site-varnish directly inside my conf.