0

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"
                    }
                ]
            },
DF1
  • 15
  • 6

1 Answers1

1

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.

joelthegraf
  • 116
  • 6
  • updated, 3001:3001 is correct but now working, 3002:3002 is correct and it's works client connecting to socket – DF1 Jun 17 '22 at 10:26
  • curl localhost:3001 from container (api service) is working good – DF1 Jun 17 '22 at 10:27
  • I don't really understand your first comment. Is it working or not? If its not working, in what way? Does your request timeout? Does the request of the client get blocked? – joelthegraf Jun 17 '22 at 10:51
  • I can access client service from browser by localhost:3000, but I can't access to api service by localhost:3001 – DF1 Jun 17 '22 at 10:57
  • i receive http://localhost:3001/api/auth/login ERR_CONNECTION_REFUSED – DF1 Jun 17 '22 at 10:57
  • but i can send request to localhost:3001/api/auth/login within API container – DF1 Jun 17 '22 at 10:57
  • Looks like a problem with fastify to me. Looking at the `Your first server` section in the [documentation](https://www.fastify.io/docs/latest/Guides/Getting-Started/#your-first-server), there is a note telling that if _only_ the port is provided on the listen function, fastify will _only_ listen on localhost: `127.0.0.1`. So try changing `app.listen(ENV.APP.PORT)` to `app.listen({port: ENV.APP.PORT, host: '0.0.0.0'});` – joelthegraf Jun 17 '22 at 11:04
  • i appreciate for your help man. this is the solution – DF1 Jun 17 '22 at 11:11
  • The note section also states: `When deploying to a Docker (or another type of) container using 0.0.0.0 or :: would be the easiest method for exposing the application.`. – joelthegraf Jun 17 '22 at 11:11
  • yes, found it , thanx – DF1 Jun 17 '22 at 11:18