I have two containers running on my DigitalOcean droplet. The first container is a REST api container running on port 9090. The second container is a ReactJS multistage container with Nginx running on port 4500. The docker-compose file is this:
version: '3'
services:
ubgrillmysql:
image: mysql:5.6
container_name: ubgrillmysql
environment:
- MYSQL_ROOT_PASSWORD=finder
- MYSQL_DATABASE=ubgrillData
- MYSQL_USER=ubgadmin
- MYSQL_PASSWORD=win(der90)Admin
volumes:
- /home/justicar/workspace/applications/data
networks:
- ubgrill_network
web:
image: ubgrill/web
container_name: web
depends_on:
- ubgrillmysql
environment:
- DATABASE_HOST=ubgrillmysql
- DATABASE_USER=ubgadmin
- DATABASE_PASSWORD=win(der90)Admin
- DATABASE_NAME=ubgrillData
- DATABASE_PORT=3306
ports:
- 9090:9090
networks:
- ubgrill_network
frontend:
image: ubgrill/frontend
container_name: frontend
build: ./src/main/ubgrill
depends_on:
- web
ports:
- 4500:80
networks:
- ubgrill_network
networks:
ubgrill_network:
external:
I have installed nginx on my droplet as I intend to transfer my blog there in the future. I created a server block using mu droplet's domain name and stored in /etc/nginx/sites-available with the name <domain>.com. The file is as follows:
upstream ubgrillapi{
server localhost:9090;
}
upstream ubgrillapp{
server localhost:4500;
}
server {
listen 80;
listen [::]:80;
root /var/www/<domain>.com/html;
index index.html index.htm;
server_name <domain>.com www.<domain>.com;
location / {
try_files $uri $uri/ =404;
}
location /ubgrill/api/ {
proxy_pass http://ubgrillapi;
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 /ubgrill/app/ {
proxy_pass http://ubgrillapp;
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;
}
}
When I try to access, http://<domain>.com/ubgrill/app, I get a 404(Not Found) error. The same goes for http://<domain>.com/ubgrill/api. I can access the app at http://<domain>.com:4500 and the api at http://<domain>.com:9090/ubgrill/api (The API actually starts with /ubgrill/api). I am a complete noob in nginx proxy and the tutorials online all deal with nginx in a separate container which is not my configuration. What is the problem with my configuration and can you please point me to a more comprehensive tutorial on nginx? Thanks.
In nginx conf :
proxy_pass http://ubgrillapp;
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Nginx proxy_pass shows the location
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
(http://example.com:9090/ubgrill/api)
In your case you i guess you should set this to:
proxy_pass localhost:9090/ubgrill/api
Related
I'm creating an application with docker-compose, vue.js, and phoenix/elixir. So far the phoenix application will work on localhost, but will not work when I run the application using docker-compose + NGINX and it's been difficult to debug. Any advice or suggestions would be helpful. The phoenix application itself does not have any of the configuration options changed from the "hello world" application and only adds in socket functionality for a chat room.
Here is the docker-compose file:
version: "3.9"
networks:
main_network:
volumes:
volume1:
varwwwcertbot:
certbotconf:
data_volume:
services:
phx:
build:
context: ./phx
restart: always
volumes:
- ./phx:/phx
ports:
- "4000:4000"
depends_on:
db:
condition: service_healthy
networks:
- main_network
db:
image: postgres
restart: always
volumes:
- ./docker-entrypoint-initdb.d/init.sql:/docker-entrypoint-initdb.d/init.sql
- data_volume:/var/lib/postgresql/data
environment:
- POSTGRES_NAME=dev-postgres
- POSTGRES_USER=pixel
- POSTGRES_DATABASE=lightchan
- POSTGRES_PASSWORD=exploration
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U pixel"]
interval: 5s
timeout: 5s
retries: 20
networks:
- main_network
frontend:
build:
context: ./frontend
restart: always
volumes:
- './frontend:/app'
- '/app/node_modules'
ports:
- "3000:3000"
networks:
- main_network
depends_on:
- "phx"
nginx:
build:
context: ./nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- volume1:/usr/share/nginx/html
- varwwwcertbot:/var/www/certbot
- certbotconf:/etc/letsencrypt
networks:
- main_network
certbot:
image: certbot/certbot:latest
volumes:
- varwwwcertbot:/var/www/certbot
- certbotconf:/etc/letsencrypt
networks:
- main_network
Here is the nginx file:
events{
}
http{
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
upstream websocket {
server 164.92.157.124:4000;
}
server {
listen 80;
server_name localhost lightchan.org www.lightchan.org;
root /usr/share/nginx/html;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
if ($scheme = http) {
return 301 https://lightchan.org$request_uri;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name localhost lightchan.org www.lightchan.org;
ssl_certificate /etc/letsencrypt/live/lightchan.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lightchan.org/privkey.pem;
location /media/pics/ {
autoindex on;
}
location / {
proxy_pass http://frontend:3000;
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_intercept_errors on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ^~ /socket/ {
proxy_pass http://websocket;
add_header X-uri "$uri";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
}
location ^~ /api/ {
proxy_pass http://phx:4000;
add_header X-uri "$uri";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
}
}
}
Note here that I attempted to proxy through an upstream for a /socket/ config and also attempted to use /api/ just using the phx docker tag. Both frontend and phx are linked in the docker-compose file, so they should be coming through. I've also turned on the 'upgrade' feature of Connection so this should be forwarding websockets too.
The phoenix application itself, still has the / front page uri, so I would suspect that being able to navigate to either www.lightchan.org/api or www.lightchan.org/socket would then allow me to see the phoenix hello world splash page, but instead there's a 502 error.
Any suggestions?
EDIT:
I've edited config/config.exs in the phoenix application to run on host 127.0.0.1 like this:
# Configures the endpoint
config :my_app, MyAppWeb.Endpoint,
url: [host: "127.0.0.1"],
render_errors: [view: MyAppWeb.ErrorView, accepts: ~w(html json), layout: false],
pubsub_server: MyApp.PubSub,
live_view: [signing_salt: "blah"]
and tested this running on locally, and it works, correctly showing the splash page at /. I've attempted to get this to work using http://<SERVER IP>:4000 on my server, but no luck.
EDIT EDIT:
Frustratingly, my autoindex for /media/pics is not working, but rather routing to the the frontend. Here is an embarrassingly thorough guide on routing priorities in NGINX (Guide on how to use regex in Nginx location block section?) and here (Nginx location priority). According to the second link:
location ^~ /images/ {
# matches any query beginning with /images/ and halts searching,
# so regular expressions will not be checked.
[ configuration D ]
}
should mean that
location ^~ /media/pics/ {
autoindex on;
}
location / {
<...>
should stop searching and the return an autoindex. So https://www.lightchan.org/media/pics/myimage.png should return myimage.png. That doesn't work and neither does
location /media/pics/ {
autoindex on;
}
Although I could have sworn it was working before...hmm.
Thanks to GreenMachine on Discord the answer was found here:
https://dev.to/eikooc/using-docker-for-your-elixir-phoenix-application-n8n
change dev.exs in config:
# from this:
http: [ip: {127, 0, 0, 1}, port: 4000],
# to this:
http: [ip: {0, 0, 0, 0}, port: 4000],
I am trying to set up subdomains to separate the back-end and front-end sides:
api.domain.com (back-end)
app.domain.com (front-end)
This is my docker-compose file:
version: "3.8"
services:
gateway:
container_name: ws-gateway
build:
context: gateway/nginx
dockerfile: Dockerfile
ports:
- "8082:8082"
depends_on:
- api
api:
container_name: ws-api
build:
context: api/nginx
dockerfile: Dockerfile
volumes:
- ./api:/app
This is my gateway Dockerfile:
FROM nginx:1.21.3-alpine
COPY ./conf.d/api.conf /etc/nginx/conf.d
WORKDIR /app
Configuration file "api.conf":
server {
listen 8082;
listen [::]:8082;
server_name api.mydomainname.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://api;
proxy_ssl_session_reuse off;
proxy_redirect off;
}
}
I specified to listen on port 8082, specified the server name, but that doesn't work.
When I try to go to the api.mydomainname.com the server gives an error "This site can’t be reached". But if I specify the port mydomainname.com:8082, then it works:
I'm building an e2e test suite inside a docker container for CI.
It has 3 services (admin, platform, dashboard) which all connect to a postgres instance.
I use nginx as a reverse proxy to direct the traffic to the correct service based on the subdomain.
Dashboard (dashboard.localtest.me) and Admin (admin.localtest.me) each have their own subdomain and everything else goes to Platform (ex. accounts.localtest.me, public.localtest.me) and there are hundreds of subdomains. The services are on their own ports as well as part of how the product is designed.
Currently I can bring all this up in docker-compose, make requests to <foo>.localtest.me:8080 from my browser and nginx will direct all the traffic to the correct endpoints. Works great.
But when the Cypress service tests start making requests (from inside the docker host) they don't resolve. My assumption is that since the hostname isn't resolving then the request isn't going to the nginx service, which means it can't get routed to the correct product service (admin, platform, or dashboard)
If I can route everything to nginx with a dns wildcard (*.localest.me) I think that would work but I can't figure out what modules or tools can allow for that. Everything I've found is for handing a reverse proxy connecting to the docker host, not containers making url requests internally.
TL;DR
How can I allow cypress container to make wildcard GET requests (*.localtest.me) to my nginx reverse_proxy container
This is roughly what my docker compose looks like, I've removed any of the internal env vars that aren't relevant
services:
postgres:
build:
context: ./
dockerfile: postgres.dockerfile
ports:
- 5432:5432
dashboard:
build:
context: ./
dockerfile: web.dockerfile
ports:
- 9001:9000
platform:
build:
context: ./
dockerfile: web.dockerfile
ports:
- 8001:8000
admin:
build:
context: ./
dockerfile: web.dockerfile
ports:
- 7001:7000
nginx:
restart: always
image: nginx
build:
context: ./
dockerfile: nginx.dockerfile
ports:
- 8080:80
- 443:443
- 8000:8000
- 9000:9000
- 7000:7000
cypress:
image: cypress-testing
build:
context: ./
dockerfile: cypress-tests.dockerfile
ports:
- 6000:6000
Here is my nginx.conf
server {
listen 80;
listen 9000;
server_name dashboard.localtest.me;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_pass http://dashboard:9000/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_buffering off;
chunked_transfer_encoding off;
}
}
server {
listen 80;
listen 7000;
server_name admin.localtest.me;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header Connection "";
proxy_pass http://admin:7000/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_buffering off;
chunked_transfer_encoding off;
}
}
server {
listen 80;
listen 8000;
server_name ~(^|\.)localtest\.me$;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_pass http://platform:8000/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_buffering off;
chunked_transfer_encoding off;
}
}
I am trying to do reverse proxy in my Docker container. I am trying to use PgAdmin4 in port 8080, not 80. For security reasons, I am not using Docker port forwarding. I am trying to use Nginx to reverse proxy pgAdmin's port 80 to 8080. my Nginx code :
server {
listen 8080;
location / {
proxy_pass http://pgadmin_test:80/;
proxy_redirect off;
proxy_set_header Host $host
}
}
This code is not working.
But if I use port 80 in Nginx, it works properly
server {
listen 80;
location / {
proxy_pass http://pgadmin_test:80/;
proxy_redirect off;
proxy_set_header Host $host
}
}
The git hub link is: https://github.com/subhadipsjsc/docker_nginx_pgadmin
nginx_test:
build: ./nginx
container_name: nginx_test
restart: always
ports:
- "3000:3000"
pgadmin_test:
image: dpage/pgadmin4
restart: always
depends_on:
- postgres_test
ports:
- 80:80
server {
listen 3000;
location / {
proxy_pass http://pgadmin_test:80/;
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;
}
}
Here is the official documentation: https://www.pgadmin.org/docs/pgadmin4/latest/container_deployment.html#http-via-nginx
For me this was helpful because I wanted pgadmin mounted in a subroute /pgadmin
Sometimes nginx server forwards request to wrong docker-compose service.
I have docker-compose config
version: "3.0"
services:
proj-reader:
image: repositry:5000/my-company.com/proj-reader
ports:
- "28090:8080"
- "28095:5005"
proj-helpdesk:
image: repository:5000/my-company.com/proj-helpdesk
ports:
- "29080:8080"
- "29085:5005"
proj-frontend:
image: repository:5000/my-company.com/proj-frontend
ports:
- "80:80"
links:
- "proj-helpdesk:backend"
- "proj-reader:reader"
...
Frontend is a nginx container with NodeJs application. And we have next nginx configuration:
upstream backend {
server backend:8080;
keepalive 30;
}
upstream reader {
server reader:8080;
keepalive 30;
}
server {
listen 80;
client_max_body_size 2m;
server_name localhost;
root /usr/share/nginx/html;
location /api/ {
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_pass http://backend;
proxy_read_timeout 600;
}
location /web-callback/ {
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_pass http://reader;
}
}
And sometimes I can see that request for /web-callback/ is recieved in other service which doesn't pointed in links section for frontend service. At first time I have thougt it happened after I have restarted reader service. But yerstaday this situation repeated and I know that reader haven't been restarted.
What cn it be? ANd how can I prevent this situation in future?
You should try to use:
location ^~ /api/ {
# Queries beginning with /api/ and then stops searching.
}
location ^~ /web-callback/ {
# Queries beginning with /web-callback/ and then stops searching.
}
https://www.keycdn.com/support/nginx-location-directive/