Alfredo Uzcategui
Alfredo Uzcategui

Reputation: 1

Docker Reverse Proxy, Nginx, MEAN Stack

Hi Everyone I get 400 code response. I am trying to deploy a MEAN stack app on docker, so I'm using reverse proxy to backend and frontend comunication without ports

My https:// site.app/api works but my frontend get

400 bad request the plain http request was sent to https

this is new for me so I watched some tutorials and posts to solve it, but I haven't got any solution If I just put the ssl on frontend it's works but my backend get erros with ssl error connections when I trying send data or something similar

I have sent data with the url https:// site.app/api through postman so, I can say it's works

DOCKERFILE

FROM node:14.3.0  As builder
RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app/

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build --prod

FROM nginx:1.19

COPY --from=builder /usr/src/app/dist/advanced-angular/ /usr/share/nginx/html

RUN rm -rf /etc/nginx/conf.d/default.conf

EXPOSE 80
EXPOSE 443

CMD ["nginx", "-g", "daemon off;"]

This is my docker-compose file

Docker Compose

version: "3.6" # Version del docker-compose
services: # Definir la lista de servicios que se crearan

  frontend: # nombre del primer servicio
    image: myImage
    restart: always
    container_name: frontend
    # command: ["npm", "start"]
    ports:
      - "80:80" # Especificar el puerto que sera Mapeado
      - "443:443"
    volumes: #el volume donde estara el projecto para que pueda ser editatado
      - ./ssl/:/etc/nginx/ssl/
      - ./nginx-conf/:/etc/nginx/conf.d/
    networks:
      - webNet
    depends_on: 
      - backend
      - mongo

  backend:
    image: myImage
    restart: always
    container_name: backend
    env_file: .env
    environment:
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=mongo
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB
    # command: ["npm", "run", "dev"]
    ports:
      - "3000:3000"
    # volumes: 
      # - ./api-server:/usr/src/app
    networks:
      - webNet
    depends_on:
      - mongo

  mongo:
    image: mongo:4.2.7-bionic 
    restart: always
    container_name: mongo
    env_file: .env
    environment:
      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
    ports:
      - "27017:27017"
    networks:
      - webNet
    volumes: 
      - /opt/mongo/prod:/data/db

networks:
  webNet:
    driver: bridge

My nginx configuration nginx.conf

upstream frontend {
    least_conn;
    server frontend:443 max_fails=3 fail_timeout=30s;
}
upstream backend {
    least_conn;
    server backend:3000 max_fails=3 fail_timeout=30s;
}

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    server_name vecin.app www.vecin.app;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ecdh_curve secp384r1;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_certificate /etc/nginx/ssl/chain.crt;
    ssl_certificate_key /etc/nginx/ssl/key.key;

    ssl_session_timeout 10m;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/ssl/chain.crt;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 30s;

    location / {
        proxy_pass http://frontend;
        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 $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-NginX-Proxy true;
        proxy_ssl_certificate /etc/nginx/ssl/chain.crt;
        proxy_ssl_certificate_key /etc/nginx/ssl/key.key;
        proxy_ssl_protocols TLSv1.2;
        proxy_ssl_verify        on;
        proxy_ssl_verify_depth  2;
        proxy_ssl_session_reuse on;
        # proxy_redirect http:// https://;

    }

    location /api{
        proxy_pass http://backend;
        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 $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-NginX-Proxy true;
        proxy_ssl_certificate /etc/nginx/ssl/chain.crt;
        proxy_ssl_certificate_key /etc/nginx/ssl/key.key;
        proxy_ssl_protocols TLSv1.2; 
        proxy_ssl_verify        on;
        proxy_ssl_verify_depth  2;
        proxy_ssl_session_reuse on;
        # proxy_redirect http:// https://;
    }
    root /usr/share/nginx/html/;
    index index.html index.htm index.nginx-debian.html;
}

server {
    listen 80;
    listen [::]:80;
    server_name vecin.app www.vecin.app;

     location / {
            rewrite ^ https://$host$request_uri? permanent;
    }
}

Upvotes: 0

Views: 326

Answers (1)

Eleomosynator
Eleomosynator

Reputation: 90

I'm going to admit that I'm not an nginx whiz and am guessing at a solution. I'll post this answer, as nobody else has given you an answer so far.

I noticed the phrasing in you nginx.conf file is slightly different than what I've seen on an online guide to redirecting all HTTP traffic to HTTPS on nginx. Your file ends in this section:

server {
    listen 80;
    listen [::]:80;
    server_name vecin.app www.vecin.app;

     location / {
            rewrite ^ https://$host$request_uri? permanent;
    }
}

The guide I saw suggests this format may be more approriate:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

The key distinction seems to be returning a 301 Permanent Redirect rather than simply rewriting the URL. The error message seemed to be about sending HTML to a port expecting HTTPS. That's what suggested to me that the Docker container is running fine, Docker networking is running ok, and nginx is running. That leaves the mechanism by which you're redirecting traffic as the prime suspect. Let us know if this works!

Here's the guide: Redirect all HTTP requests to HTTPS with Nginx

Upvotes: 0

Related Questions