daeuniverse / daed-revived-next

daed, A modern web dashboard for dae
https://dae.v2raya.org
MIT License
47 stars 11 forks source link

feature: Container orchestration with dae-wing #29

Open hero-intelligent opened 8 months ago

hero-intelligent commented 8 months ago

Dockerfile:

# can't build on latest node version v21.0.0, because of this issue:
# https://github.com/nodejs/node/issues/50269
# neither on bun, because of this issue:
# https://github.com/oven-sh/bun/issues/4671
FROM docker.io/node:20-alpine AS base

FROM base AS builder

WORKDIR /build

COPY . .

ENV HUSKY 0
ENV STANDALONE 1

RUN corepack enable
RUN corepack prepare pnpm@latest --activate

RUN pnpm install
RUN pnpm build

FROM golang:1.21-bookworm as wing

RUN \
    apt-get update; apt-get install -y git make llvm-15 clang-15; \
    apt-get clean autoclean && apt-get autoremove -y && rm -rf /var/lib/{apt,dpkg,cache,log}/

# build bundle process
ENV CGO_ENABLED=0
ENV CLANG=clang-15

WORKDIR /build/wing

COPY ./wing .

RUN make deps
RUN go build -o dae-wing

FROM base AS runner

WORKDIR /app

COPY --from=builder /build/public ./public

RUN mkdir .next

COPY --from=builder /build/.next/standalone .
COPY --from=builder /build/.next/static ./.next/static

ENV NODE_ENV production

COPY --from=wing /build/wing/dae-wing /usr/local/bin

EXPOSE 3000

CMD dae-wing run -c ./etc/dae-wing --api-only & node server.js
sudo docker run -it \
    --privileged \
    --network=host \
    --pid=host \
    --restart=always \
    -v /sys:/sys \
    -v /etc/daed:/etc/dae-wing \
    --name=daed-next \
    next
hero-intelligent commented 8 months ago

I have some questions.

  1. why the dashboard site is at 127.0.1.1 instead of 127.0.0.1 or 0.0.0.0?

related log:

  ▲ Next.js 13.5.6
  - Local:        http://debian:3000
  - Network:      http://127.0.1.1:3000

 ✓ Ready in 41ms
  1. Why the too weak password is not displayed onto the screen instead of connection status 500?
 ⨯ ClientError: too weak password; should contain numbers and letters, and no less than 6 in length: {"response":{"errors":[{"message":"too weak password; should contain numbers and letters, and no less than 6 in length","path":["createUser"]}],"data":null,"status":200,"headers":{}},"request":{"query":"mutation CreateUser($username: String!, $password: String!) {\n  createUser(username: $username, password: $password)\n}","variables":{"username":"daed","password":"daeuniverse"}}}
    at makeRequest (/app/.next/server/chunks/871.js:120:169752)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async POST (/app/.next/server/app/api/login/route.js:27:37)
    at async /app/node_modules/.pnpm/next@13.5.6_@babel+core@7.23.2_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:14:39709 {
  response: {
    errors: [ [Object] ],
    data: null,
    status: 200,
    headers: Headers { [Symbol(map)]: [Object: null prototype] }
  },
  request: {
    query: 'mutation CreateUser($username: String!, $password: String!) {\n' +
      '  createUser(username: $username, password: $password)\n' +
      '}',
    variables: { username: 'daed', password: 'daeuniverse' }
  }
}
WARN[0156] dangerous converting: may exceeds graphQL int32 range  name=SoMarkFromDae type=uint32
WARN[0156] dangerous converting: may exceeds graphQL int32 range  name=SoMarkFromDae type=uint32
^CERRO[0196] Exiting: interrupt   
  1. At the start of the program and trying to access the dashboard, I get a white screen with a blue spinner in the middle, with a notice from browser read Performing a TLS Handshake to cdn.jsdelivr.net..., until I click on the cancel refresh button.
hero-intelligent commented 8 months ago

