Home > OS >  Why i cant access to my docker node app via browser, within container it works?
Why i cant access to my docker node app via browser, within container it works?

Time:06-17

my docker-compose.yml

version: "3"

services:
  client:
    ports:
      - "3000:3000"
    restart: always
    container_name: thread_client
    build:
      context: .
      dockerfile: ./client/client.Dockerfile
    volumes:
      - ./client/src:/app/client/src
      - /app/client/node_modules
    depends_on:
      - api

  api:
    build:
      context: .
      dockerfile: ./server/server.Dockerfile
    container_name: thread_api
    restart: always
    ports:
      - "3001:3001"
      - "3002:3002"
    volumes:
      - ./server/src:/app/server/src
      - /app/server/node_modules

  pg_db:
    image: postgres:14-alpine
    container_name: thread_db
    restart: always
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: thread
      POSTGRES_USER: postgres
    volumes:
      - pg_volume:/var/lib/postgresql/data

  adminer:
    image: adminer
    restart: always
    depends_on:
      - pg_db
    ports:
      - "9090:8080"

volumes:
  pg_volume:

client.Dockerfile

FROM node:16-alpine

WORKDIR /app

COPY .editorconfig .
COPY .eslintrc.yml .
COPY .lintstagedrc.yml .
COPY .ls-lint.yml .
COPY .npmrc .
COPY .nvmrc .
COPY .prettierrc.yml .
COPY .stylelintrc.yml .

COPY package.json .
COPY package-lock.json .

RUN npm install

COPY ./shared ./shared

RUN npm run install:shared

WORKDIR /app/client
COPY ./client/package.json .
COPY ./client/package-lock.json .
COPY ./client/.eslintrc.yml .
COPY ./client/.npmrc .
COPY ./client/.stylelintrc.yml .
COPY ./client/jsconfig.json .
COPY ./client/.env.example .env

RUN npm install

COPY ./client .

RUN npm run build

EXPOSE 3000

CMD ["npm", "run", "start"]

server.Dockerfile

FROM node:16-alpine

WORKDIR /app

COPY .editorconfig .
COPY .eslintrc.yml .
COPY .lintstagedrc.yml .
COPY .ls-lint.yml .
COPY .npmrc .
COPY .nvmrc .
COPY .prettierrc.yml .
COPY .stylelintrc.yml .

COPY package.json .
COPY package-lock.json .

RUN npm install

COPY ./shared ./shared

RUN npm run install:shared

WORKDIR /app/client
COPY ./client/package.json .
COPY ./client/package-lock.json .
COPY ./client/.eslintrc.yml .
COPY ./client/.npmrc .
COPY ./client/.stylelintrc.yml .
COPY ./client/jsconfig.json .
COPY ./client/.env.example .env

RUN npm install

COPY ./client .

RUN npm run build

WORKDIR /app/server

COPY ./server/package.json .
COPY ./server/package-lock.json .
COPY ./server/.env.example .env

RUN npm install

COPY ./server .

EXPOSE 8654

CMD ["npm", "start"]

client app is accessed in browser easily, but API service not, and I don't understand why

server.js

import fastify from 'fastify';
import cors from '@fastify/cors';
import fastifyStatic from '@fastify/static';
import http from 'http';
import Knex from 'knex';
import { Model } from 'objection';
import qs from 'qs';
import { Server as SocketServer } from 'socket.io';

import knexConfig from '../knexfile.js';
import { initApi } from './api/api.js';
import { ENV, ExitCode } from './common/enums/enums.js';
import { socketInjector as socketInjectorPlugin } from './plugins/plugins.js';
import { auth, comment, image, post, user } from './services/services.js';
import { handlers as socketHandlers } from './socket/handlers.js';

const app = fastify({
  querystringParser: str => qs.parse(str, { comma: true })
});

const socketServer = http.Server(app);
const io = new SocketServer(socketServer, {
  cors: {
    origin: '*',
    credentials: true
  }
});

const knex = Knex(knexConfig);
Model.knex(knex);

io.on('connection', socketHandlers);

app.register(cors, {
  origin: "*"
});
app.register(socketInjectorPlugin, { io });
app.register(initApi, {
  services: {
    auth,
    comment,
    image,
    post,
    user
  },
  prefix: ENV.APP.API_PATH
});

const staticPath = new URL('../../client/build', import.meta.url);
app.register(fastifyStatic, {
  root: staticPath.pathname,
  prefix: '/'
});

app.setNotFoundHandler((req, res) => {
  res.sendFile('index.html');
});

const startServer = async () => {
  try {
    await app.listen(ENV.APP.PORT);
    console.log(`Server is listening port: ${ENV.APP.PORT}`);
  } catch (err) {
    app.log.error(err);
    process.exit(ExitCode.ERROR);
  }
};
startServer();

socketServer.listen(ENV.APP.SOCKET_PORT);

So, I have tried curl localhost:3001 in API container and it's works, but why client works good via browser and API doesn't I don't any ideas.

How to debug, to find right solution?

UPD: docker inspect (API service container)

"Ports": {
                "3001/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "3001"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "3001"
                    }
                ],
                "3002/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "3002"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "3002"
                    }
                ]
            },

CodePudding user response:

Looking at your comment stating:

i am trying to access to that app via browser by localhost:3001

And the ports part of your docker-compose.yaml.

    ports:
      - "8654:3001"
      - "3002:3002"

You are trying to access the application on the wrong port.

With - "8654:3001" you are telling docker-compose to map port 3001 of the container to port 8654 on your host. (documentation)

Try to open http://localhost:8654 in your browser or changing 8654 in the docker-compose.yaml to 3001.

  • Related