feat(docker): add multi-arch Docker build and tagged release pipeline
This commit is contained in:
16
.dockerignore
Normal file
16
.dockerignore
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
node_modules/
|
||||||
|
.nogit/
|
||||||
|
nogit/
|
||||||
|
.git/
|
||||||
|
.playwright-mcp/
|
||||||
|
.vscode/
|
||||||
|
test/
|
||||||
|
dist_rust/
|
||||||
|
dist_ts_web/
|
||||||
|
rust/target/
|
||||||
|
sip_trace.log
|
||||||
|
sip_trace_*.log
|
||||||
|
proxy.out
|
||||||
|
proxy_v2.out
|
||||||
|
*.pid
|
||||||
|
.server.pid
|
||||||
32
.gitea/workflows/docker_tags.yaml
Normal file
32
.gitea/workflows/docker_tags.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: Docker (tags)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
env:
|
||||||
|
IMAGE: code.foss.global/host.today/ht-docker-node:dbase_dind
|
||||||
|
NPMCI_LOGIN_DOCKER_GITEA: ${{ github.server_url }}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }}
|
||||||
|
NPMCI_LOGIN_DOCKER_DOCKERREGISTRY: ${{ secrets.NPMCI_LOGIN_DOCKER_DOCKERREGISTRY }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ${{ env.IMAGE }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Prepare
|
||||||
|
run: |
|
||||||
|
pnpm install -g pnpm
|
||||||
|
pnpm install -g @git.zone/tsdocker
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
run: |
|
||||||
|
tsdocker login
|
||||||
|
tsdocker build
|
||||||
|
tsdocker push
|
||||||
@@ -8,5 +8,16 @@
|
|||||||
"production": true
|
"production": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"@git.zone/tsrust": {
|
||||||
|
"targets": ["linux_amd64", "linux_arm64"]
|
||||||
|
},
|
||||||
|
"@git.zone/tsdocker": {
|
||||||
|
"registries": ["code.foss.global"],
|
||||||
|
"registryRepoMap": {
|
||||||
|
"code.foss.global": "serve.zone/siprouter",
|
||||||
|
"dockerregistry.lossless.digital": "serve.zone/siprouter"
|
||||||
|
},
|
||||||
|
"platforms": ["linux/amd64", "linux/arm64"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
62
Dockerfile
Normal file
62
Dockerfile
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# gitzone dockerfile_service
|
||||||
|
## STAGE 1 // BUILD
|
||||||
|
FROM code.foss.global/host.today/ht-docker-node:lts AS build
|
||||||
|
|
||||||
|
# buildx sets TARGETARCH automatically for each platform it's building:
|
||||||
|
# linux/amd64 -> TARGETARCH=amd64
|
||||||
|
# linux/arm64 -> TARGETARCH=arm64
|
||||||
|
# We use it to tell tsrust to build ONLY the current container's arch. This
|
||||||
|
# overrides the `@git.zone/tsrust.targets` list in .smartconfig.json, which is
|
||||||
|
# right for local dev / CI (where you want both binaries) but wrong for per-
|
||||||
|
# platform Docker stages (each stage would then also try to cross-compile to
|
||||||
|
# the OTHER arch — which fails in the arm64 stage because no reverse cross-
|
||||||
|
# toolchain is installed).
|
||||||
|
#
|
||||||
|
# With --target set, tsrust builds a single target natively within whichever
|
||||||
|
# platform this stage is running under (native on amd64, QEMU-emulated on arm64).
|
||||||
|
ARG TARGETARCH
|
||||||
|
|
||||||
|
COPY ./ /app
|
||||||
|
WORKDIR /app
|
||||||
|
RUN pnpm config set store-dir .pnpm-store
|
||||||
|
RUN rm -rf node_modules && pnpm install
|
||||||
|
|
||||||
|
# tsrust --target takes precedence over .smartconfig.json's targets array.
|
||||||
|
# Writes dist_rust/proxy-engine_linux_amd64 or dist_rust/proxy-engine_linux_arm64.
|
||||||
|
# The TS layer (ts/proxybridge.ts buildLocalPaths) picks the right one at runtime
|
||||||
|
# via process.arch.
|
||||||
|
RUN pnpm exec tsrust --target linux_${TARGETARCH}
|
||||||
|
|
||||||
|
# Web bundle (esbuild — pure JS, uses the platform's native esbuild binary
|
||||||
|
# installed by pnpm above, so no cross-bundling concerns).
|
||||||
|
RUN pnpm run bundle
|
||||||
|
|
||||||
|
# Drop pnpm store to keep the image smaller. node_modules stays because the
|
||||||
|
# runtime entrypoint is tsx and siprouter has no separate dist_ts/ to run from.
|
||||||
|
RUN rm -rf .pnpm-store
|
||||||
|
|
||||||
|
## STAGE 2 // PRODUCTION
|
||||||
|
FROM code.foss.global/host.today/ht-docker-node:alpine-node AS production
|
||||||
|
|
||||||
|
# gcompat + libstdc++ let the glibc-linked proxy-engine binary run on Alpine.
|
||||||
|
RUN apk add --no-cache gcompat libstdc++
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=build /app /app
|
||||||
|
|
||||||
|
ENV SIPROUTER_MODE=OCI_CONTAINER
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.title="siprouter" \
|
||||||
|
org.opencontainers.image.description="SIP proxy with Rust data plane and WebRTC bridge" \
|
||||||
|
org.opencontainers.image.source="https://code.foss.global/serve.zone/siprouter"
|
||||||
|
|
||||||
|
# 5070 SIP signaling (UDP+TCP)
|
||||||
|
# 5061 SIP-TLS (optional, UDP+TCP)
|
||||||
|
# 3060 Web UI / WebSocket (HTTP or HTTPS, auto-detected from .nogit/cert.pem)
|
||||||
|
# 20000-20200/udp RTP media range (must match config.proxy.rtpPortRange)
|
||||||
|
EXPOSE 5070/udp 5070/tcp 5061/udp 5061/tcp 3060/tcp 20000-20200/udp
|
||||||
|
|
||||||
|
# exec replaces sh as PID 1 with tsx, so SIGINT/SIGTERM reach Node and
|
||||||
|
# ts/sipproxy.ts' shutdown handler (which calls shutdownProxyEngine) runs cleanly.
|
||||||
|
CMD ["sh", "-c", "exec ./node_modules/.bin/tsx ts/sipproxy.ts"]
|
||||||
@@ -1,5 +1,14 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-04-11 - 1.20.0 - feat(docker)
|
||||||
|
add multi-arch Docker build and tagged release pipeline
|
||||||
|
|
||||||
|
- Add a production Dockerfile for building and running the SIP router with the Rust proxy engine and web bundle
|
||||||
|
- Configure tsdocker and tsrust for linux/amd64 and linux/arm64 image builds and registry mapping
|
||||||
|
- Add a tag-triggered Gitea workflow to build and push Docker images
|
||||||
|
- Update runtime binary resolution to load architecture-specific Rust artifacts in Docker and CI environments
|
||||||
|
- Add Docker-related package scripts, dependency updates, and ignore rules for container builds
|
||||||
|
|
||||||
## 2026-04-11 - 1.19.2 - fix(web-ui)
|
## 2026-04-11 - 1.19.2 - fix(web-ui)
|
||||||
normalize lucide icon names across SIP proxy views
|
normalize lucide icon names across SIP proxy views
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"bundle": "node node_modules/.pnpm/esbuild@0.27.7/node_modules/esbuild/bin/esbuild ts_web/index.ts --bundle --format=esm --outfile=dist_ts_web/bundle.js --platform=browser --target=es2022 --minify",
|
"bundle": "node node_modules/.pnpm/esbuild@0.27.7/node_modules/esbuild/bin/esbuild ts_web/index.ts --bundle --format=esm --outfile=dist_ts_web/bundle.js --platform=browser --target=es2022 --minify",
|
||||||
"buildRust": "tsrust",
|
"buildRust": "tsrust",
|
||||||
|
"build": "pnpm run buildRust && pnpm run bundle",
|
||||||
|
"build:docker": "tsdocker build --verbose",
|
||||||
|
"release:docker": "tsdocker push --verbose",
|
||||||
"start": "tsx ts/sipproxy.ts",
|
"start": "tsx ts/sipproxy.ts",
|
||||||
"restartBackground": "pnpm run buildRust && pnpm run bundle; test -f .server.pid && kill $(cat .server.pid) 2>/dev/null; sleep 1; rm -f sip_trace.log proxy.out && nohup tsx ts/sipproxy.ts > proxy.out 2>&1 & echo $! > .server.pid; sleep 2; cat proxy.out"
|
"restartBackground": "pnpm run buildRust && pnpm run bundle; test -f .server.pid && kill $(cat .server.pid) 2>/dev/null; sleep 1; rm -f sip_trace.log proxy.out && nohup tsx ts/sipproxy.ts > proxy.out 2>&1 & echo $! > .server.pid; sleep 2; cat proxy.out"
|
||||||
},
|
},
|
||||||
@@ -14,10 +17,12 @@
|
|||||||
"@design.estate/dees-element": "^2.2.4",
|
"@design.estate/dees-element": "^2.2.4",
|
||||||
"@push.rocks/smartrust": "^1.3.2",
|
"@push.rocks/smartrust": "^1.3.2",
|
||||||
"@push.rocks/smartstate": "^2.3.0",
|
"@push.rocks/smartstate": "^2.3.0",
|
||||||
|
"tsx": "^4.21.0",
|
||||||
"ws": "^8.20.0"
|
"ws": "^8.20.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbundle": "^2.10.0",
|
"@git.zone/tsbundle": "^2.10.0",
|
||||||
|
"@git.zone/tsdocker": "^2.2.4",
|
||||||
"@git.zone/tsrust": "^1.3.2",
|
"@git.zone/tsrust": "^1.3.2",
|
||||||
"@git.zone/tswatch": "^3.3.2",
|
"@git.zone/tswatch": "^3.3.2",
|
||||||
"@types/ws": "^8.18.1"
|
"@types/ws": "^8.18.1"
|
||||||
|
|||||||
650
pnpm-lock.yaml
generated
650
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: 'siprouter',
|
name: 'siprouter',
|
||||||
version: '1.19.2',
|
version: '1.20.0',
|
||||||
description: 'undefined'
|
description: 'undefined'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,8 +134,22 @@ let logFn: ((msg: string) => void) | undefined;
|
|||||||
|
|
||||||
function buildLocalPaths(): string[] {
|
function buildLocalPaths(): string[] {
|
||||||
const root = process.cwd();
|
const root = process.cwd();
|
||||||
|
// Map Node's process.arch to tsrust's friendly target name.
|
||||||
|
// tsrust writes multi-target binaries as <bin>_<os>_<arch>,
|
||||||
|
// e.g. proxy-engine_linux_amd64 / proxy-engine_linux_arm64.
|
||||||
|
const archSuffix =
|
||||||
|
process.arch === 'arm64' ? 'linux_arm64' :
|
||||||
|
process.arch === 'x64' ? 'linux_amd64' :
|
||||||
|
null;
|
||||||
|
const multiTarget = archSuffix
|
||||||
|
? [path.join(root, 'dist_rust', `proxy-engine_${archSuffix}`)]
|
||||||
|
: [];
|
||||||
return [
|
return [
|
||||||
|
// 1. Multi-target output matching the running host arch (Docker image, CI, multi-target dev).
|
||||||
|
...multiTarget,
|
||||||
|
// 2. Single-target (unsuffixed) output — legacy/fallback when tsrust runs without targets.
|
||||||
path.join(root, 'dist_rust', 'proxy-engine'),
|
path.join(root, 'dist_rust', 'proxy-engine'),
|
||||||
|
// 3. Direct cargo builds for dev iteration.
|
||||||
path.join(root, 'rust', 'target', 'release', 'proxy-engine'),
|
path.join(root, 'rust', 'target', 'release', 'proxy-engine'),
|
||||||
path.join(root, 'rust', 'target', 'debug', 'proxy-engine'),
|
path.join(root, 'rust', 'target', 'debug', 'proxy-engine'),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: 'siprouter',
|
name: 'siprouter',
|
||||||
version: '1.19.2',
|
version: '1.20.0',
|
||||||
description: 'undefined'
|
description: 'undefined'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user