Nginx-proxy doesn't forward to container exposing port 3001 and rewrites URL to static IP - ruby-on-rails

I got a web application running on Ruby on Rails with SOLR in docker-compose. It exposes port 3001, and I want a subdomain URL than my university possesses (and I have access to the configuration panel where I can only specify the "target", what is the IP, I guess, of my local server on which the web application is running).
I first tried to do this redirection without nginx, but the URL data.chembiosys.de was just redirected to http://static.ip:3001
The app is running though, and is accessible.
So I wanted to try to use nginx as a reverse proxy, but the effect is basically the same:
- I need to specify the port number and the IP of my server in the configuration panel of the domain name of interest
- when I type "data.chembiosys.de" in the browser, it shows the IP and the port number
What I do is that I first create a nginx-proxy network:
sudo docker network create nginx-proxy
Then I start nginx-proxy with docker-compose.yml:
version: "3"
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- /home/myhome/Projects/nginx-proxy/conf/my_conf.conf:/etc/nginx/conf.d/my_proxy.conf:ro
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.local
networks:
default:
external:
name: nginx-proxy
In the second volume, I copy to the nginx-proxy container the following config file:
server {
listen 80;
server_name http://mystaticip:3001;
client_max_body_size 2G;
return 301 http://data.chembiosys.de$request_uri;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host data.chembiosys.de;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://mystaticip:3001;
}
}
And finally, I run the rails app docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
container_name: seek-mysql_cbs
restart: always
env_file:
- docker/db.env
volumes:
- seek-mysql-db_cbs:/var/lib/mysql
seek: # The SEEK application
#build: .
image: fairdom/seek:1.7
container_name: seek_cbs
command: docker/entrypoint.sh
restart: always
environment:
RAILS_ENV: production
SOLR_PORT: 8983
NO_ENTRYPOINT_WORKERS: 1
env_file:
- docker/db.env
volumes:
- seek-filestore_cbs:/seek/filestore
- seek-cache_cbs:/seek/tmp/cache
ports:
- "3001:3000"
depends_on:
- db
- solr
links:
- db
- solr
seek_workers: # The SEEK delayed job workers
#build: .
image: fairdom/seek:1.7
container_name: seek-workers_cbs
command: docker/start_workers.sh
restart: always
environment:
RAILS_ENV: production
SOLR_PORT: 8983
env_file:
- docker/db.env
volumes:
- seek-filestore_cbs:/seek/filestore
- seek-cache_cbs:/seek/tmp/cache
depends_on:
- db
- solr
links:
- db
- solr
solr:
image: fairdom/seek-solr
container_name: seek-solr_cbs
volumes:
- seek-solr-data_cbs:/opt/solr/server/solr/seek/data
restart: always
volumes:
seek-filestore_cbs:
driver: local-persist
driver_opts:
mountpoint: /home/myhome/Projects/ChemBioSys/docker_volumes/seek-filestore_cbs
seek-mysql-db_cbs:
driver: local-persist
driver_opts:
mountpoint: /home/myhome/Projects/ChemBioSys/docker_volumes/seek-mysql-db_cbs
seek-solr-data_cbs:
driver: local-persist
driver_opts:
mountpoint: /home/myhome/Projects/ChemBioSys/docker_volumes/seek-solr-data_cbs
seek-cache_cbs:
driver: local-persist
driver_opts:
mountpoint: /home/myhome/Projects/ChemBioSys/docker_volumes/seek-cache_cbs
networks:
default:
external:
name: nginx-proxy
I have the feeling that nginx-proxy is just failing to connect the URL to the app. What an I doing wrong and how to connect the app to the URL with nginx? And also, how to avoid the rewrite of the URL to the IP:port?
P.S. The static IP I got from the SysAdmins is alphanumerical and I see the following warning when the nginx-proxy docker-compose runs:
nginx-proxy | [warn] 30#30: server name "http://pc08.ian.uni-jena.de:3001" has suspicious symbols in /etc/nginx/conf.d/my_proxy.conf:3

Related

Nginx get error when using in a docker-compose file

