NGINX container as a proxy for other docker containers - docker

I have bind9 DNS server running as a container, and is mapped to port 53003 on the docker host:
version: "3"
services:
DNS-SRV:
container_name: DNS-SRV
image: ubuntu/bind9
ports:
- "53003:53"
environment:
- TZ=UTC
volumes:
- ~/core/bind9/:/etc/bind/
and I wonder if I can use NGINX server as a proxy for it and other containerized services, here is my nginx.config file:
events {
worker_connections 1024;
}
stream {
upstream dns_servers {
server <docker_hostIP>:53003;
}
server {
listen 53 udp;
listen 53; #tcp
proxy_pass dns_servers;
error_log /var/log/nginx/dns.log info;
proxy_responses 1;
proxy_timeout 1s;
}
}
What I'm trying to do is to map any dns requests for the docker host on port 53 to port 53003, I'm not sure if there is another way:
Client -- DNS request ---> 53 (( [ NGINX ] --> 53003:53 ))
My setup isn't working, I'm testing it by doing nslookup like this:
# nslookup <domain> <docker_hostIP>
but I'm getting connection timed out, what could be the issue?

You could do this?
Create a docker-compose incorporating both services
version: "3"
services:
DNS-SRV:
container_name: DNS-SRV
image: ubuntu/bind9
environment:
- TZ=UTC
volumes:
- ~/core/bind9/:/etc/bind/
NGINX:
image: nginx:alpine
ports:
- "53:53/udp"
- "53:53/tcp"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- "DNS-SRV"
Then in your nginx.conf do something like this?
events {
worker_connections 1024;
}
stream {
upstream dns_servers {
server DNS-SRV:53;
}
server {
listen 53 udp;
listen 53; #tcp
proxy_pass dns_servers;
error_log /var/log/nginx/dns.log info;
proxy_responses 1;
proxy_timeout 1s;
}
}

Related

Configure NGINX, Docker Compose, AWS EC2

