When I start de Project with php artisan serve everything works fine, but when I start my project with docker-compose up -d there is an error: 403 Forbidden nginx/1.10.3
Nginx default file:
listen [::]:80;
listen 80;
root /var/www/html/public;
index index.html index.htm index.php;
server_name {{getenv "NGINX_SERVER_NAME"}};
server_tokens off;
charset utf-8;
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; }
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/usr/local/var/run/php-fpm.sock;
}
error_page 404 /index.php;
location ~ /\.ht {
deny all;
}
add_header X-Served-By Bitpress.io;
include h5bp/basic.conf;
}
and here is my docker-compose File
docker-compose.yml
version: "3"
networks:
app-tier:
driver: bridge
services:
app:
image: test
container_name: site
build:
context: .
dockerfile: docker/Dockerfile
networks:
- app-tier
env_file:
- .docker.env
ports:
- 5050:80
volumes:
- .:/var/www/html
environment:
APP_ENV: local
CONTAINER_ROLE: app
scheduler:
image: test
container_name: scheduler
depends_on:
- app
env_file:
- .docker.env
volumes:
- .:/var/www/html
environment:
CONTAINER_ROLE: scheduler
queue:
image: test
container_name: queue
depends_on:
- app
env_file:
- .docker.env
volumes:
- .:/var/www/html
environment:
CONTAINER_ROLE: queue
I've seen, that the Permissions from the Directories is root.
I have tried to change it with the commandRUN chown -R www-data:www-data /var/www/html but it not works.
I just update what you have, but won't fix 100% your issues, some stuff have ot be done too, but without all information I cannot do more.
You may need to add php-fpm into your docker-compose.yml
nginx.conf
server {
listen [::]:80;
listen 80;
# will be remove if you run everything inside container
root /var/www/html/public;
# will be remove if you run everything inside container
index index.html index.htm index.php;
server_name {{getenv "NGINX_SERVER_NAME"}};
server_tokens off;
charset utf-8;
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; }
# will be remove
# location / {
# try_files $uri $uri/ /index.php$is_args$args;
# }
# Add this, now nginx only redirect request to expose socket from docker
location / {
proxy_pass http://localhost:5050
proxy_ser_header X-Served-By Bitpress.io;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/usr/local/var/run/php-fpm.sock;
}
# will be remove if you run everything inside container
error_page 404 /index.php;
location ~ /\.ht {
deny all;
}
# will be remove if you run everything inside container
add_header X-Served-By Bitpress.io;
include h5bp/basic.conf;
}
docker-compose.yml
version: "3"
networks:
app-tier:
driver: bridge
services:
app:
image: test
container_name: site
build:
context: .
dockerfile: docker/Dockerfile
networks:
- app-tier
env_file:
- .docker.env
ports:
- 5050:80
volumes:
- .:/var/www/html
# - /absolute/path/better:/var/www/html
environment:
APP_ENV: local
CONTAINER_ROLE: app
scheduler:
image: test
container_name: scheduler
networks: # <-- add thisadd this
- app-tier # <-- add thisadd this
depends_on:
- app
env_file:
- .docker.env
volumes:
- .:/var/www/html
# - /absolute/path/better:/var/www/html
environment:
CONTAINER_ROLE: scheduler
queue:
image: test
container_name: queue
networks: # <-- add thisadd this
- app-tier # <-- add thisadd this
depends_on:
- app
env_file:
- .docker.env
volumes:
- .:/var/www/html
# - /absolute/path/better:/var/www/html
environment:
CONTAINER_ROLE: queue
You may have an issues between env_file: and CONTAINER_ROLE who have the priority: your 3 containers share the shame .docker.env it may be an issues. it may be a good idead to have:
.docker.app.env
.docker.scheduler.env
.docker.queue.env
Related
Upgrading Nginx docker with image tag Nginx:latest causes not executing PHP files and give direct access to web directory!
Upgrading docker-compose.yml from nginx:1.18.0 to Nginx:latest seems to cause a major issue.
Ngnix container not executing PHP files anymore and give direct access to all content of web repository
Details:
Extract of docker-compose.yml (full reproductible example below)
webserver:
#image: nginx:1.8.0
image: nginx:latest
and then "docker-composer up -d"
raises the issue.
Effect:
Nginx 1.18.0 not executing PHP files (using php7.4-fpm) and give direct access to web contains
eg: domain.com/index.php can then be directly downloaded!
First elements:
image nginx:latest or image nginx produce the same effect
image nginx:1.8.0 (nor any explicit x.y.z tag) does not produce this issue
Troubling facts:
nginx image with tag: nginx:mainline download version # nginx version: nginx/1.21.5
nginx image with tag: nginx:latest download a 1.8.0 version # nginx version: nginx/1.8.0
Probable issue :
image nginx:latest has the following file (extract)
/etc/nginx/nginx.conf
html {
(...)
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*; # THIS LINE IS NEW - instantiated a default site
}
Don't know if this point has been noticed
Is a Dockerfile with "rm /etc/nginx/sites-enabled/" cmd an acceptable workaround or a prerequisite?
Reproducible example
docker-compose.yml
version: "3"
services:
cms_php:
image: php:7.4-fpm
container_name: cms_php
restart: unless-stopped
networks:
- internal
- external
volumes:
- ./src:/var/www/html
webserver:
# image: nginx:1.18.0 # OK
# image: nginx:1.17.0 # OK
# image: nginx:mainline # OK
image: nginx:latest # NOK
# image: nginx # NOK
container_name: webserver
depends_on:
- cms_php
restart: unless-stopped
ports:
- 80:80
volumes:
- ./src:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d/
networks:
- external
networks:
external:
driver: bridge
internal:
driver: bridge
nginx-conf/nginx.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
index index.php index.html index.htm;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass cms_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;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
src/index.php
<?php echo "Hi..."; ?>
With the below setup, I am able to get the desired data. I didn't have to make changes to your files. You may have an issue with your paths/setup. Try to imitate my setup. I am using nginx:latest.
$ curl localhost:80
Hi...
Running docker processes in this setup
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------
cms_php docker-php-entrypoint php-fpm Up 9000/tcp
webserver /docker-entrypoint.sh ngin ... Up 0.0.0.0:80->80/tcp
Folder structure
$ tree
.
├── docker-compose.yaml
├── nginx-conf
│ └── nginx.conf
└── src
└── index.php
2 directories, 3 files
src/index.php
$ cat src/index.php
<?php echo "Hi..."; ?>
docker-compose.yaml
$ cat docker-compose.yaml
version: "3"
services:
cms_php:
image: php:7.4-fpm
container_name: cms_php
restart: unless-stopped
networks:
- internal
- external
volumes:
- ./src:/var/www/html
webserver:
image: nginx:latest
container_name: webserver
depends_on:
- cms_php
restart: unless-stopped
ports:
- 80:80
volumes:
- ./src:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d/
networks:
- external
networks:
external:
driver: bridge
internal:
driver: bridge
nginx-conf/nginx.conf
$ cat nginx-conf/nginx.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
index index.php index.html index.htm;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass cms_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;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico {
log_not_found off; access_log off;
}
location = /robots.txt {
log_not_found off; access_log off; allow all;
}
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
}
Good day. Can I ask for some help? I just started to learn docker and create my local set. All of my containers(nginx, app, mysql) are running ok but I can't access my test app in browser.
Here's my docker-compose.yml file
version: '3'
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8088:80"
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- mysql
- php
mysql:
image: mysql:5.7.22
container_name: mysql
tty: true
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: localdb
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./src:/var/www/html
ports:
- "9000:9000"
And here's my default.conf for nginx
server {
listen 80;
index index.html index.html;
servername 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.html?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.html;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
According to your comment, the problem is located at your docker-compose file. You want to access your nginx server on port 81, but you bind your nginx on port 8088.
So simply change the port binding from 8088:80 to 81:80. This should fix your problem.
If you want to learn more about port binding, just have a look at the documentation: https://docs.docker.com/compose/compose-file/compose-file-v3/#ports
Here is a fixed example:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "81:80"
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- mysql
- php
It's because containers can't access your host (That is your main os) you have to use -p for connecting the ports of your container to your computer (main os)
For example you use docker run npm
and imagine by your setup npm runs at port 3000
now you have to do networking of your container
use docker run -p 3000:3000 npm
The -p 3000:3000 says that your 3000 port of your container now attach to the 3000 port of your main os and now you can see your site (that is run on your container in your main os web browser in the specific port (3000))
I am new to this and I don't really know what I did, but it worked without running docker run -p [port:port] [container] command. I did some changes on my docker-compose.yml and default.conf
I was so happy that it is running now, but it would be great if someone could just explain how it worked. Thanks for all the response.
docker-compose.yml
version: '3'
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "80:80"
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- mysql
- php
mysql:
image: mysql:5.7.22
container_name: mysql
tty: true
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: localdb
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./src:/var/www/html
ports:
- "9000:9000"
default.config
server {
listen 80;
index index.html 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.html?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.html;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
I am trying to set up a Dockerised Mern app secured with ssl. So far i have managed to serve my react app via nginx container, but am now having issues with my api backend.
if my web page sends a https request to my nginx container, how can i take that request, downgrade it to http, and send it to the api container, and securely return the response? it this even the preferred approach?
my Nginx conf
server {
listen 80;
server_name example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
root /var/www/html/build;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
index index.html
try_files $uri $uri/ #backend;
}
location /login {
return 301 https://$host;
}
location #backend {
proxy_pass https://example.com;
}
my docker-compose.yml
version: '3.7'
services:
nginx:
image: nginx:1.15-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./data/build:/var/www/html/build
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
backend:
container_name: backend
restart: unless-stopped
build: ./api
ports:
- '3001:3001'
env_file: ./api/.env
environment:
- NODE_ENV=production
I managed to find a solution to my problem.
i changed by docker-compose.yml to:
version: '3.7'
services:
nginx:
image: nginx:1.15-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./data/build:/var/www/html/build
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
links:
- backend
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
backend:
container_name: backend
restart: unless-stopped
build: ./api
ports:
- '3001:3001'
env_file: ./api/.env
environment:
- NODE_ENV=production
and my nginx conf to:
server {
listen 80;
server_name example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
root /var/www/html/build;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
index index.html
try_files $uri $uri/ #backend;
}
location /login {
return 301 https://$host;
}
location #backend {
proxy_pass https://example.com;
}
location /api/ {
proxy_pass http://backend:3001/api/;
}
I tried to start some services via docker-compose. One of them is a nginx reverse-proxy, handling different paths. One path ("/react") is to a containerized react_app with a nginx on port 80. Solely, the reverse-proxy is working correctly. Also, if I server the nginx of the react_app on port 80, all work's fine. Combining both without changing anything in the config leads to 404 for static files like css and js.
Setup #1
Correct forward for path /test to Google.
docker-compose.yml
version: "3"
services:
#react_app:
# container_name: react_app
# image: react_image
# build: .
reverse-proxy:
image: nginx:latest
container_name: reverse-proxy
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- '80:80'
nginx.conf (reverse-proxy)
location /test {
proxy_pass http://www.google.com/;
}
Setup #2
No reverse proxy. Correct answer from nginx inside of container react_app.
docker-compose.yml
version: "3"
services:
react_app:
container_name: react_app
image: react_image
build: .
#reverse-proxy:
# image: nginx:latest
# container_name: reverse-proxy
# volumes:
# - ./nginx.conf:/etc/nginx/nginx.conf
# ports:
# - '80:80'
Setup #3 (not working!)
Reverse proxy and React App with nginx. Loads index.html, but fails so load files in /static
nginx.conf (reverse-proxy)
location /react {
proxy_pass http://react_app/;
}
docker-compose.yml
version: "3"
services:
react_app:
container_name: react_app
image: react_image
build: .
reverse-proxy:
image: nginx:latest
container_name: reverse-proxy
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- '80:80'
Activating both systems leads to failing static content. It seems to me that the reverse-proxy tries to server the files, but fails (for good reason), because there is no log entry in reac_app's nginx. Here's the config from the reac_app nginx, perhaps I'm missing something out.
nginx.conf (inside react_app container)
events {}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
try_files $uri /index.html;
}
}
}
--> Update
This is a rather unsatisfying workaround - but it works. Although now reacts routing is messed up. I cannot reach /react/login
http {
server {
server_name services;
location /react {
proxy_pass http://react_app/;
}
location /static/css {
proxy_pass http://react_app/static/css;
add_header Content-Type text/css;
}
location /static/js {
proxy_pass http://react_app/statics/js;
add_header Content-Type application/x-javascript;
}
}
}
If you check the paths of the missing static files in your browser, you'll notice their relative paths are not what you expect. You can fix this by adding sub filters inside your nginx reverse proxy configuration.
http {
server {
server_name services;
location /react {
proxy_pass http://react_app/;
######## Add the following ##########
sub_filter 'action="/' 'action="/react/';
sub_filter 'href="/' 'href="/react/';
sub_filter 'src="/' 'src="/react/';
sub_filter_once off;
#####################################
}
}
}
This will update the relative paths to your static files.
I have one node.js application (web-app) and two lumen applications (api, customer-api) that are load balanced by an nginx container listening on port 80.
My docker-compose.yml file:
version: '2'
services:
nginx:
build:
context: ../
dockerfile: posbytz-docker/nginx/dockerfile
volumes:
- api
- customer-api
ports:
- "80:80"
networks:
- network
depends_on:
- web-app
- api
- customer-api
web-app:
build:
context: ../
dockerfile: posbytz-docker/web-app-dockerfile
volumes:
- ../web-app:/posbytz/web-app
- /posbytz/web-app/node_modules
ports:
- "3004:3004"
networks:
- network
api:
build:
context: ../
dockerfile: posbytz-docker/api-dockerfile
volumes:
- ../api:/var/www/api
networks:
- network
customer-api:
build:
context: ../
dockerfile: posbytz-docker/customer-api-dockerfile
volumes:
- ../customer-api:/var/www/customer-api
networks:
- network
redis:
image: redis
ports:
- "6379:6379"
networks:
- network
memcached:
image: memcached
ports:
- "11211:11211"
networks:
- network
mysql:
image: mysql:5.7
volumes:
- ./db-data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- network
adminer:
image: adminer
restart: always
ports:
- "9001:8080"
networks:
- network
networks:
network:
driver: bridge
Since I am using a bridged network, I am able to access each container from another container using the container names. But what I want instead is, access the containers using the server_name of their nginx configuation.
Below are the nginx configuration of each application,
web-app.conf:
server {
listen 80;
server_name posbytz.local;
resolver 127.0.0.11 valid=10s;
location / {
proxy_pass http://web-app:3004;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
api.conf:
server {
listen 80;
index index.php index.html;
root /var/www/api/public;
server_name api.posbytz.local;
resolver 127.0.0.11 valid=10s;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass api:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
customer-api.conf
server {
listen 80;
index index.php index.html;
root /var/www/customer-api/public;
server_name customer-api.posbytz.local;
resolver 127.0.0.11 valid=10s;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass customer-api:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
The problem
I want to access both api and customer-api containers from web-app container. The problem is when I try curl http://nginx I'am only getting response from the api container. Is there any way to access the customer-api container through the nginx container?
What I tried
When I manually mapped the IP of nginx container (172.21.0.9) with their respective server_name in the /etc/hosts file on the web-app container it seems to work.
What I added on /etc/hosts file on web-app container:
172.21.0.9 api.posbytz.local
172.21.0.9 customer-api.posbytz.local
Is there any other way to achieve this without manual intervention?
Finally made it to work by changing the nginx configuration on customer-api.conf to listen on port 81 ie. listen 80; to listen 81;. Now http://nginx resolves to http://api:9000 and http://nginx:81 resolves to http://customer-api:9000
You can use aliases:
networks:
some-network:
aliases:
- api.posbytz.local
- customer-api.posbytz.local