Skip to content
lisaacPublic

About

轻量 Docker (compose) manager

Topics

Resources

Stars

29 stars

Watchers

0 watching

Forks

Repository files navigation

phyless

轻量的自托管 Docker 管理面板:一个二进制,无需任何依赖。

整个程序就是一个约 36 MB 的静态可执行文件(压缩后约 15 MB),网页前端和 Compose 引擎都编译在里面。不需要数据库、运行时或额外的库,也不需要安装 docker CLI 或 docker compose。只要机器上有 Docker Engine,下载后直接运行即可。

在线演示 · Docker 镜像 · 下载二进制

在线演示只展示界面,数据是浏览器里的示例,不会连接真实 Docker。

快速开始

前提:服务器上已运行 Docker Engine,除此之外不需要任何东西。

用容器运行:

docker volume create phyless-data
docker run -d \
  --name phyless \
  --restart unless-stopped \
  -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v phyless-data:/data \
  ghcr.io/lisaac/phyless:latest

或者用 Compose(compose.yaml):

services:
  phyless:
    image: ghcr.io/lisaac/phyless:latest
    container_name: phyless
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - phyless-data:/data

volumes:
  phyless-data:
docker compose up -d

镜像 latest 同时包含 amd64 / arm64 / armv7 / 386,Docker 会按宿主架构自动拉取对应版本,命令无需按架构修改。

或者直接运行二进制(Linux,自动识别架构;其他平台见 Releases):

ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/;s/armv7l/armv7/;s/i.86/386/')
curl -fsSL "https://github.com/lisaac/phyless/releases/latest/download/phyless-linux-$ARCH.tar.gz" | tar -xz
sudo ./phyless-linux-$ARCH -C /var/lib/phyless

打开 http://<服务器地址>:8080,按提示为 admin 设置密码,完成。

接下来可以:

  • 在「容器」页点 创建,粘贴一条 docker run 命令即可建容器;
  • 在「Compose」页新建项目,或选择已有的 Compose YAML 文件注册(容器部署需要先挂载目录,见 管理宿主机上的 Compose 项目);
  • 服务器拉不动镜像时,在拉取对话框里选一个代理(见 使用代理拉取镜像)。

为什么用 phyless

轻量

  • 单个二进制:后端、网页和 Compose 引擎编译进同一个文件,Linux amd64 约 36 MB(压缩包约 15 MB)。容器镜像基于 scratch,里面只有这一个文件,根证书也编译在程序里。
  • 无需任何依赖:静态编译,不依赖 glibc 或其他系统库;不需要数据库,账号和配置是数据目录里的普通文件;Compose 通过内嵌的 Go API 执行,宿主机无需安装 docker 或 docker compose 命令。
  • 省内存:默认把堆内存软上限设为 128 MB,路由器、NAS、小 VPS 也跑得动(可用 GOMEMLIMIT、GOGC 环境变量调整)。
  • 部署简单:一条 docker run,或者下载二进制直接运行。

网络受限也能拉镜像

  • 每次拉取都可以临时指定代理,不用改 daemon 配置,也不用重启 Docker。
  • 服务器完全连不上镜像仓库时,可以改由浏览器经 Cloudflare Worker 下载镜像,再流式导入服务器。

迁移和升级更省事

  • docker run 命令和 compose.yaml 可以互相转换。
  • 容器可以批量检查有没有新镜像;升级时沿用原配置,失败会自动回滚。Compose 项目一键拉取并更新。

功能一览

总览

Docker 主机与版本、操作系统和内核、总内存、存储驱动与可用空间,以及容器(运行中 / 总数)、镜像、网络、存储卷数量。