all based on 952b1c9878739349bde5149468a230f66e633256

kunish commented 8 months ago

I have some questions.

  1. why the dashboard site is at 127.0.1.1 instead of 127.0.0.1 or 0.0.0.0?

related log:

  ▲ Next.js 13.5.6
  - Local:        http://debian:3000
  - Network:      http://127.0.1.1:3000

 ✓ Ready in 41ms
  1. Why the too weak password is not displayed onto the screen instead of connection status 500?
 ⨯ ClientError: too weak password; should contain numbers and letters, and no less than 6 in length: {"response":{"errors":[{"message":"too weak password; should contain numbers and letters, and no less than 6 in length","path":["createUser"]}],"data":null,"status":200,"headers":{}},"request":{"query":"mutation CreateUser($username: String!, $password: String!) {\n  createUser(username: $username, password: $password)\n}","variables":{"username":"daed","password":"daeuniverse"}}}
    at makeRequest (/app/.next/server/chunks/871.js:120:169752)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async POST (/app/.next/server/app/api/login/route.js:27:37)
    at async /app/node_modules/.pnpm/next@13.5.6_@babel+core@7.23.2_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:14:39709 {
  response: {
    errors: [ [Object] ],
    data: null,
    status: 200,
    headers: Headers { [Symbol(map)]: [Object: null prototype] }
  },
  request: {
    query: 'mutation CreateUser($username: String!, $password: String!) {\n' +
      '  createUser(username: $username, password: $password)\n' +
      '}',
    variables: { username: 'daed', password: 'daeuniverse' }
  }
}
WARN[0156] dangerous converting: may exceeds graphQL int32 range  name=SoMarkFromDae type=uint32
WARN[0156] dangerous converting: may exceeds graphQL int32 range  name=SoMarkFromDae type=uint32
^CERRO[0196] Exiting: interrupt   
  1. At the start of the program and trying to access the dashboard, I get a white screen with a blue spinner in the middle, with a notice from browser read Performing a TLS Handshake to cdn.jsdelivr.net..., until I click on the cancel refresh button.

Haven't done too much error handling or forwarding yet

kunish commented 8 months ago

Maybe we can do better, by adding a Dockerfile seperately for dae-wing, doing so allows us to have a docker-compose.yml that can build and start daed and dae-wing at once, at the same time, avoid coupling these two projects too much.

kunish commented 8 months ago

By the way, personaly, i really dont like the & business

hero-intelligent commented 8 months ago
# can't build on latest node version v21.0.0, because of this issue:
# https://github.com/nodejs/node/issues/50269
# neither on bun, because of this issue:
# https://github.com/oven-sh/bun/issues/4671
FROM docker.io/node:20-alpine AS base

FROM base AS builder

WORKDIR /build

COPY . .

ENV HUSKY 0
ENV STANDALONE 1

RUN corepack enable
RUN corepack prepare pnpm@latest --activate

RUN pnpm install
RUN pnpm build

FROM golang:1.21-bookworm as build-bundle

RUN \
    apt-get update; apt-get install -y git make llvm-15 clang-15; \
    apt-get clean autoclean && apt-get autoremove -y && rm -rf /var/lib/{apt,dpkg,cache,log}/

# build bundle process
ENV CGO_ENABLED=0
ENV CLANG=clang-15
ARG DAED_VERSION=self-build

WORKDIR /build/web

COPY --from=builder /build/public ./public

RUN mkdir .next

COPY --from=builder /build/.next/standalone .
COPY --from=builder /build/.next/static ./.next/static

ENV NODE_ENV production

WORKDIR /build/wing

COPY ./wing .

RUN make APPNAME=daed VERSION=$DAED_VERSION OUTPUT=daed WEB_DIST=/build/web/ bundle

FROM alpine

LABEL org.opencontainers.image.source=https://github.com/daeuniverse/daed