I have an EC2 AWS instance and I want to create a test environment for an application.
All other containers are working properly, but NGINX's is the only one that is not stable and keeps restarting constantly.
I tried in several ways to make NGINX run. Change addresses I used Return 301. Tried to remove certbot, nothing worked.
I'm an intern and I need to create this test environment for an assessment. Can someone help me?
my docker-compose.yml is like this
version: "3.9"
services:
backend:
container_name: backend
image: <my_image>
restart: always
ports:
- "3030:3030"
environment:
- "DATABASE_URL=${DATABASE_URL}"
- "SERVER_PORT=${SERVER_PORT}"
- "JWT_SECRET=${JWT_SECRET}"
sniffer:
container_name: mqtt-sniffer
image: <my_image>
restart: always
environment:
- "POSTGRES_DB=${POSTGRES_DB}"
- "POSTGRES_USER=${POSTGRES_USER}"
- "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}"
- "POSTGRES_HOST=${POSTGRES_HOST}"
- "MQTT_CLIENT_ID=${MQTT_CLIENT_ID}"
- "MQTT_USER=${MQTT_USER}"
- "MQTT_PASSWORD=${MQTT_PASSWORD}"
- "MQTT_HOST=${MQTT_HOST}"
- "MQTT_PORT=${MQTT_PORT}"
web:
container_name: web
image: <my_image>
restart: always
nginx:
container_name: nginx
image: nginx:latest
restart: always
ports:
- "80:80"
- "443:443"
environment:
- API_SERVER_NAME=${API_SERVER_NAME}
volumes:
- /home/ubuntu/app/nginx/default.conf:/etc/nginx/nginx.conf:ro
- /home/ubuntu/app/certbot/www:/etc/nginx/acme_challenge:ro
- /home/ubuntu/app/certbot/certificate:/etc/nginx/certificate:ro
and my default.conf is like this
events {}
http {
server {
listen 80;
listen [::]:80;
server_name 18.231.90.250;
location /.well-known/acme-challenge/ {
root /etc/nginx/acme_challenge;
}
location / {
proxy_pass http://18.231.90.250;
}
}
server {
listen 80;
listen [::]:80;
location /.well-known/acme-challenge/ {
root /etc/nginx/acme_challenge;
}
location / {
proxy_pass http://web:80;
}
}
server {
listen 443 default_server ssl;
listen [::]:443 ssl;
ssl_certificate /etc/nginx/certificate/live/teste.clientautoponia.com/fullchain.pem;
ssl_certificate_key /etc/nginx/certificate/live/teste.clientautoponia.com/privkey.pem;
location / {
proxy_pass http://backend:3030;
}
}
I don't need to have the ssl certificate, I just want to be able to communicate when accessing the instance. Get a 200 when trying to access the address.

Change nginx server name in Docker

I have a project running on docker. I use Nginx reverse proxy to run my app.
All works fine but trying to personalize the server_name on nginx but couldn't figure out how.
Docker yml file
I've added server name to /etc/hosts by docker
version: "3"
services:
nginx:
container_name: nginx
volumes:
- ./nginx/logs/nginx:/var/log/nginx
build:
context: ./nginx
dockerfile: ./Dockerfile
depends_on:
- menu-app
ports:
- "80:80"
- "433:433"
extra_hosts:
- "www.qr-menu.loc:172.18.0.100"
- "www.qr-menu.loc:127.0.0.1"
networks:
default:
ipv4_address: 172.18.0.100
menu-app:
image: menu-app
container_name: menu-app
volumes:
- './menu-app/config:/var/www/config'
- './menu-app/core:/var/www/core'
- './menu-app/ecosystem.json:/var/www/ecosystem.json'
- './menu-app/tsconfig.json:/var/www/tsconfig.json'
- './menu-app/tsconfig-build.json:/var/www/tsconfig-build.json'
- "./menu-app/src:/var/www/src"
- "./menu-app/package.json:/var/www/package.json"
build:
context: .
dockerfile: menu-app/.docker/Dockerfile
tmpfs:
- /var/www/dist
ports:
- "3000:3000"
extra_hosts:
- "www.qr-menu.loc:127.0.0.1"
- "www.qr-menu.loc:172.18.0.100"
networks:
default:
ipam:
driver: default
config:
- subnet: 172.18.0.0/24
And I have Nginx conf
server_names_hash_bucket_size 1024;
upstream local_pwa {
server menu-app:3000;
keepalive 8;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name www.qr-menu.loc 172.18.0.100;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://local_pwa/;
}
}
but unfortunately, app runs on localhost instead of www.qr-menu.loc
I couldn't figure out how to change server_name on Nginx.
This is a really, really late answer. The server_name directive tells nginx which configuration block to use on receipt of a request. Also see: http://nginx.org/en/docs/http/server_names.html
I think the docker-compose extra_hosts directive might only work for domain-name resolution within the docker network. In other words, on your computer that's running docker the name "www.qr-menu.loc" is not available, but in a running docker container that name should be available.

Docker swarm can't reach worker nodes

