Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 35 additions & 24 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,39 @@

jobs:
## Clash
docker_clash:
name: "app-clash"
job-clash:
name: "clash"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && build_image app-clash latest docker_clash/clash.Dockerfile && push_image clash
source ./tool.sh && build_image clash latest docker_clash/clash.Dockerfile && push_image clash

## Selkies
job-gui-linux:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Comment on lines +33 to +41
name: "gui-linux"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: |
source ./tool.sh && build_image gui-linux latest docker_gui/gui_linux.Dockerfile && push_image gui


## Casdoor
docker_casdoor:
job-casdoor:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Comment on lines +42 to +51
name: "casdoor"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && build_image casdoor latest docker_casdoor/casdoor.Dockerfile && push_image casdoor

## Keycloak
docker_keycloak:
job-keycloak:
name: "keycloak"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && build_image keycloak latest docker_keycloak/keycloak.Dockerfile && push_image keycloak

Expand All @@ -60,7 +70,7 @@
name: "dev-hub"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh
build_image dev-hub latest docker_devbox/hub.Dockerfile \
Expand All @@ -72,7 +82,7 @@
name: "dev-hub-traefik"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh
build_image dev-hub-traefik latest docker_devbox/hub.Dockerfile \
Expand All @@ -86,7 +96,7 @@
name: "openresty"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && build_image openresty latest docker_openresty/openresty.Dockerfile && push_image openresty

Expand All @@ -95,7 +105,7 @@
name: "searxng"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && build_image searxng latest docker_searxng/searxng.Dockerfile && push_image searxng