I use a docker-compose file with 3 service (node-red, mosquitto and mongo) and and I want use nginx as load balancer of node-red service:
version: '2.2'
networks:
Platform-Network:
name: IoT-Network
volumes:
Platform:
MQTT-broker:
DataBase:
Nginx:
services:
Platform:
image: custom-node-red:latest
networks:
- Platform-Network
restart: always
volumes:
- ./node-red:/data
# depends_on:
# - Nginx
MQTT-broker:
container_name: mosquitto
image: eclipse-mosquitto
ports:
- "192.168.100.101:1883:1883"
networks:
- Platform-Network
restart: always
depends_on:
- Platform
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
DataBase:
container_name: mongodb
image: mongo
ports:
- "8083:27017"
networks:
- Platform-Network
restart: always
depends_on:
- Platform
volumes:
- ./mongodb/data:/data/db
- ./mongodb/backup:/data/backup
- ./mongodb/mongod.conf:/etc/mongod.conf
- ./mongodb/log:/var/log/mongodb/
Nginx:
container_name: nginx
image: nginx
ports:
- "4000:4000"
depends_on:
- Platform
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
restart: always
Nginx config file is:
user nginx;
events {
worker_connections 1000;
}
http {
upstream platform {
server platform_1:1880;
server platform_2:1880;
server platform_3:1880;
}
server {
listen [::]:4000;
listen 4000;
location / {
proxy_pass http://platform;
}
}
}
I run my service with docker-compose -f platform.yaml up -d --scale Platform=3 and containers up as show in
this
.But as showen in above image, nginx dosnt up.
Nginx container log get this error and i can't resolve it.
Your nginx service also need to join the same network as Platform:
Nginx:
container_name: nginx
image: nginx
ports:
- "4000:4000"
depends_on:
- Platform
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
restart: always
networks: # add this
- Platform-Network

Traefik proxy ip auth

I have a traefik in docker-compose:
version: '3'
networks:
proxy:
driver: bridge
services:
traefik:
container_name: traefik
image: traefik:v1.7.9
command: --api --docker
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/etc/traefik/traefik.toml
- ./acme.json:/acme.json
networks:
- proxy
Also have nginx under mydomain.com, and I want to allow only my ip to connect to it:
nginx:
build: ./nginx
networks:
- backend
- traefik_proxy
restart: always
labels:
traefik.enable: "true"
traefik.port: "80"
traefik.frontend.headers.allowedHosts: "1.2.3.4" # MyIp
traefik.frontend.rule: "Host:mysite.com,www.mysite.com"
When I access mysite.com I got Bad Host error, and the IP in headers is my server's ip instead of my real ip.
P.S Docker in swarm mode, but nginx and traefik build using local docker-compose
The solution is to add following directives to nginx docker-compose:
traefik.frontend.whiteList.sourceRange: "1.2.3.4" # my Ip
traefik.frontend.passHostHeader: true
traefik.frontend.whiteList.useXForwardedFor: "true"

Error 502 accessing nextcloud via docker with nginx

Heyo!
Update: I figured it out and added my answer.
I'm currently in the process of learning docker and I've written a docker-compose file that should launch nginx, gitea, nextcloud and route them all via domain name as a reverse proxy.
All is going well except for with nextcloud. I can access it via localhost:3001 but not via the nginx reverse proxy. All is well with gitea, it works both ways.
The error I'm getting is:
nginx_proxy | 2018/08/10 00:17:34 [error] 8#8: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: cloud.example.ca, request: "GET / HTTP/1.1", upstream: "http://172.19.0.4:3001/", host: "cloud.example.ca"
docker-compose.yml:
version: '3.1'
services:
nginx:
container_name: nginx_proxy
image: nginx:latest
restart: always
volumes:
// Here I'm swapping out my default.conf for the container's by mounting my
directory over theirs.
- ./nginx-conf:/etc/nginx/conf.d
ports:
- 80:80
- 443:443
networks:
- proxy
nextcloud_db:
container_name: nextcloud_db
image: mariadb:latest
restart: always
volumes:
- nextcloud_db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/cloud_db_root
MYSQL_PASSWORD_FILE: /run/secrets/cloud_db_pass
MYSQL_DATABASE: devcloud
MYSQL_USER: devcloud
secrets:
- cloud_db_root
- cloud_db_pass
networks:
- database
gitea_db:
container_name: gitea_db
image: mariadb:latest
restart: always
volumes:
- gitea_db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/cloud_db_root
MYSQL_PASSWORD_FILE: /run/secrets/cloud_db_pass
MYSQL_DATABASE: gitea
MYSQL_USER: gitea
secrets:
- cloud_db_root
- cloud_db_pass
networks:
- database
nextcloud:
image: nextcloud
container_name: nextcloud
ports:
- 3001:80
volumes:
- nextcloud:/var/www/html
restart: always
networks:
- proxy
- database
gitea:
container_name: gitea
image: gitea/gitea:latest
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
volumes:
- gitea:/data
ports:
- 3000:3000
- 22:22
networks:
- proxy
- database
volumes:
nextcloud:
nextcloud_db:
gitea:
gitea_db:
networks:
proxy:
database:
secrets:
cloud_db_pass:
file: cloud_db_pass.txt
cloud_db_root:
file: cloud_db_root.txt
My default.conf that gets mounted into /etc/nginx/conf.d/default.conf
upstream nextcloud {
server nextcloud:3001;
}
upstream gitea {
server gitea:3000;
}
server {
listen 80;
listen [::]:80;
server_name cloud.example.ca;
location / {
proxy_pass http://nextcloud;
}
}
server {
listen 80;
listen [::]:80;
server_name git.example.ca;
location / {
proxy_pass http://gitea;
}
}
I of course have my hosts file setup to route the domains to localhost. I've done a bit of googling but nothing I've found so far seems to align with what I'm running into. Thanks in advance!
Long story short, one does not simply reverse proxy to port 80 with nextcloud. It's just not allowed. I have it deployed and working great with a certificate over 443! :)

