Home > Mobile >  Backend and Frontend in Docker work locally but not remotely
Backend and Frontend in Docker work locally but not remotely

Time:10-11

Problem

I have three Docker containers: a backend, a frontend and an nginx container that handle requests. When I run it on my computer (windows laptop with docker engine), everything works perfectly. I can see the call are made in the logs of the containers:

reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00  0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00  0000] "GET /static/js/bundle.js HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00  0000] "GET /static/js/vendors~main.chunk.js HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:00  0000] "GET /static/js/main.chunk.js HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:01  0000] "GET /favicon.ico HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:01  0000] "GET /manifest.json HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:01  0000] "GET /logo192.png HTTP/1.1" 304 0 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
reverse_proxy_1  | 172.19.0.1 - - [10/Oct/2021:21:15:02  0000] "GET /api/versions/ HTTP/1.1" 200 55 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
backend_1        | Sending versions

When I deploy this either on a dedicated ubuntu server (192.168.31.103) on a network or a VM in VirtualBox on my computer, it seems the frontend and backend don't communicate anymore. I can see the front end, but if I do the same operation as before, the backend is not queried:

192.168.31.101 - - [10/Oct/2021:21:29:39  0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39  0000] "GET /sockjs-node HTTP/1.1" 101 2801 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39  0000] "GET /static/js/bundle.js HTTP/1.1" 304 0 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39  0000] "GET /static/js/vendors~main.chunk.js HTTP/1.1" 304 0 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:39  0000] "GET /static/js/main.chunk.js HTTP/1.1" 304 0 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:29:41  0000] "GET /favicon.ico HTTP/1.1" 200 2114 "http://192.168.31.103/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"

I can go directly to the backend in my browser: http://192.168.31.103/api/versions/ and this works fine, return the json object and nginx displays the corresponding log.

192.168.31.101 - - [10/Oct/2021:21:39:25  0000] "GET /api/versions/ HTTP/1.1" 200 55 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
192.168.31.101 - - [10/Oct/2021:21:39:25  0000] "GET /favicon.ico HTTP/1.1" 200 2114 "http://192.168.31.103/api/versions/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"

(note that 192.168.31.101 is the IP of my laptop on the network).

Can you spot the mistake?

Configuration

I have a Django-REST backend, that serve some views, everything behind the /api/ prefix, for examples: http:localhost/api/version. I removed all CSRF protection for now.

settings.py

ALLOWED_HOSTS = [
  localhost,
  127.0.0.1,
  192.168.31.103,
]

I have a React frontend that will fetch this backend:

App.js

[...]
const backendURL = 'http://localhost';

const getBackendVersion = () => {
    setFetchingVersions(true);
    fetch(`${backendURL}/api/versions/`)
      .then( response => response.json())
      .then( d => {
        setAppVersions({
          'frontend': frontendVersion,
          'backend': d['versions']['maapi'],
        })
      })
      .catch( () => setFetchingVersions(false));
  };
[...]

I deploy this using Docker.

docker-compose.yml

version: '3.8'

services:
  backend:
    build: ./ma-backend
    command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
    expose:
      - 8000
    env_file:
      - ./.env.prod

  frontend:
    build: ./ma-frontend
    command: npm start
    expose:
      - 3000
    depends_on:
      - backend
    env_file:
      - ./.env.prod

  reverse_proxy:
    build: ./nginx
    ports:
      - 80:80
    depends_on:
      - backend
      - frontend

nginx.conf:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
  worker_connections 1024;
}

http {
  upstream backend {
    server backend:8000;
  }

  upstream frontend {
    server frontend:3000;
  }

  server {
    listen 80;

    server_name localhost 127.0.0.1;

    location /api {
      proxy_pass              http://backend;
      proxy_http_version  1.1;
      proxy_redirect      default;
      proxy_set_header    Upgrade $http_upgrade;
      proxy_set_header    Connection "upgrade";
      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 /admin {
      proxy_pass              http://backend;
      proxy_http_version  1.1;
      proxy_redirect      default;
      proxy_set_header    Upgrade $http_upgrade;
      proxy_set_header    Connection "upgrade";
      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 / {
      proxy_pass              http://frontend;
      proxy_http_version  1.1;
      proxy_redirect      default;
      proxy_set_header    Upgrade $http_upgrade;
      proxy_set_header    Connection "upgrade";
      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;
    }
  }
}

CodePudding user response:

Looks like backendURL = 'http://localhost'; may be the culprit here? E.g your front-end is configured to query your backend at http://localhost eventhough it is deployed on a different IP/server.

Is it possible for you to use a environment variable or something like that during the React build process to provide the actual URL of your backend?

  • Related