skip to Main Content

i made a docker container for react app and another for django app . now when i make a websocket call

const socket = new WebSocket(
      // `ws://${WEB_SOCKET}:${WEB_SOCKET_PORT}/ws/lobby/`//this works when i feed ip of django app
      'wss://backend:8000/ws/lobby/'

    );

it says
home.jsx:9 WebSocket connection to 'wss://backend:8000/ws/lobby/' failed:

here is docker-compose.yml file

services:
    django-backend:
      container_name: backend 
      restart : always 
      build:
        context: ./server
      ports:
        - "8000:8000"
      depends_on:
        - postgres
        - redis 
      volumes:
        - ./server:/app 
.
.
    chess-frontend:
      container_name: frontend
      restart : always 
      build:
        context: ./chess-front
        target: development  
      ports:
        - "5173:5173"
      volumes:
        - ./chess-front:/usr/src/app

presently i am checking ip of django container and manually updating the web socket url .my question is

  • is there a way to make websocket url using domain name (ie. container name )
  • if not can i automatically get django container’s ip in docker-compose up and update in url .

2

Answers


  1. Chosen as BEST ANSWER

    after research i found that web socket urls with domain name of host container do not resolve into ip of host container , even if they are in same network.

    check this stack overflow thread

    however i came up with a way to automatically update the ip of host container by running bash script before the frontend container starts . This fetches ip of backend container and updates my .env file variable

    Dockerfile of react app

    FROM node:alpine AS base 
    WORKDIR /usr/src/app 
    COPY package*.json /usr/src/app/
    RUN npm install 
    
    FROM  base AS development 
    COPY . .
    COPY update_env.sh /usr/src/app/
    EXPOSE 5173
    RUN chmod +x /usr/src/app/update_env.sh
    CMD ["sh", "-c", "npm run dev"]
    FROM base AS production
    COPY . .
    EXPOSE 5173
    CMD ["npm" , "run" , "build"]
    

    update_env.sh

    #!/bin/sh
    BACKEND_CONTAINER_NAME="backend"
    ENV_FILE_PATH="./.env"
    BACKEND_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $BACKEND_CONTAINER_NAME)
    
    if [ -n "$BACKEND_IP" ]; then
        # Checks if VITE_IP already exists in the .env file
        if grep -q '^VITE_IP=' "$ENV_FILE_PATH"; then
            # Updates the existing VITE_IP value
            sed -i "s/^VITE_IP=.*/VITE_IP=$BACKEND_IP/" "$ENV_FILE_PATH"
        else
            # Adds VITE_IP to the .env file
            echo "VITE_IP=$BACKEND_IP" >> "$ENV_FILE_PATH"
        fi
    
        echo "Updated VITE_IP in .env file."
    else
        echo "Error: Unable to obtain the IP address of the backend container."
    fi
    

    docker-compose.yml

    chess-frontend:
        container_name: frontend
        restart : always 
        build:
          context: ./chess-front
          target: development  
        ports:
          - "5173:5173"
        volumes:
          - ./chess-front:/usr/src/app
        depends_on:
          - django-backend
        command: sh -c "/usr/src/app/update_env.sh && npm run dev"
    

    now whenever container restarts , i get ip of backend container automatically.


  2. In Docker, containers can be accessed by their names within the same network.
    You can create a network using the docker network create command.
    For example:
    docker network create my-network
    Then, when you run your containers, add them to the network using the –network flag.
    For example:
    docker run –name backend –network my-network

    YML update would be to specify networks as per below.

    version: '3'
    services:
      django-backend:
        container_name: backend
        restart: always
        build:
          context: ./server
        ports:
          - "8000:8000"
        depends_on:
          - postgres
          - redis
        volumes:
          - ./server:/app
        networks:
          - my-network
      chess-frontend:
        container_name: frontend
        restart: always
        build:
          context: ./chess-front
          target: development
        ports:
          - "5173:5173"
        volumes:
          - ./chess-front:/usr/src/app
        networks:
          - my-network
    networks:
      my-network:
        driver: bridge
    

    Remember to replace the port numbers (8000 and 5173) with the actual ports used by your backend and frontend services, respectively.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search