容器

  • 列表:状态、端口、镜像、CPU/内存曲线;支持批量启动、停止、重启、删除。
  • 生命周期:启动、停止、重启、暂停/恢复、强制结束、重命名、删除。
  • 详情:配置(inspect)、实时日志、资源占用、进程列表(top)、网页终端(可在独立窗口打开)。没有 shell 的容器(distroless、scratch)自动进入 busybox 调试模式,不修改目标容器。
  • 文件:浏览容器内文件,上传、下载、重命名,在容器之间复制文件。运行中、已停止、没有 ls 的容器都能浏览,不会把整个文件系统传回来。详见 docs/file-browsing.md。
  • 创建:表单或直接粘贴 docker run 命令;可把常用命令保存为模板;随时查看任意容器对应的 docker run 命令或 compose.yaml。
  • 复制、导出与导入容器。
  • 检查升级 / 升级:单个或批量;显示本地与远端 digest;升级失败自动回滚。详见 docs/container-upgrade.md。
  • 管理 phyless 自身容器:升级、Compose 重建等会停掉自己的操作交给一次性的 phyless-helper 容器完成;停止、删除、重启自身前先确认,暂停自身被拒绝。详见 docs/self-update.md。

Compose

  • 新建项目时在当前服务器的 Compose 存储目录(默认 /srv)下创建同名目录;也可选择已有 YAML 文件注册。自动发现存储目录中的项目及正在运行但未注册的项目。
  • 查看项目下的服务与容器状态。
  • 在线编辑 compose.yaml 及项目目录内的其他文件(上传、下载、重命名)。
  • 操作:Up、Down、Stop、Restart、Pause、Pull、Build、Update(拉取并重建);输出以流式日志显示在任务抽屉中。
  • Build 仅对含 build: 的项目显示,浏览器代理模式下会先预拉 Dockerfile 的 FROM 镜像。详见 docs/compose-build.md。

镜像

  • 拉取(可选代理)、上传 tar 导入、导出为 tar。
  • 打标签 / 删除标签、删除镜像、清理悬空镜像。
  • 查看详情、构建历史(history),浏览镜像内文件并下载。

网络与存储卷

  • 网络:创建、删除、查看详情,把容器连入或断开网络。
  • 存储卷:创建、删除(带确认)、查看详情,浏览卷内文件。

事件

实时查看 Docker 事件,默认显示最近 1 小时;可按时间范围、事件类型筛选,并按名称 / 动作 / 镜像搜索。

本机配置

浏览和编辑 phyless 所在环境的配置文件(如 /etc)。容器部署时看到的是容器内的文件系统,不是宿主机。

设置(仅管理员)

页面 作用
Docker 连接 管理多个 Docker 主机:本机 socket、unix:///path/to/docker.sock 或 tcp://host:2375,可配置 TLS 证书(CA / Cert / Key),随时切换当前主机。
用户管理 创建账号并分配角色:admin(全部权限)、operator(可执行操作)、viewer(只读)。
审计日志 记录谁在什么时间执行了什么操作。

其他

  • 所有写操作进入全局任务队列,在右侧任务抽屉查看进度、日志或取消。
  • 适配手机浏览器;支持日间 / 夜间主题。

部署

phyless 需要访问 Docker Socket,并把数据(账号、JWT 密钥、配置、审计日志)存放在一个目录里。下面三种方式任选其一。

方式一:Docker 容器(推荐)

见 快速开始。镜像基于 Alpine,里面只有 phyless 二进制和 CA 证书;数据保存在 phyless-data 卷的 /data 下。latest 为多架构镜像(amd64 / arm64 / armv7 / 386),docker pull 会按宿主架构自动选择;也可直接指定 latest-amd64、latest-arm64、latest-armv7、latest-386。

升级 phyless:

docker pull ghcr.io/lisaac/phyless:latest
docker rm -f phyless

然后重新执行快速开始中的 docker run 命令。phyless-data 卷会保留,账号和配置不会丢失。

常用命令:

docker logs -f phyless       # 查看日志
docker restart phyless       # 重启,不影响数据
docker rm -f phyless         # 删除容器,phyless-data 卷仍保留

方式二:直接运行二进制