Expand All @@ -104,7 +114,7 @@
name: "storebox"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh
build_image storebox latest docker_storebox/storebox.Dockerfile && push_image storebox
Expand All @@ -114,7 +124,7 @@
name: "logent"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh
build_image logent latest docker_logent/logent.Dockerfile && push_image logent
Expand All @@ -124,7 +134,7 @@
name: "nocobase"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh
build_image nocobase latest docker_nocobase/nocobase.Dockerfile && push_image nocobase
Expand All @@ -134,7 +144,7 @@
name: "openclaw"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh
build_image openclaw latest docker_openclaw/openclaw.Dockerfile && push_image openclaw
Expand All @@ -144,7 +154,7 @@
name: "developer,base-dev"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && free_diskspace
build_image base-dev latest docker_devbox/dev.Dockerfile \
Expand All @@ -158,7 +168,7 @@
name: "data-science-dev"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && free_diskspace
build_image data-science-dev latest docker_devbox/dev.Dockerfile \
Expand All @@ -173,7 +183,7 @@
name: "full-stack-dev"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && free_diskspace
build_image full-stack-dev latest docker_devbox/dev.Dockerfile \
Expand All @@ -188,7 +198,7 @@
name: "full-cuda,cuda-dev"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- run: |
source ./tool.sh && free_diskspace
build_image cuda-dev latest docker_devbox/dev.Dockerfile \
Expand All @@ -212,13 +222,14 @@
"job-searxng",
"job-openresty",
"job-dev-hub",
"docker_keycloak",
"docker_casdoor",
"docker_clash",
"job-keycloak",
"job-casdoor",
"job-clash",
"job-gui-linux"
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- env:
AUTH_FILE_CONTENT: ${{ secrets.AUTH_FILE_CONTENT }}
DOCKER_MIRROR_REGISTRY: ${{ vars.DOCKER_MIRROR_REGISTRY }}
Expand Down
4 changes: 2 additions & 2 deletions docker_casdoor/work/script-setup-casdoor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ setup_casdoor() {
&& mkdir -pv /opt/casdoor/web/build /opt/casdoor/conf

echo "--> Building Backend..." \
&& cd /tmp/casdoor && echo "${VER_CASDOOR}" > /tmp/casdoor/version_info.txt \
&& CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -ldflags="-w -s -X 'github.com/casdoor/casdoor/util.Version=${VER_CASDOOR}'" -o "server_linux_${ARCH}" . \
&& cd /tmp/casdoor && echo "v${VER_CASDOOR}" > /tmp/casdoor/version_info.txt \
&& CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -ldflags="-w -s -X 'github.com/casdoor/casdoor/util.Version=v${VER_CASDOOR}'" -o "server_linux_${ARCH}" . \
&& mv "./server_linux_${ARCH}" ./swagger ./docker-entrypoint.sh ./version_info.txt /opt/casdoor/ \
&& cat ./conf/app.conf | sort > /opt/casdoor/conf/app.conf \
&& ln -sf "/opt/casdoor/server_linux_${ARCH}" /opt/casdoor/server ;
Expand Down
6 changes: 3 additions & 3 deletions docker_clash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

```shell
docker run -d \
--name=app-clash \
--name=svc-clash \
-p 7890:7890 -p 9090:9090 \
-e PROXY_PROVIDER="https://subs.zeabur.app/clash" \
labnow/app-clash
-e PROXY_PROVIDER="https://raw.githubusercontent.com/snakem982/proxypool/main/source/clash-meta.yaml" \
labnow/clash
```

After the container starts, visit this page to manage proxy: http://localhost:9090/ui/ui-zashboard/
2 changes: 1 addition & 1 deletion docker_clash/clash.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ RUN set -eux \
&& echo 'export PATH=${PATH}:/opt/clash' >> /etc/profile.d/path-clash.sh \
&& ln -sf /opt/clash/clash /usr/local/bin/

ENV PROXY_PROVIDER="https://subs.zeabur.app/clash"
ENV PROXY_PROVIDER="https://raw.githubusercontent.com/snakem982/proxypool/main/source/clash-meta.yaml"
CMD ["/opt/clash/start-clash.sh"]
2 changes: 1 addition & 1 deletion docker_clash/demo/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
svc-clash:
image: docker.io/labnow/app-clash
image: docker.io/labnow/clash
container_name: svc-clash
hostname: svc-clash
restart: unless-stopped
Expand Down
113 changes: 113 additions & 0 deletions docker_gui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# GUI Linux

这个镜像用于打包 Selkies-GStreamer,把容器内的 Linux GUI 会话通过浏览器访问。
镜像只负责 GUI 串流层,默认关闭 Selkies 内置 Basic Auth,认证和鉴权建议放在上游网关、反向代理或平台侧处理。

## 构建

```bash
docker build -f docker_gui/gui_linux.Dockerfile -t labnow/gui:selkies docker_gui
```

基础镜像假设满足以下条件:

- 基于 Ubuntu。
- 已包含 Node.js 最新 LTS。
- 已包含 Python >= 3.13。

构建过程会安装 Selkies 运行期系统依赖,默认克隆 Selkies `main` 分支最新源码,并安装到 `/opt/selkies`。
默认使用源码构建方式,只保留运行期需要的 Python venv、web dashboard 产物和少量 addon 产物,构建依赖会在同一层内清理。

如需固定某个 branch、tag 或 commit,可以使用:

```bash
docker build -f docker_gui/gui_linux.Dockerfile \
--build-arg ARG_SELKIES_REF=main \
-t labnow/gui:selkies docker_gui
```

如需回退到官方 portable release 包,可以使用:

```bash
docker build -f docker_gui/gui_linux.Dockerfile \
--build-arg ARG_SELKIES_INSTALL_METHOD=release \
-t labnow/gui:selkies-release docker_gui
```

## 启动

```bash
docker run --rm -p 8080:8080 labnow/gui:selkies
```

浏览器访问:

```text
http://localhost:8080
```

默认不需要输入用户名和密码。如果确实需要启用 Selkies 内置 Basic Auth,可以显式传入:

```bash
docker run --rm -p 8080:8080 \
-e SELKIES_ENABLE_BASIC_AUTH=true \
-e SELKIES_BASIC_AUTH_USER=user \
-e SELKIES_BASIC_AUTH_PASSWORD=mypasswd \
labnow/gui:selkies
```

## 常用环境变量

| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `SELKIES_ADDR` | `0.0.0.0` | HTTP/WebSocket 监听地址。 |
| `SELKIES_PORT` | `8080` | HTTP/WebSocket 监听端口。 |
| `SELKIES_ENABLE_BASIC_AUTH` | `false` | 是否启用 Selkies 内置 Basic Auth。 |
| `SELKIES_BASIC_AUTH_USER` | 空 | Basic Auth 用户名。 |
| `SELKIES_BASIC_AUTH_PASSWORD` | 空 | Basic Auth 密码。 |
| `SELKIES_ENCODER` | `x264enc` | 视频编码器。 |
| `SELKIES_ENABLE_RESIZE` | `false` | 是否允许 Selkies 按浏览器窗口调整分辨率。 |
| `SELKIES_STUN_HOST` | `stun.l.google.com` | STUN 服务器地址。 |
| `SELKIES_STUN_PORT` | `19302` | STUN 服务器端口。 |
| `SELKIES_TURN_HOST` | 空 | TURN 服务器地址。Docker bridge、NAT 或代理场景通常需要配置。 |
| `SELKIES_TURN_PORT` | `3478` | TURN 服务器端口。 |
| `SELKIES_TURN_PROTOCOL` | `udp` | TURN 传输协议。 |
| `SELKIES_TURN_TLS` | `false` | TURN 是否启用 TLS。 |
| `SELKIES_TURN_USERNAME` | 空 | TURN 用户名。 |
| `SELKIES_TURN_PASSWORD` | 空 | TURN 密码。 |
| `SELKIES_TURN_SHARED_SECRET` | 空 | TURN shared secret,用于 HMAC 临时凭证。 |

也可以直接传递 `selkies-gstreamer-run` 参数:

```bash
docker run --rm -p 8080:8080 labnow/gui:selkies --encoder=vp8enc --enable_resize=true
```

## 关于 Connection failed

`8080` 端口只承载 Web UI 和 signaling WebSocket。Selkies 的画面、音频、输入等媒体流走 WebRTC,WebRTC 会通过 ICE 协商额外的 UDP/TCP candidate。

因此,只做 `-p 8080:8080` 时,页面可以打开,但媒体流不一定能连通。如果浏览器提示 `Connection failed`,通常不是 HTTP 端口映射失败,而是 ICE/WebRTC 连接失败。

常见处理方式:

- 本地 Linux 开发时,优先使用 `--network=host`,让浏览器能直接访问容器产生的 ICE candidate。
- Docker bridge、跨主机、NAT、反向代理、只允许暴露一个 HTTP 端口的部署,建议配置外部 TURN 服务。
- 如果不使用 TURN,需要额外开放 WebRTC 实际使用的 UDP/TCP 端口范围,并确保浏览器能路由到日志里的 candidate 地址。

外部 TURN 示例:

```bash
docker run --rm -it -p 8080:8080 \
quay.io/labnow0dev/gui-linux bash

# optional env:
-e SELKIES_TURN_PROTOCOL=tcp \
-e SELKIES_TURN_TLS=true \
-e SELKIES_TURN_HOST=turn.example.com \
-e SELKIES_TURN_PORT=443 \
-e SELKIES_TURN_USERNAME="$TURN_USERNAME" \
-e SELKIES_TURN_PASSWORD="$TURN_PASSWORD" \
```

日志中出现 `Listening on http://0.0.0.0:8080` 表示 HTTP 服务已经启动。若随后反复出现 session 建立、ICE candidate 交换、peer cleanup,通常应优先检查 TURN、网络模式或 UDP/TCP candidate 可达性。
69 changes: 69 additions & 0 deletions docker_gui/gui_linux.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Distributed under the terms of the Modified BSD License.

ARG BASE_NAMESPACE
ARG BASE_IMG_BUILD="node"
ARG BASE_IMG="base"
ARG ARG_SELKIES_INSTALL_METHOD=source
ARG ARG_SELKIES_REF=main


# Stage 1: build selkies from source
FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG_BUILD} AS builder

