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"
                    }
                ]
            },