适合不想多跑一个容器的机器。Releases 提供 Linux amd64 / arm64 / armv7 / 386、macOS arm64、Windows amd64 版本,其他平台请自行构建。以下命令自动识别 Linux 架构。

ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/;s/armv7l/armv7/;s/i.86/386/')
curl -fsSL "https://github.com/lisaac/phyless/releases/latest/download/phyless-linux-$ARCH.tar.gz" | tar -xz
sudo install "phyless-linux-$ARCH" /usr/local/bin/phyless
sudo phyless -C /var/lib/phyless

-C 指定数据目录。运行用户需要能读写 /var/run/docker.sock,也就是 root 或 docker 组成员。直接运行时,phyless 能看到宿主机上的 Compose 目录和 /etc,不需要额外挂载。

作为 systemd 服务常驻:

# /etc/systemd/system/phyless.service
[Unit]
Description=phyless
After=docker.service
Requires=docker.service

[Service]
ExecStart=/usr/local/bin/phyless -C /var/lib/phyless
Restart=on-failure

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now phyless

升级时替换 /usr/local/bin/phyless,然后执行 sudo systemctl restart phyless。

方式三:Docker Compose(从源码构建)

在仓库根目录执行:

docker compose up -d --build

compose.yaml 用本地源码构建镜像,把 ./data 挂载到 /data,把宿主机 /srv 挂载到容器内同一路径,并挂载 Docker Socket。更新代码后重新执行同一条命令即可。data/ 已被 Git 和构建上下文忽略,不要提交。

管理宿主机上的 Compose 项目

直接运行二进制时不需要这一步。以容器方式运行时,Docker Socket 只提供 Docker API,不会把宿主机的 Compose 文件带进容器。需要把项目目录以相同的绝对路径挂载进 phyless:

docker run -d \
  --name phyless \
  --restart unless-stopped \
  -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v phyless-data:/data \
  -v /srv:/srv \
  ghcr.io/lisaac/phyless:latest

Compose 部署时在 compose.yaml 中加同样的挂载:

services:
  phyless:
    volumes:
      - /srv:/srv

然后可在「Compose」页新建项目,生成 /srv/<项目>/compose.yaml,或选择已有 YAML 文件注册。可在「Docker 连接」中修改每台服务器的 Compose 存储目录;容器部署时需要把该目录以相同的绝对路径挂载进 phyless,否则相对路径的 build:、volumes:、env_file 会解析到错误位置。

管理远程 Docker 主机

在「设置 → Docker 连接」添加 tcp://<主机>:2375(或启用 TLS 并填写证书),保存后切换即可。远程主机需要自行开放 Docker API,务必配 TLS 或限定内网访问。

也可以填 unix:///path/to/docker.sock 连接非默认位置的 Socket,例如 rootless Docker 的 unix:///run/user/1000/docker.sock,或经 SSH 转发来的远程 Socket(见 作为客户端使用)。

部署参数

项目 默认值 说明
端口 8080 用 -p <宿主端口>:8080 修改对外端口。
数据目录 /data 启动参数 -C <目录> 可修改。
内存上限 128 MB(软上限) 环境变量 GOMEMLIMIT(如 256MiB)、GOGC 可覆盖。
Docker Socket /var/run/docker.sock 管理本机 Docker 必需。

公网访问请放在 HTTPS 反向代理之后(见 安全须知)。

作为客户端使用

phyless 不要求和 Docker 跑在同一台机器上。在自己的电脑(macOS / Windows / Linux 桌面)上运行它,当作本地客户端,通过「设置 → Docker 连接」管理一台或多台远程 Docker 主机,服务器上什么都不用装。

1. 下载并运行

从 Releases 下载对应平台的文件:

平台 文件
macOS(Apple Silicon) phyless-darwin-arm64.tar.gz
Windows x64 phyless-windows-amd64.zip
Linux x64 / arm64 / armv7 / x86 phyless-linux-amd64.tar.gz / phyless-linux-arm64.tar.gz / phyless-linux-armv7.tar.gz / phyless-linux-386.tar.gz

macOS:

curl -fsSL https://github.com/lisaac/phyless/releases/latest/download/phyless-darwin-arm64.tar.gz | tar -xz
xattr -d com.apple.quarantine phyless-darwin-arm64 2>/dev/null; ./phyless-darwin-arm64 -C ~/.phyless

