How to run websocket and express http server on same port on docker on localhost?

I have a frontend container and a backend container. The frontend container serves react-based apps, and the backend container serves storage/authentication and other remote API. I am trying to use the WebSocket on the same port as the HTTP server, but the WebSocket server is always returning the pending state.

I tried using a different port and it’s working but not on the same port as the HTTP server.

Outside docker, it’s working fine.

Even I deployed the app to some servers and it’s working fine.

docker-compose: 2.1 express:4.17.1

docker-compose.yml file

version: '2.1'
services:
  backend:
    image: ${XSH_DOCKER_IMAGE}
    working_dir: /app
    command: sh -c "sleep 2; yarn start"
    env_file:
      - ${XSH_SECRETS}
    ports:
      - "${XSH_DEBUG_PORT_HOST}:${XSH_DEBUG_PORT_CONTAINER}"
    volumes:
      - ${XSH_BACKEND_WORKDIR}:/app/

  frontend:
    image: ${XSH_DOCKER_IMAGE}
    user: ${XSH_USER_ID}:${XSH_USER_GROUP}
    working_dir: /app
    command: yarn start
    ports:
      - "${XSH_WEBPACK_PORT_HOST}:${XSH_WEBPACK_PORT_CONTAINER}"
      - "${XSH_WEBPACK_ANALYZER_PORT_HOST}:8888"
    volumes:
      - ${XSH_FRONTEND_WORKDIR}:/app/

networks:
  default:
    driver: bridge
    ipam:
      config:
        - subnet: $XSH_DOCKER_NETWORK_SUBNET

How exactly did you do that?

I don’t work with websockets, but normally you can’t run multiple services on the same port and same IP address. The way to go is using a proxy server

@rimelek Thanks for your response.

Below is a brief of how I am doing that.

As shared above there are two containers, one is for serving frontend data(js/css/images etc).
For the backend, we use another container that handles the database and other APIs.

The frontend is currently served on the 8002 port, currently shown as placeholder text in docker-compose.yml

We use an x.sh file which does some cleanup and starts the docker container.

I tried creating a test WebSocket server in the backend with a different port and it worked on docker. I used ws - npm for websocket server.

When using the same code on the same port 8002 it didn’t work on docker, however, when deployed to the server it worked through docker and without docker.

The backend is in express js and the frontend is in react.

you can’t run multiple services on the same port

On the test server, it is working fine. I used the approach shared in the stackoverflow thread javascript - Express and WebSocket listening on the same port - Stack Overflow for using websocket on the same port.

Thanks for the link. So as I mentioned before, two application can’t listen on the same port and I wanted to see how it worked on the host because I was sure it was not doing that.

The Stck Overflow example shows two modules but only one actual listening service. The first (http server) is not listening on any port by itself, but the second module (ws-server) imports the http server so it is basically a single application on one port and a router implemented in code that “decides” what it should return based on the request.

When you move these apps to two different containers you can’t load the http server module this way. You could, but that would be run independently from the other servie in the other container.

So either you run the backend and the fontent component in behind a single listening service in one container, or you use a reverse proxy in front of the backend and the frontend which can do the same that the router did in the same code on the host.

By router I mean the app.get and app.post methods. I am not a nodejs developer so my answer is based on observation and other programming languages, but I guess that requests that was no cought by http server would be handled by the websocket server component.

We talked about reverse proxies in many topics and there are many proxy applications, but you will find Nginx Proxy and Traefik the most popular.