Organize home server docker containers behind nginx proxy [resolved] - docker

I have a home server I use primarily for self-hosted applications (notes, git server, Jenkins server, etc.) that I'd like to organize so I don't have to remember all the ports for each container. I was hoping to setup a structure as follows:
http://home.server/
http://home.server/jenkins
http://home.server/cowyo
http://home.server/pihole
etc…
I'd like the root endpoint to route to a container running google's cadvisor for monitoring the status of all my containers, /jenkins to route to Jenkins, /pihole to pi-hole, etc.
Here's how I setup my docker-compose and nginx.conf files based on my understanding of the configuration schema:
docker-compose.yml:
version: '3'
services:
webserver:
image: nginx:alpine
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
restart: unless-stopped
cadvisor:
image: 'google/cadvisor'
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
ports:
- "8090:8090"
pi-hole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "67:67/udp"
- "8070:8070/tcp"
- "4437:4437/tcp"
environment:
TZ: 'America/Chicago'
# WEBPASSWORD: 'set a secure password here or it will be random'
# Volumes store your data between container upgrades
volumes:
- './etc-pihole/:/etc/pihole/'
- './etc-dnsmasq.d/:/etc/dnsmasq.d/'
dns:
- 127.0.0.1
- 1.1.1.1
# Recommended but not required (DHCP needs NET_ADMIN)
# https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
cap_add:
- NET_ADMIN
restart: unless-stopped
cowyo:
image: 'schollz/cowyo'
ports:
- "8050:8050"
volumes:
- './cowyo/data/:/data/'
restart: unless-stopped
jenkins:
image: 'bitnami/jenkins:2'
ports:
- '8080:8080'
- '8443:8443'
- '50000:50000'
volumes:
- 'jenkins_data:/bitnami'
restart: unless-stopped
volumes:
jenkins_data:
driver: local
nginx.conf:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream docker-cadvisor {
server cadvisor:8090;
}
upstream docker-pihole {
server pi-hole:8070;
}
upstream docker-cowyo {
server cowyo:8050;
}
upstream docker-jenkins {
server jenkins:8080;
}
server {
listen 80;
location / {
proxy_pass http://docker-cadvisor;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
server {
listen 80;
location /pihole {
proxy_pass http://docker-pihole;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
server {
listen 80;
location /cowyo {
proxy_pass http://docker-cowyo;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
server {
listen 80;
location /jenkins {
proxy_pass http://docker-jenkins;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
Any ideas on what I'm doing wrong? Any help would be appreciated.
Edit: The problem with the way it runs now is that when I go to one of the urls above, I get a "this website can't be reached" error.
Edit2: The problem above was caused by a bad nginx.conf file which was causing the docker container to not start properly. After resolving that, I get a "502 Bad Gateway".
Edit3 [resolution]: My solution was in this stack overflow answer. TLDR is I had to add the line "network_mode: host" to the nginx section in my docker-compose.yml file.

What is the error you are getting ? Tre below config and if you don't get expected result then see respective logs for the error .
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream docker-cadvisor {
server cadvisor:8090;
}
upstream docker-pihole {
server pi-hole:8070;
}
upstream docker-cowyo {
server cowyo:8050;
}
upstream docker-jenkins {
server jenkins:8080;
}
server {
listen 80;
server_name home.server;
fastcgi_param home.server $host;
location / {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_pass http://docker-cadvisor;
}
access_log /tmp/cadvisor-access.log main;
error_log /tmp/cadvisor-error.log error;
}
server {
listen 80;
server_name home.server;
fastcgi_param home.server $host;
location /jenkins {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_pass http://docker-jenkins;
}
access_log /tmp/jenkins-access.log main;
error_log /tmp/jenkins-error.log error;
}
server {
listen 80;
server_name home.server;
fastcgi_param home.server $host;
location /cowyo {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_pass http://docker-cowyo;
}
access_log /tmp/cowyo-access.log main;
error_log /tmp/cowyo-error.log error;
}
server {
listen 80;
server_name home.server;
fastcgi_param home.server $host;
location /pihole {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_pass http://docker-pihole;
}
access_log /tmp/pihole-access.log main;
error_log /tmp/pihole-error.log error;
}
}

I think you should change to
upstream docker-cadvisor {
server 127.0.0.1:8090;
}
upstream docker-pihole {
server 127.0.0.1:8070;
}
upstream docker-cowyo {
server 127.0.0.1:8050;
}
upstream docker-jenkins {
server 127.0.0.1:8080;
}

Related

nginx multiple locations using proxy_path to different urls leads to 502 response

I made an nginx.conf file, my issue is that the all the proxy_pass redirects end up being 502 Bad Gateway messages.
Here is the nginx.conf:
http {
server {
listen 80;
server_tokens off;
location / {
client_max_body_size 0;
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://172.21.144.10;
}
}
server {
listen 443;
server_tokens off;
location / {
client_max_body_size 0;
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://172.21.144.10:443;
}
}
}
The url http://172.21.144.10 points to a gitlab-ce install in another docker container, it is accessible via the browser.
I've tried both proxy_pass with and without a trailing slash, so that's not the issue.

Can't get client's real IP when using Nginx in Docker

I have configured Nginx reverse proxy with Docker in my project.
part of my docker-compose file:
version: "3"
# optional ports are specified throughout for more advanced use cases.
services:
proxy-service:
container_name: budi-nginx-dev
restart: on-failure
image: nginx:latest
volumes:
- ./.generated-nginx.dev.conf:/etc/nginx/nginx.conf
ports:
- "${MAIN_PORT}:10000"
depends_on:
- minio-service
- couchdb-service
extra_hosts:
- "host.docker.internal:host-gateway"
I have add "X-Forwarded-For proxy_set_header" in "location /api/".
part of my nginx file:
user nginx;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 33282;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
proxy_set_header Host $host;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
map $http_upgrade $connection_upgrade {
default "upgrade";
}
server {
listen 10000 default_server;
server_name _;
client_max_body_size 1000m;
ignore_invalid_headers off;
proxy_buffering off;
location ~ ^/api/(system|admin|global)/ {
proxy_pass http://host.docker.internal:4002;
}
location /api/ {
proxy_read_timeout 120s;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://host.docker.internal:4001;
}
location /app_ {
proxy_pass http://host.docker.internal:4001;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://minio-service:9000;
}
client_header_timeout 60;
client_body_timeout 60;
keepalive_timeout 60;
gzip off;
gzip_comp_level 4;
}
}
When I request api that start with "api/", I get "127.20.0.1" of "X-Forwarded-For" property in the request header. Obviously it is not the real client ip.
I would like to known how to get the real client ip in this case.

Getting NGINX to point to docker mattermost-preview

I'm trying to follow this: https://forum.mattermost.org/t/recipe-embedding-mattermost-in-web-applications-using-an-iframe-unsupported-recipe/10233
I'm running a dockerized version of mattermost. I am running a dockerized container of nginx. I configured my nginx according to: https://docs.mattermost.com/install/install-ubuntu-1804.html#configuring-nginx-as-a-proxy-for-mattermost-server
I have the mattermost-preview container running on localhost:8065.
I followed the steps and restart the nginx instance and visit localhost:80 but still see the default nginx welcome page.
Here's my default.conf:
upstream backend {
server localhost:8065;
keepalive 32;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mattermost_cache:10m max_size=3g inactive=120m use_temp_path=off;
server {
listen 80 default_server;
server_name localhost;
return 301 https://$server_name$request_uri;
}
server {
listen 443 http2;
server_name localhost_two;
http2_push_preload on; # Enable HTTP/2 Server Push
ssl off;
location ~ /api/v[0-9]+/(users/)?websocket$ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 50M;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_hide_header Content-Security-Policy;
proxy_hide_header X-Frame-Options;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
client_body_timeout 60;
send_timeout 300;
lingering_timeout 5;
proxy_connect_timeout 90;
proxy_send_timeout 300;
proxy_read_timeout 90s;
proxy_http_version 1.1;
proxy_pass http://backend;
}
location / {
client_max_body_size 50M;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_hide_header Content-Security-Policy;
proxy_hide_header X-Frame-Options;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
proxy_read_timeout 600s;
proxy_cache mattermost_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 2;
proxy_cache_use_stale timeout;
proxy_cache_lock on;
proxy_http_version 1.1;
proxy_pass http://backend;
}
}
# This block is useful for debugging TLS v1.3. Please feel free to remove this
# and use the `$ssl_early_data` variable exposed by NGINX directly should you
# wish to do so.
map $ssl_early_data $tls1_3_early_data {
"~." $ssl_early_data;
default "";
}
My nginx.conf is the default one

Reverse proxy from "directory" to "server not working

I have a docker-compose file that creates 3 apache containers, and an NGINX container. The apache containers are all different applications that will have their own docker containers.
I want to use NGINX to reverse proxy from a directory off the root nginx container URL to the main parent of the 3 apache instances.
In the configuration below location / works. /parts and /wiki do not.
I have confirmed that all 3 apache containers do work by swapping out the proxy_pass on the / location, so I know the issue is with the nginx config. However I am a newb to nginx, and am not sure how to figure this out.
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream docker-apache-php {
server ths_apache_php:80;
}
upstream docker-apache-php-two {
server ths_apache_php_two:80;
}
upstream docker-apache-php-three {
server ths_apache_php_three:80;
}
server {
listen 8080;
location / {
proxy_pass http://docker-apache-php;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /parts {
proxy_pass http://docker-apache-php-two;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /wiki {
proxy_pass http://docker-apache-php-three;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
I solved the problem, apparently the URLs on the proxy_pass needed to end with a /. This is now working as I need it too.
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream docker-apache-php {
server ths_apache_php:80;
}
upstream docker-apache-php-two {
server ths_apache_php_two:80;
}
upstream docker-apache-php-three {
server ths_apache_php_three:80;
}
server {
listen 8080;
location / {
proxy_pass http://docker-apache-php/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /parts {
proxy_pass http://docker-apache-php-two/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /wiki {
proxy_pass http://docker-apache-php-three/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}

Nginx: Add context if one doesn't exist - in redirection

Requirement:
Redirect http://ruby.server.com to https://ruby.server.com/app1/ and don't append anything if the incoming URL has context (ex: http://ruby.server.com/app2/) in it
Setup
We have the following setup
Amazon Load Balancer
| http - |
| --> 80(ruby.server.com)
| https - |
nginx is running on ruby.server.com at port 80. There is no 443 in nginx.
server {
listen 80;
server_name ruby.server.com;
root /home/ubuntu/ruby/server/public/;
location / {
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
client_max_body_size 100M;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4009/;
root /home/ubuntu/ruby/server/public/;
}
if ($http_x_forwarded_proto != 'https') line is used for redirecting http://ruby.server.com to https://ruby.server.com
More context
We have 2 rails apps running inside the rails server, /public/app1, /public/app2. By default we want to redirect ruby.server.com to go to app1.
We can solve the above problem within the rails itself that involves an additional redirection. We are trying to see if we can get that context append within the nginx layer.
Solution based #timothy's note.
server {
listen 80;
server_name ruby.server.com;
root /home/ubuntu/staging/server/public/;
location / {
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host/app1/? permanent;
}
client_max_body_size 100M;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4009/;
root /home/ubuntu/staging/server/public/;
#auth_basic "Restricted";
#auth_basic_user_file /etc/nginx/.htpasswd;
}
location ^~ /[^\/]+/ {
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
client_max_body_size 100M;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4009/;
}
}
server {
listen 80;
server_name ruby.server.com;
root /home/ubuntu/ruby/server/public/;
location / {
# Default location for:
# http://ruby.server.com
# https://ruby.server.com
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
client_max_body_size 100M;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4009/;
}
location ^~ /[^\/]+/ {
# Location for:
# http://ruby.server.com/anything/
# https://ruby.server.com/anything/
# Do whatever you need here. :)
client_max_body_size 100M;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4009/;
}
}

Resources