eilvelia / tdl

Node.js bindings to TDLib 🥒
MIT License
411 stars 53 forks source link

TDLib doesn't work in docker container #163

Closed Jhon-Mosk closed 2 months ago

Jhon-Mosk commented 3 months ago

I'm trying run tdl client in container. And I get next error:

app-1  | [13:46:18 UTC] ERROR: No native build was found for platform=linux arch=x64 runtime=node abi=115 uv=1 libc=musl node=20.15.1
app-1  |     loaded from: /usr/src/app/node_modules/tdl
app-1  | 
app-1  |     err: {
app-1  |       "type": "Error",
app-1  |       "message": "No native build was found for platform=linux arch=x64 runtime=node abi=115 uv=1 libc=musl node=20.15.1\n    loaded from: /usr/src/app/node_modules/tdl\n",
app-1  |       "stack":
app-1  |           Error: No native build was found for platform=linux arch=x64 runtime=node abi=115 uv=1 libc=musl node=20.15.1
app-1  |               loaded from: /usr/src/app/node_modules/tdl
app-1  |           
app-1  |               at load.resolve.load.path (/usr/src/app/node_modules/node-gyp-build/node-gyp-build.js:60:9)
app-1  |               at load (/usr/src/app/node_modules/node-gyp-build/node-gyp-build.js:22:30)
app-1  |               at loadAddon (/usr/src/app/node_modules/tdl/dist/addon.js:14:43)
app-1  |               at init (/usr/src/app/node_modules/tdl/dist/index.js:78:38)
app-1  |               at Object.createClient (/usr/src/app/node_modules/tdl/dist/index.js:142:5)
app-1  |               at Object.createClient (/usr/src/app/lib/tdl/index.js:16:22)
app-1  |               at run (/usr/src/app/main.js:11:31)
app-1  |               at Object.<anonymous> (/usr/src/app/main.js:36:1)
app-1  |               at Module._compile (node:internal/modules/cjs/loader:1358:14)
app-1  |               at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
app-1  |     }
Jhon-Mosk commented 3 months ago

If I run this code without docker, just node, it's work perfect.

# Отчет о подробностях системы
---

## Подробности отчета
- **Дата создания:**                               2024-07-12 16:51:32

## Аппаратная информация:
- **Модель оборудования:**                         ASUSTeK COMPUTER INC. PRIME B250M-PLUS
- **Память:**                                      16,0 ГиБ
- **Процессор:**                                   Intel® Core™ i7-7700K × 8
- **Графика:**                                     NVIDIA GeForce GTX 1060 6GB
- **Ёмкость диска:**                               2,1 ТБ

## Программная информация:
- **Версия прошивки:**                             0808
- **Название ОС:**                                 Fedora Linux 40 (Workstation Edition)
- **Сборка ОС:**                                   (null)
- **Тип ОС:**                                      64-бит
- **Версия GNOME:**                                46
- **Оконный интерфейс:**                           X11
- **Версия ядра:**                                 Linux 6.9.7-200.fc40.x86_64
Jhon-Mosk commented 3 months ago

Docker version 27.0.3, build 7d4bcd8 Docker Compose version v2.27.0-desktop.2 local node v20.15.1 node in docker v20.15.1-alpine

Jhon-Mosk commented 3 months ago

"tdl": "7.4.0" tdlLib: 1.8.33

Jhon-Mosk commented 3 months ago

I builded TDLib for Alpine and had this error.

Jhon-Mosk commented 3 months ago

Maybe version of TDLib build is 1.8.33 and version of tdl is 7.4.0. And they are not compatible?

Jhon-Mosk commented 3 months ago

In TDLib recommended contacting tdl repository. https://github.com/tdlib/td/issues/2981

eilvelia commented 3 months ago

This is not related to TDLib itself. If you use a glibc-based distribution in the docker container (e.g., ubuntu or debian), it will work out of the box. There is no prebuilt tdl's node addon available for musl, in that case the node addon should be built from source, but that didn't happen for some reason. That might be because there's no gcc and/or python3 present in your container (try apk add alpine-sdk gcc g++ python3 make), or you didn't run npm install. You should run npm install during the build of the container; you can't generally just copy the node modules from the host system. After that, you can also split the docker build into two stages so the final container is small and doesn't contain gcc (https://docs.docker.com/build/building/multi-stage/).

Jhon-Mosk commented 3 months ago

I builded TDLib for Alpine into container.

# syntax=docker/dockerfile:1

ARG NODE_VERSION=20.15.1

FROM node:${NODE_VERSION}-alpine as base
RUN apk update &&\
    apk upgrade &&\
    apk add alpine-sdk linux-headers git zlib-dev openssl-dev gperf php cmake &&\
    git clone https://github.com/tdlib/td.git &&\
    cd td &&\
    rm -rf build &&\
    mkdir build &&\
    cd build &&\
    cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=../tdlib .. &&\
    cmake --build . --target install &&\
    cd .. &&\
    cd .. &&\
    ls -l td/tdlib
WORKDIR /usr/src/app
EXPOSE $PORT

# development
FROM base AS development
USER node
COPY package*.json .
CMD ["sh", "-c", "npm install && npm run dev"]

# production
FROM base AS production
RUN --mount=type=bind,source=package.json,target=package.json \
    --mount=type=bind,source=package-lock.json,target=package-lock.json \
    --mount=type=cache,target=/root/.npm \
    npm ci --omit=dev
USER node
COPY . .
CMD npm run start
Jhon-Mosk commented 3 months ago

Than, I copied libtdjson.so.1.8.33 and used it.

eilvelia commented 3 months ago

COPY . . might be overwriting something from the previously executed npm ci.

I would do something like this (untested):

ARG NODE_VERSION=20.15.1

FROM node:${NODE_VERSION}-alpine AS build
WORKDIR /
RUN apk update && \
    apk add --no-cache alpine-sdk linux-headers git zlib-dev openssl-dev gperf cmake make gcc g++ python3 && \
    git clone https://github.com/tdlib/td.git && \
    cd td && \
    mkdir -p build && \
    cd build && \
    cmake -DCMAKE_BUILD_TYPE=Release .. && \
    cmake --build . --target tdjson
WORKDIR /usr/src/app
COPY . .
RUN cp -L /td/build/libtdjson.so . && npm install

FROM node:${NODE_VERSION}-alpine
WORKDIR /usr/src/app
COPY --from=build /usr/src/app .
ENTRYPOINT ["npm", "start"]

Add node_modules to .dockerignore.

Jhon-Mosk commented 3 months ago

COPY . . the team does not start, only part of the development works

Jhon-Mosk commented 2 months ago

I figured out what the problem was. You need to run the command ldd /path/to/file/libtdjson.so on the *.so file and it will be clear what is missing. It was necessary to install libc++-dev