Windows(PowerShell,解压 zip 后):

.\phyless-windows-amd64.exe -C $env:USERPROFILE\.phyless

然后在浏览器打开 http://localhost:8080,按提示设置 admin 密码。

phyless 监听所有网卡的 8080 端口,同一局域网的机器也能访问。在不可信网络中请用防火墙限制,或只在需要时运行。

2. 连接 Docker

在「设置 → Docker 连接」添加服务器,地址三选一:

地址 场景
留空 本机的 Docker Desktop / OrbStack / Colima 等(读取 DOCKER_HOST 或默认 Socket)
unix:///path/to/docker.sock 指定本机 Socket,如 Colima 的 unix:///Users/<你>/.colima/default/docker.sock;也可以是 SSH 转发来的远程 Socket(macOS / Linux)
tcp://<主机>:2376 + TLS 远程主机开放了 Docker API(建议配 TLS 证书)

通过 SSH 连接远程主机(远程无需开放 Docker API 端口,macOS / Linux):把远程 Socket 转发成本地文件

ssh -nNT -L /tmp/docker-myserver.sock:/var/run/docker.sock user@myserver

然后添加 unix:///tmp/docker-myserver.sock。SSH 用户需要能访问远程的 Docker Socket(root 或 docker 组)。重新建立转发前先删除旧的 /tmp/docker-myserver.sock。

添加多台服务器后,在列表中随时切换。

客户端模式下,「Compose」页注册项目、编辑 compose.yaml 和「本机配置」操作的是运行 phyless 的这台电脑上的文件,而不是远程主机;Compose 的 build: 上下文也从本机读取。容器、镜像、网络、存储卷等则都在远程 Docker 上。

使用代理拉取镜像

代理只对当前这次操作生效。镜像拉取、Compose 的 Pull / Up / Build / Update、容器升级与检查升级的对话框里都能选择:

方式 适用场景 要求
服务端代理 服务器能访问某个代理 HTTP / HTTPS / SOCKS5 地址,需能从 phyless 容器内访问
浏览器代理导入 服务器完全连不上镜像仓库 部署一个 Cloudflare Worker

浏览器代理:三步配置

1. 部署 Worker

Worker 源码是 cloudflare-worker/registry-proxy.js,二选一:

  • 控制台:打开 Cloudflare 创建 Worker,选择 Create Worker → Deploy,把脚本完整粘贴进编辑器后再次部署。参考 Dashboard 部署文档。

  • 命令行(需要 Node.js):在仓库根目录执行

    npx wrangler login
    npx wrangler deploy cloudflare-worker/registry-proxy.js --name phyless-registry-proxy --compatibility-date 2024-11-01

部署后在 Worker 概览页复制地址 https://<name>.<subdomain>.workers.dev。

2. 配置白名单

在 Worker 的 Settings → Variables and Secrets 添加变量并重新部署:

变量 示例 作用
ALLOWED_ORIGINS https://phyless.example.com 允许调用 Worker 的 phyless 网址,多个用逗号分隔;不带路径和结尾 /。
UPSTREAM_ALLOWLIST 见下 允许访问的镜像仓库域名,按实际使用收紧。
ALLOW_ANY_UPSTREAMS false 是否允许任意上游,生产环境保持 false。
ALLOW_MISSING_ORIGIN false 是否接受无 Origin 的请求,保持 false。

UPSTREAM_ALLOWLIST 常用取值:

# Docker Hub + GHCR
registry-1.docker.io,auth.docker.io,hub.docker.com,*.docker.io,*.docker.com,ghcr.io,lscr.io,*.githubusercontent.com

# 仅 Docker Hub
registry-1.docker.io,auth.docker.io,hub.docker.com,*.docker.io,*.docker.com

# 仅 GHCR
ghcr.io,lscr.io,*.githubusercontent.com

Quay、GCR、registry.k8s.io、MCR、ECR Public、GitLab 等其他仓库的镜像层会重定向到各自的 CDN 域名,取值见 cloudflare-worker/README.md。