RUN mkdir -p /usr/local/share/daed/
RUN mkdir -p /etc/daed/
RUN wget -O /usr/local/share/daed/geoip.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geoip.dat; \
    wget -O /usr/local/share/daed/geosite.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geosite.dat
COPY --from=build-bundle /build/wing/daed /usr/local/bin

EXPOSE 2023

CMD ["daed", "run", "-c", "/etc/daed"]

Notice: FAILED as expected to build in daed legacy way, needn't try again yourself.

kunish commented 8 months ago

What i mean was something like this

# wing/Dockerfile
FROM golang:1.21-bookworm as builder

WORKDIR /build

RUN apt-get update
RUN apt-get install -y git make llvm-15 clang-15

ENV CGO_ENABLED=0
ENV CLANG=clang-15
ARG VERSION=self-build

COPY . .

RUN make APPNAME=dae-wing VERSION=$VERSION

FROM alpine

WORKDIR /etc/dae-wing

RUN mkdir -p /usr/local/share/dae-wing
RUN wget -O /usr/local/share/dae-wing/geoip.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geoip.dat
RUN wget -O /usr/local/share/dae-wing/geosite.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geosite.dat
COPY --from=builder /build/dae-wing /usr/local/bin

EXPOSE 2023

CMD ["dae-wing"]
ENTRYPOINT ["dae-wing", "run", "-c", "."]
# docker-compose.yml
version: '3'

services:
  dae-wing:
    # referencing the wing/Dockerfile inside the dae-wing submodule directory
    build: wing
    container_name: dae-wing
    ports:
      - '2023:2023'

  daed:
    # referencing the Dockerfile at the root directory of this repository
    build: .
    container_name: daed
    environment:
      WING_API_URL: 'http://dae-wing:2023'
    ports:
      - '3000:3000'
    depends_on:
      - dae-wing
hero-intelligent commented 8 months ago
# .env.local
NEXT_PUBLIC_JWT_SECRET=daeuniverse
NEXT_TELEMETRY_DISABLED=1

HOSTNAME="0.0.0.0"

WING_API_URL=http://172.17.0.1:2023
# can't build on latest node version v21.0.0, because of this issue:
# https://github.com/nodejs/node/issues/50269
# neither on bun, because of this issue:
# https://github.com/oven-sh/bun/issues/4671
FROM docker.io/node:20-alpine AS web-base

FROM web-base AS web-builder

WORKDIR /build

COPY . .

ENV HUSKY 0
ENV STANDALONE 1

RUN corepack enable
RUN corepack prepare pnpm@latest --activate

RUN pnpm install
RUN pnpm build

FROM web-base AS web-runner

LABEL org.opencontainers.image.source=https://github.com/daeuniverse/daed-revived-next

WORKDIR /app

COPY --from=web-builder /build/public ./public

RUN mkdir .next

COPY --from=web-builder /build/.next/standalone .
COPY --from=web-builder /build/.next/static ./.next/static

ENV NODE_ENV production

EXPOSE 3000

CMD ["node", "server.js"]

FROM golang:1.21-bookworm as wing-builder

RUN \
    apt-get update; apt-get install -y git make llvm-15 clang-15; \
    apt-get clean autoclean && apt-get autoremove -y && rm -rf /var/lib/{apt,dpkg,cache,log}/

# build bundle process
ENV CGO_ENABLED=0
ENV CLANG=clang-15

WORKDIR /build/wing

COPY ./wing .

RUN make deps
RUN go build -o dae-wing

FROM alpine as wing-runner

LABEL org.opencontainers.image.source=https://github.com/daeuniverse/dae-wing

RUN mkdir -p /usr/local/share/dae-wing/ && mkdir -p /etc/dae-wing/
RUN wget -O /usr/local/share/dae-wing/geoip.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geoip.dat; \
    wget -O /usr/local/share/dae-wing/geosite.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geosite.dat

COPY --from=wing-builder /build/wing/dae-wing /usr/local/bin

EXPOSE 2023

