Nginx reverse-proxy not serving static files - docker

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.

Related

Error 504 Gateway Time-out when running nginx in docker through docker-compose

I'm using nginx in docker-compose file for handling my frontend and backend website.
I had no problems for a long time but once I've got the error "504 Gateway Time-out" when I try to access my project through localhost and it's port
http://localhost:8080
when I type docker Ip and its port
http://172.18.0.1:8080
I can access the project and nginx works correctly.
I'm sure my config file is correct because It was working for 6 months and I don't know what happened for it.
what should I check to find the problem?
docker-compose file:
.
.
.
nginx:
container_name: nginx
image: nginx:1.19-alpine
restart: unless-stopped
ports:
- '8080:80'
volumes:
- ./frontend:/var/www/html/frontend
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
networks:
- backend_appx
networks:
backend_appx :
external: true
.
.
nginx config file:
upstream nextjs_upstream {
server next_app:3000;
}
server {
listen 80 default_server;
server_name _;
server_tokens off;
# set root
root /var/www/html/frontend;
# set log
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
location /_next/static {
proxy_cache STATIC;
proxy_pass http://nextjs_upstream;
add_header X-Cache-Status $upstream_cache_status;
}
}

Nginx Reverse Proxy on docker containers : 404 redirections

I'm trying to deploy a docker-compose stack that contains a Nginx service to manage the others like Jenkins or Grafana. However, when I target my Jenkins service like http://myapp.fr/jenkins, the homepage of the service will redirect to the login page at this URL: http://myapp.fr/login?from=%2F. How I can fix this for all services to prefix with the service name for all pages of it (like http://myapp.fr/jenkins/login?from=%2F).
My stack looks like this :
version: "3.7"
services:
## NGINX ##
web:
image: nginx
container_name: myapp_nginx
volumes:
- ./config/nginx/templates:/etc/nginx/templates
- ./config/nginx/include.d:/etc/nginx/include.d
- ./config/nginx/www:/var/www/certbot
ports:
- "80:80"
- "443:443"
environment:
- NGINX_HOST=myapp.fr
- NGINX_PORT=80
networks:
- myapp
## JENKINS ##
jenkins:
build:
context: ./dockerfile/jenkins
dockerfile: Dockerfile
container_name: myapp_jenkins
hostname: jenkins.myapp.fr
privileged: true
user: root
ports:
- 8080:8080
- 50000:50000
volumes:
- ~/jenkins:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/local/bin/docker:/usr/local/bin/docker
restart: always
networks:
- myapp
## GRAFANA ##
grafana:
image: grafana/grafana-enterprise:8.2.0
container_name: myapp_grafana
hostname: grafana.myapp.fr
ports:
- 3000:3000
user: "104"
networks:
- myapp
networks:
myapp:
driver: bridge
My default.conf of nginx is in one of my docker volumes and it looks like this :
server {
listen 80;
listen [::]:80;
server_name myapp.fr;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /jenkins/ {
proxy_set_header Host $host;
add_header Access-Control-Allow-Origin '*';
proxy_pass http://jenkins.myapp.fr:8080/;
}
location /grafana/ {
proxy_set_header Host $host;
add_header Access-Control-Allow-Origin '*';
proxy_pass http://grafana.myapp.fr:3000/;
}
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Access-Control-Allow-Origin';
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
When I began the deploy, I use a docker-compose up -d command and all services are running. myapp.fr show the nginx index. However, if I specified the subpath myapp.fr/jenkins, it will be showig a 404 error because of a redirection to http://myapp.fr/login?from=%2F
How I can fix this for all services to prefix service name for all pages of it (like http://myapp.fr/jenkins/login?from=%2F).
Thanks
You have to tell Jenkins that you are using an additional context path, so it generates all the redirections with the added context. You can do this by passing the --prefix=/jenkins on startup. You can pass this through JENKINS_OPTS environment variable as well. Following is how you can pass this to docker run.
docker run --name myjenkins -p 8080:8080 -p 50000:50000 --env JENKINS_OPTS="--prefix=/jenkins" jenkins/jenkins:lts
Update
Following is a sample NginX configuration you can use. Note the proxy_redirect option specified, which makes sure all redirect URLs are changed to your correct Hostname.
server {
listen 80;
server_name jenkins.ycr.com;
location /jenkins {
proxy_pass http://127.0.0.1:8081;
proxy_redirect http://127.0.0.1:8081/ http://jenkins.ycr.com/;
}
}

nginx reverse proxy with part of url as dynamic

i have a django app and nginx as services on docker-compose. Am using nginx as a reverse proxy.
here is the docker compose file
version: "3.8"
services:
# nginx reverse proxy
nginx:
image: nginx:1.17.10
container_name: nginx
ports:
- "80:80"
restart: on-failure
depends_on:
- app
app:
image: django-app-image
conatinter_name: app
expose
- 8001
restart: on-failure
here is the nginx configuration
user www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# sendfile on;
upstream django-app {
server app:8001;
}
server {
listen 80;
listen [::]:80;
location /vocal-bm{
client_max_body_size 0;
proxy_pass http://django-app/vocal-bm;
proxy_set_header Host $host;
}
}
This is what i want to achieve:
I should visit http://localhost/vocal-bm/<some-variable>
and the route served should be http://django-app/vocal-bm/<some-variable>
The above configuration just routes to http://django-app
How do I get it to work i.e route to http://django-app/vocal-bm/<some-variable>
What I have tried
adding a trailing slash on the proxy_pass proxy_pass http://django-app/vocal-bm/;
but a get http://django-app/vocal-bm//<some-variable> with the double slash before the dynamic variable.
I have also tried the rewrite but it gives http://django-app also

Docker nginx / bad gateway : multiple app with docker-compose

sorry for the question. I'm new with docker and nginx. I need some help
So, I have a docker with the nginx proxy and 3 dockers with 3 different applications
I don't know how to configure nginx at all to avoid bad gateway errors on my 3 applications. Can you please help me?
I can only find help for this problem on 1 application.
My docker-compose
version: '2.1'
services:
proxy:
container_name: proxy
hostname: proxy
build: .docker/nginx
ports:
- "80:80" #80:80
- "443:443"
volumes:
- ./certs:/etc/nginx/certs
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
- proxy
restart: always
networks:
proxy:
external: true
My DockerFile
FROM jwilder/nginx-proxy
RUN { \
echo 'client_max_body_size 500M;'; \
} > /etc/nginx/conf.d/my_proxy.conf
App1
version: '3'
services:
apache:
build: .docker/apache
container_name: app1_apache
environment:
VIRTUAL_HOST: "app1.local"
expose:
- "80"
volumes:
- .docker/config/vhosts:/etc/apache2/sites-enabled
- ../../app1:/var/www/app1.local
depends_on:
- php
networks:
- default
- proxy
php:
build: .docker/php
container_name: app1_php
environment:
VIRTUAL_HOST: "app1.local"
volumes:
- ../../app1:/var/www/app1.local
networks:
- default
- proxy
networks:
proxy:
external: true
Same file for App2 and App3
I found this solution but I don't understand how to implement it.
nginx docker container: 502 bad gateway response
I need to modify the nginx config.d configuration file but I don't see how I can do that.
my default config.d file
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
So, I have to add
upstream app1{
//insert your hosts ip here
server 192.168.99.100:8080;
}
upstream app2{
//insert your hosts ip here
server 192.168.99.100:8080;
}
upstream app3{
//insert your hosts ip here
server 192.168.99.100:8080;
}
That's right ?
Do I also have to change the proxy_pass?
The nginx configuration is really obscure to me.
Thank you for your help

nginx 403 Forbidden on laravel project with docker

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

Resources