ARG ARG_SELKIES_INSTALL_METHOD=source
ARG ARG_SELKIES_REF=main

COPY work /opt/utils/

RUN set -eux && chmod +x /opt/utils/*.sh \
&& source /opt/utils/script-utils.sh \
&& source /opt/utils/script-setup-gui.sh \
&& install_apt /opt/utils/install_list_selkies.apt \
&& if [ "${ARG_SELKIES_INSTALL_METHOD}" = "release" ] ; then \
setup_selkies_from_release ; \
else \
export VER_SELKIES_REF="${ARG_SELKIES_REF}" ; \
setup_selkies_build_dependencies && setup_selkies_from_source ; \
fi \
&& mv /opt/utils/docker-entrypoint.sh /opt/selkies/docker-entrypoint.sh \
&& mv /opt/utils/install_list_selkies.apt /opt/selkies/ \
&& chmod +x /opt/selkies/docker-entrypoint.sh


# Stage 2: runtime image
FROM ${BASE_NAMESPACE:+$BASE_NAMESPACE/}${BASE_IMG}

LABEL maintainer="postmaster@labnow.ai"

COPY --from=builder /opt/selkies /opt/selkies

RUN set -eux && cd /opt/selkies \
&& source /opt/utils/script-utils.sh \
&& install_apt /opt/selkies/install_list_selkies.apt \
&& apt install -y build-essential cmake pkg-config libx11-dev libxext-dev libxfixes-dev libjpeg-dev libx264-dev libyuv-dev libavcodec-dev libavutil-dev libva-dev \
&& pip install --no-cache-dir --no-binary :all: pixelflux \
&& apt purge -y build-essential cmake pkg-config libx11-dev libxext-dev libxfixes-dev libjpeg-dev libx264-dev libyuv-dev libavcodec-dev libavutil-dev libva-dev \
&& pip install --no-cache-dir ./*.whl \
&& if [ -f /opt/selkies/lib/selkies_joystick_interposer.so ]; then \
ln -sf /opt/selkies/lib/selkies_joystick_interposer.so /usr/lib/selkies_joystick_interposer.so ; \
fi \
&& if [ -f /opt/selkies/lib/libudev.so.1.0.0-fake ]; then \
ln -sf /opt/selkies/lib/libudev.so.1.0.0-fake /usr/lib/libudev.so.1.0.0-fake \
&& ln -sf /opt/selkies/lib/libudev.so.1.0.0-fake /usr/lib/libudev.so.1 \
&& ln -sf /opt/selkies/lib/libudev.so.1.0.0-fake /usr/lib/libudev.so ; \
fi \
&& list_installed_packages && install__clean

ENV PATH=/opt/selkies:/opt/conda/bin:${PATH}

EXPOSE 8080
WORKDIR /opt/selkies

# '-c' option make bash commands are read from string.
# If there are arguments after the string, they are assigned to the positional parameters, starting with $0.
# '-o pipefail' prevents errors in a pipeline from being masked.
# If any command in a pipeline fails, that return code will be used as the return code of the whole pipeline.
# '--login': make bash first reads and executes commands from the file /etc/profile, if that file exists.
# After that, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.
SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"]
ENTRYPOINT ["/opt/selkies/docker-entrypoint.sh"]
Loading