完整变量说明见 cloudflare-worker/README.md。

3. 在 phyless 中使用

  1. 打开任一拉取 / 升级对话框,选择 浏览器代理导入;
  2. 填入 Worker 地址,如 https://phyless-registry-proxy.example.workers.dev(无需手动拼 ?url=);
  3. 在「前端代理仓库账号」中按 registry 选用账号:可以是只存在当前浏览器的账号,也可以是 phyless 服务端保存的账号(选用时临时取用、不写入浏览器)。每个镜像只会使用其所在 registry 选中的账号;“记住凭据”只把浏览器账号存在当前浏览器的 localStorage。
  4. 拉取对话框点「搜索远程镜像」可搜索 Docker Hub,或输入完整仓库名(如 ghcr.io/owner/app)查看标签。搜索与拉取方式一致:「不使用代理」由 phyless 服务端直接访问,「服务端代理」经所选代理访问,「浏览器代理导入」经 Worker 访问并使用 docker.io 账号登录。Worker 出口 IP 为共享 IP,Docker Hub API 按 IP 限额,频繁 429 时建议改用服务端方式;标签查询遇到 429 会自动改用 registry 接口(仅标签名)。
  5. 仓库账号直接在拉取对话框里管理,按 registry 分组、每组单选一个账号(或匿名):「不使用代理 / 服务端代理」下是服务端仓库账号(加密保存在 phyless 服务端、所有用户共享),「浏览器代理导入」下是前端代理仓库账号。两者都可一键验证,验证走与拉取相同的网络路径。
  6. 「平台」默认即 Docker daemon 所在平台(含 ARM 变体,如 linux/arm/v7),与 docker pull 的自动选择一致;手动指定时两种代理都严格按指定平台拉取。GHCR 等非 Docker Hub 仓库的标签会读取 manifest 补全更新时间、大小、架构和仓库描述。

限制:只支持 Linux 平台的 tag 镜像,不支持 digest 引用和 foreign layer;Compose Build 只预拉 Dockerfile 中能静态解析的 FROM 镜像。Worker 只处理 GET / HEAD / OPTIONS 和发往白名单上游的小 POST(registry API 登录),不保存镜像内容。详细设计见 docs/pull-and-registry-accounts.md。搜索需白名单包含 hub.docker.com;添加 docker.io 账号后由 phyless 服务端登录换取 JWT(服务端连不上 Hub 时改经 Worker),搜索按账号额度进行。

本地开发

需要 Go(版本见 go.mod)和 Node.js。

./build.sh                          # 构建前端并嵌入,产出 ./phyless
./phyless -C ./data                 # 启动后端,监听 :8080
cd frontend && npm install && npm run dev   # 前端热更新,/api 代理到 localhost:8080

测试:go test ./...、cd frontend && npm test。

安全须知

  • 挂载 Docker Socket 等同于授予宿主机 root 级权限,只向可信用户开放。
  • 公网访问务必放在 HTTPS 反向代理之后。
  • /data(phyless-data 卷或 ./data)保存 JWT 密钥、账号和审计日志:定期备份,不要公开或提交到 Git。
  • 给日常使用者分配 operator 或 viewer 角色,admin 只留给管理者。

许可证

本项目基于 MIT License 发布。

第三方组件

phyless 内嵌了 BusyBox 1.37.0 的静态可执行文件(来自 Alpine busybox-static 1.37.0-r31,amd64 / arm64 / arm / 386),只在 phyless 创建的辅助容器里运行,用于无 shell 终端和文件浏览,不与 phyless 链接。BusyBox 以 GPL-2.0-only 授权,不影响 phyless 本身的 MIT 许可证。来源、校验值和对应源码见 busybox-NOTICE.md:每个 Release 都附带上游源码包和 Alpine 的构建脚本,发布包和容器镜像的 licenses/ 目录里都有许可证文本。

About

轻量 Docker (compose) manager

Topics

Resources

Stars

29 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages