FinnM
FinnM

Reputation: 411

Docker-Compose - Frontend service cannot use endpoint from backend

Context

I am currently working on a multi-container project involving react, django, and (eventually) several datastores all containerized and tied together with docker-compose. This is all developed within vscode devcontainers. The host operating system is Windows 11.

Problem

I can make requests to my Django API via the browser (and Django's API web interface). However I cannot make requesets to the API via the frontend service. Using the javascript fetch api, I am unable to make requests to any of the following

What I've Tried

Details

Backend Dockerfile

FROM  python:3.10-alpine
ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY . . 
RUN apk add poetry && poetry install
EXPOSE 8000

Frontend Dockerfile

FROM node:lts-alpine
WORKDIR /app
COPY . .
RUN yarn install
EXPOSE 3000
CMD ["yarn", "start"]

docker-compose.yml

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/frontend
    depends_on:
      - backend

  backend:
    build: ./backend
    ports:
      - "8000:8000"
    volumes:
      - ./backend:/backend
    command: "poetry run python manage.py runserver 0.0.0.0:8000"

Django Settings.py

ALLOWED_HOSTS = ["0.0.0.0"] # ADDED CORS

# Application definition

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "corsheaders", # ADDED CORS
]

CORS_ORIGIN_WHITELIST = [
    "http://localhost:3000" # ADDED CORS
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware", # ADDED CORS
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

React App.tsx

const App = () => {
  const [currentTime, setCurrentTime] = useState(0);
  const [currentDate, setCurrentDate] = useState(0);
  useEffect(() => {
    fetch(`http://localhost:8000`)
      .then((res) => res.json())
      .then((data) => {
        setCurrentTime(data.time);
        setCurrentDate(data.date);
      });
  }, []);
  return (
    <div className="App">
      <header className="App-header">
        <p>
          The date is {currentDate} and the time is {currentTime}.
        </p>{" "}
        <br />
      </header>
    </div>
  );
};

Upvotes: 0

Views: 274

Answers (1)

FinnM
FinnM

Reputation: 411

Django's settings.py required the following since the only ports that were accessible were from the http://host.docker.internal domain. Not localhost as described in many tuts and documentation.

CORS_ORIGIN_WHITELIST = [
    ..., 
    "http://host.docker.internal:3000"
]

Upvotes: 0

Related Questions