CMD ["dae-wing", "run", "-c", "/etc/dae-wing"]
version: '3'

services:
  daed:
    build:
      context: .
      dockerfile: Dockerfile
      target: web-runner
    container_name: daed
    network_mode: bridge
    ports:
      - '3000:3000'
    depends_on:
     - dae-wing

  dae-wing:
    privileged: true
    network_mode: host
    pid: host
    build:
      context: .
      dockerfile: Dockerfile
      target: wing-runner
    container_name: dae-wing
    volumes:
      - /sys:/sys
      - /etc/dae-wing:/etc/dae-wing
hero-intelligent commented 8 months ago

tested

hero-intelligent commented 8 months ago

For Mac (Test Needed):

reference: https://nickjanetakis.com/blog/docker-tip-65-get-your-docker-hosts-ip-address-from-in-a-container

# .env.local
WING_API_URL=http://host.docker.internal:2023
# docker-compose.yml
version: '3'

services:
  dae-wing:
    privileged: true
    network_mode: host
    pid: host
    build: wing
    container_name: dae-wing
    volumes:
      - /sys:/sys
      - /etc/dae-wing:/etc/dae-wing

  daed:
    # referencing the Dockerfile at the root directory of this repository
    build: .
    container_name: daed
    ports:
      - '3000:3000'
    depends_on:
      - dae-wing
# wing/Dockerfile
FROM golang:1.21-bookworm as builder

WORKDIR /build

RUN apt-get update
RUN apt-get install -y git make llvm-15 clang-15

ENV CGO_ENABLED=0
ENV CLANG=clang-15
ARG VERSION=self-build

COPY . .

RUN make APPNAME=dae-wing VERSION=$VERSION

FROM alpine

WORKDIR /etc/dae-wing

RUN mkdir -p /usr/local/share/dae-wing
RUN wget -O /usr/local/share/dae-wing/geoip.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geoip.dat
RUN wget -O /usr/local/share/dae-wing/geosite.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geosite.dat
COPY --from=builder /build/dae-wing /usr/local/bin

EXPOSE 2023

CMD ["dae-wing"]
ENTRYPOINT ["dae-wing", "run", "-c", "."]
hero-intelligent commented 8 months ago

As for Linux, it won't work due to 8b2779392f3749406a78e06f45e5335f301753db. Environment variable WING_API_URL is burnt in during build process and unable to be changed, while the address may change and be different from that of build process.

What i mean was something like this

# wing/Dockerfile
FROM golang:1.21-bookworm as builder

WORKDIR /build

RUN apt-get update
RUN apt-get install -y git make llvm-15 clang-15

ENV CGO_ENABLED=0
ENV CLANG=clang-15
ARG VERSION=self-build

COPY . .

RUN make APPNAME=dae-wing VERSION=$VERSION

FROM alpine

WORKDIR /etc/dae-wing

RUN mkdir -p /usr/local/share/dae-wing
RUN wget -O /usr/local/share/dae-wing/geoip.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geoip.dat
RUN wget -O /usr/local/share/dae-wing/geosite.dat https://github.com/v2rayA/dist-v2ray-rules-dat/raw/master/geosite.dat
COPY --from=builder /build/dae-wing /usr/local/bin

EXPOSE 2023

CMD ["dae-wing"]
ENTRYPOINT ["dae-wing", "run", "-c", "."]
# docker-compose.yml
version: '3'

services:
  dae-wing:
    # referencing the wing/Dockerfile inside the dae-wing submodule directory
    build: wing
    container_name: dae-wing
    ports:
      - '2023:2023'

  daed:
    # referencing the Dockerfile at the root directory of this repository
    build: .
    container_name: daed
    environment:
      WING_API_URL: 'http://dae-wing:2023'
    ports:
      - '3000:3000'
    depends_on:
      - dae-wing
hero-intelligent commented 8 months ago

There is another command line i'd like to keep here for future use.

ip -4 addr show eth0 | grep -Po 'inet \K[\d.]+'