So, i have set up a docker swarm and connected a worker on it and deployed a stack with 4 services:
generator, which will be located at the worker node
API & scheduler, both will be located on the manager node
proxy, that will be located on the manager node, accepting requests and redirecting it though the other 3
This is my stack file:
version: "3.7"
services:
generator:
image: musicorum/generator:latest
restart: always
environment:
- 'XXXX=XXXX'
deploy:
resources:
reservations:
memory: 860M
placement:
constraints:
- "node.labels.generator==yes"
ports:
- 5000:5000
networks:
- proxy_ext
- netg
volumes:
- type: bind
source: /home/musicorum/cache
target: /usr/src/app/cache
api:
image: musicorum/api:latest
restart: always
environment:
- 'XXXX=XXXX'
networks:
- proxy_ext
ports:
- 4500:4500
deploy:
placement:
constraints:
- "node.labels.generator!=yes"
scheduler:
image: musicorum/scheduler:latest
restart: always
environment:
- 'XXXX=XXXX'
ports:
- 6500:6500
networks:
- proxy_ext
deploy:
placement:
constraints:
- "node.labels.generator!=yes"
proxy:
image: nginx:latest
restart: always
networks:
- proxy_ext
- netg
ports:
- 80:80
- 443:443
configs:
- source: nginx_4
target: /etc/nginx/conf.d/default.conf
- source: sslcrt
target: /etc/ssl/musicorumapp/ssl.crt
- source: sslkey
target: /etc/ssl/musicorumapp/ssl.key
depends_on:
- scheduler
- api
- generator
deploy:
placement:
constraints:
- "node.labels.generator!=yes"
configs:
nginx_4:
external: true
sslcrt:
external: true
sslkey:
external: true
networks:
proxy_ext:
external: true
netg:
driver: overlay
attachable: true
As you can see, the they are connected on the same network, i even created proxy_ext and netg to double-check the connection, but Nginx give this message when start up:
/docker-entrypoint.sh: Configuration complete; ready for start up
2020/07/07 13:32:17 [emerg] 1#1: host not found in upstream "musicorum_generator" in /etc/nginx/conf.d/default.conf:30
nginx: [emerg] host not found in upstream "musicorum_generator" in /etc/nginx/conf.d/default.conf:30
I don't know why the Nginx, at the manager node, can't reach out to the generator container, at the worker node. If it helps, here's my default.conf:
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/musicorumapp/ssl.crt;
ssl_certificate_key /etc/ssl/musicorumapp/ssl.key;
server_name api.musicorumapp.com;
location / {
proxy_pass http://musicorum_api:4500/;
}
}
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/musicorumapp/ssl.crt;
ssl_certificate_key /etc/ssl/musicorumapp/ssl.key;
server_name scheduler.musicorumapp.com;
location / {
proxy_pass http://musicorum_scheduler:6500/;
}
}
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/musicorumapp/ssl.crt;
ssl_certificate_key /etc/ssl/musicorumapp/ssl.key;
server_name generator.musicorumapp.com;
location / {
proxy_pass http://musicorum_generator:5000/;
}
}
In your default.conf you need to reference the services by their service name. This is the name that the internal DNS will resolve.
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/musicorumapp/ssl.crt;
ssl_certificate_key /etc/ssl/musicorumapp/ssl.key;
server_name api.musicorumapp.com;
location / {
proxy_pass http://api:4500/; <------ 'api' is the service name
}
}
You only would need to prefix the name of your stack if the reverse proxy server was running external to your stack's network, but since they are all on the same network, the DNS will resolve the service name alone.
You may also remove the ports: 8000:8000 on all of your apps (except reverse proxy) in your stack yaml file because you want to route traffic through your reverse proxy, not bind the port to the host. This could lead to security vulnerabilities as well. There are no port restrictions within a docker network. If an application is listening on 8000, your reverse proxy can contact it with http://service-name:8000 within the stack's overlay network.

Nginx Proxy Upstream Server Docker Compose - 502 Bad Gateway Connection Refused