How can I configure Traefik with letsencrypt and multiple services

I am trying to understand Traefik but I am not sure I understan how it works due to my lack of knowledge. I am tying to create following scenario
Frontend --> Static. www.example.com example.com with LE
Backend --> api.example.com LE
Redis --> Local network only
Mongodb --> Local network only.
I read the documentation and I came up with following docker-compose.yml file but I don't know it is correct or not. I am not sure about how nginx will map to port 80 and how traefik will create LE certificates.
version: '3'
services:
redis:
restart: always
image: redis:alpine
networks:
- internal
mongo:
restart: always
image: mongodb
networks:
- internal
frontend:
image: nginx:1-alpine
command: [nginx-debug, '-g', 'daemon off; error_log /dev/stdout info;']
volumes:
- "./static_assets:/usr/share/nginx/html:ro"
- "./nginx_config/default.conf:/etc/nginx/conf.d/default.conf"
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=PathPrefixStrip: /assets"
- "traefik.port=80"
- "traefik.frontend.rule=Host:example.com,www.example.com"
api:
image: MYAPIIMAGE
ports:
- "3000:3000"
networks:
- web
- internal
labels:
- "traefik.backend=api"
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.port=3000"
- "traefik.frontend.rule=Host:api.example.com"
traefik:
image: traefik:1.4.5
restart: always
ports:
- 80:80
- 443:443
networks:
- web
volumes:
- "./acme.toml:/etc/traefik/conf/acme.toml:ro"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./acme.json:/etc/traefik/conf/acme.json:rw"
container_name: traefik
networks:
web:
external:
name: web
internal:
external:
name: internal
Traefik will take a request and map it to a container's port based on your frontend rules. Unless otherwise specified in your Traefik config, traefik will always map its port 80 to you whatever port you specify in traefik.port. These are configured in the entrypoints.http configuration for Traefik.
Any time you specify a host, Traefik will attempt to get a Let's Encrypt cert for it as long as in the traefik config you have acme.OnHostRule set to true.

Docker bind host to container

I have two containers nginx and php how to configure docker-compose so when I make wget http://example.com from inside php container this host should point to nginx container
Map your nginx port to host port.
If you host has name example.com and nginx runs on 8080 port, set up your docker-compose like
nginx:
image: nginx
hostname: nginx
ports:
- "8080:80"
In this case request to http://example.com will be really executed as http://nginx:8080.
I've specified static ips for my containers in docker-compose.yml and added extra_host:
services:
nginx:
image: nginx
ports:
- "8200:80"
- "8201:443"
volumes:
- .:/var/www/html
networks:
test:
ipv4_address: 10.5.0.5
php:
build: ./docker/php
volumes:
- .:/var/www/html
environment:
APP_ENV: "dev"
networks:
test:
ipv4_address: 10.5.0.6
extra_hosts:
- "example.com:10.5.0.5"
networks:
test:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16

Resources