I am trying to containerize all things related to my web app using Docker Compose, including Nginx & SSL Certificates. To do this I am using the Nginx Proxy image from JWilder and the LetsEncrypt Companion, but am having trouble getting the nginx proxy to work, result ends up being:
Nginx 502 Bad Gateway
[error] 31160#0: *35 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xx, server: domain.com, request: "GET /dev/ HTTP/1.1", upstream: "webapp://127.0.0.1:8080", host: "domain.com"
This only happened when trying to set up the Nginx proxy and SSL certificates so I know it's a configuration issue for either or both of these containers. If anyone can spot where I am going wrong, I would be extremely grateful!
Here are the containers in question:
version: '3.1'
networks:
mywebapp:
services:
nginx-proxy:
container_name: nginx-proxy
build: ./env/nginx-proxy
networks:
- mywebapp
ports:
- 80:80
- 443:443
env_file:
- ./env/nginx-proxy/.env
depends_on:
- webapp
tty: true
volumes:
- ./src:/home/www/mywebapp/src
- ./storage:/home/www/storage/mywebapp
- ./data/nginx-proxy/logs:/var/log/nginx
- ./env/nginx-proxy/webserver/nginx.conf:/etc/nginx/nginx.conf
- ./env/nginx-proxy/webserver/conf.d:/etc/nginx/conf.d
- ./env/nginx-proxy/webserver/vhost.d:/etc/nginx/vhost.d
- ./env/nginx-proxy/webserver/defaults:/etc/nginx/defaults
- ./env/nginx-proxy/webserver/global:/etc/nginx/global
- ./env/nginx-proxy/ssl/certs:/etc/nginx/certs
- ./env/nginx-proxy/share:/usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
labels:
com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
letsencrypt:
restart: always
container_name: letsencrypt
image: jrcs/letsencrypt-nginx-proxy-companion
env_file:
- ./env/letsencrypt/.env
volumes:
- ./data/letsencrypt/logs:/var/log
- ./env/nginx-proxy/webserver/nginx.conf:/etc/nginx/nginx.conf
- ./env/nginx-proxy/webserver/conf.d:/etc/nginx/conf.d
- ./env/nginx-proxy/webserver/vhost.d:/etc/nginx/vhost.d
- ./env/nginx-proxy/webserver/defaults:/etc/nginx/defaults
- ./env/nginx-proxy/webserver/global:/etc/nginx/global
- ./env/nginx-proxy/ssl/certs:/etc/nginx/certs
- ./env/nginx-proxy/share:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
depends_on:
- nginx-proxy
webapp:
container_name: webapp
build: ./env/webapp
hostname: webapp
networks:
- mywebapp
ports:
- 9000:9000
- 8080:8080
volumes:
- ./env/composer:/home/www/.composer
- ./env/global/bashrc:/home/www/.bashrc
- ./data/bash/.bash_history:/home/www/.bash_history
- ~/.ssh:/home/www/.ssh:ro
- ~/.gitconfig:/home/www/.gitconfig:ro
- ./storage:/home/www/storage/mywebapp
- ./src:/home/www/mywebapp/src
Key points being:
Webapp is the source of my web application which is running PHP, MySQL and Nginx webserver. The webapp webserver exposes and listens on port 8080 to serve the PHP files.
Nginx proxy exposes standard ports 443 and 80 and proxy passes to webapp on port 8080
LetsEncrypt Companion generates the certs and renews.
Nginx Proxy server configuration:
upstream webapp {
server 127.0.0.1:8080;
}
server {
listen 80;
listen [::]:80;
server_name webapp.localhost;
location / {
proxy_pass http://webapp;
}
}
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate certs/default.crt;
ssl_certificate_key certs/default.key;
include /etc/nginx/global/ssl-params.conf;
server_name webapp.localhost;
location / {
proxy_pass http://webapp;
}
}
Webapp webserver configuration:
server {
listen 8080;
listen [::]:8080;
server_name webapp.localhost;
root /home/www/webapp/src;
index index.php;
include /etc/nginx/defaults/php.conf;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
}
When visiting http://webapp.localhost:8080 I can see the webapp webserver serves the page no trouble, so I suspect it's something wrong with my Nginx Proxy server configuration.
Thanks for reading.
Since nginx and webapp are on two separate containers, nginx can't reach webapp on localhost(127.0.0.1) as you've configured for upstream:
upstream webapp {
server 127.0.0.1:8080;
}
Change it to webapp:8080.

nginx reverse-proxy docker applications

I am trying to set up nginx as proxy with the following functionality:
If www.mydomain.com is called, hand out static content.
If www.mydomain.com/wekan is called, redirect to my Wekan-Dokan container.
For keeping it simple, everything is on localhost and no network required.
This is my nginx configuration:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
server{
location / {
proxy_pass http://localhost:9050;
}
location /wekan {
proxy_pass http://localhost:3001;
}
location /pics {
proxy_pass http://localhost/example.jpg;
}
location ~ \.(gif|jpg|png)$ {
root /home/myUser/serverTest/data/images;
}
}
server{
listen 9050;
root /home/myUser/serverTest/data/up1;
location / {
}
}
}
And here is my docker-compose for the Wekan App:
version: '2'
services:
wekandb:
image: mongo:3.2.21
container_name: wekan-db
restart: always
command: mongod --smallfiles --oplogSize 128
networks:
- wekan-tier
expose:
- 27017
volumes:
- /home/myUser/wekan/wekan-db:/data/db
- /home/myUser/wekan/wekan-db-dump:/dump
wekan:
image: quay.io/wekan/wekan
container_name: wekan-app
restart: always
networks:
- wekan-tier
ports:
# Docker outsideport:insideport
- 3001:8080
environment:
- MONGO_URL=mongodb://wekandb:27017/wekan
- ROOT_URL=http://localhost
So as my basic understanding of nginx,
calling localhost:3001 and calling localhost/wekan should be the same, since localhost/wekan gets redirected to localhost:3001.
This is not the case (it gets redirected to a wekan "page not found" version)

Resources