From 0ec0fa2cfda427cd4eff9c6da8df2705c7ed0903 Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Sun, 28 Jun 2026 15:05:17 +0800 Subject: [PATCH] feat: add Roundcube app (#4365) --- apps/roundcube/README.md | 64 ++++++++ apps/roundcube/data.yml | 31 ++++ apps/roundcube/latest/.env.sample | 11 ++ apps/roundcube/latest/data.yml | 167 +++++++++++++++++++++ apps/roundcube/latest/docker-compose.yml | 37 +++++ apps/roundcube/latest/scripts/init.sh | 7 + apps/roundcube/latest/scripts/uninstall.sh | 2 + apps/roundcube/latest/scripts/upgrade.sh | 3 + apps/roundcube/logo.png | Bin 0 -> 3090 bytes apps/roundcube/source-evidence.json | 14 ++ 10 files changed, 336 insertions(+) create mode 100644 apps/roundcube/README.md create mode 100644 apps/roundcube/data.yml create mode 100644 apps/roundcube/latest/.env.sample create mode 100644 apps/roundcube/latest/data.yml create mode 100644 apps/roundcube/latest/docker-compose.yml create mode 100755 apps/roundcube/latest/scripts/init.sh create mode 100755 apps/roundcube/latest/scripts/uninstall.sh create mode 100755 apps/roundcube/latest/scripts/upgrade.sh create mode 100644 apps/roundcube/logo.png create mode 100644 apps/roundcube/source-evidence.json diff --git a/apps/roundcube/README.md b/apps/roundcube/README.md new file mode 100644 index 000000000..6e330809b --- /dev/null +++ b/apps/roundcube/README.md @@ -0,0 +1,64 @@ +# Roundcube + +## 产品介绍 +Roundcube 是一个开源 Webmail 客户端,可通过浏览器连接已有的 IMAP/SMTP 邮件服务器收发邮件。 + +## 主要功能 +- 通过浏览器访问 IMAP 邮箱 +- 使用外部 SMTP 服务器发送邮件 +- 支持内置插件、主题和自定义配置 +- 使用本地 SQLite 保存 Webmail 元数据 + +## 访问说明 +安装后通过 `http://<服务器 IP>:18090` 访问,实际端口以安装表单中的 `PANEL_APP_PORT_HTTP` 为准。 + +## Introduction +Roundcube is an open source Webmail client for accessing an existing IMAP and SMTP mail server from a browser. + +## Features +- Browser-based IMAP mail access +- Send mail through an external SMTP server +- Built-in plugins, themes and custom configuration support +- Local SQLite metadata storage + +## 部署说明 +- 本应用使用官方 Docker 镜像 `roundcube/roundcubemail:1.7.1-apache-nonroot`。 +- 应用分类:邮件服务。 +- 支持架构:amd64、arm64。 +- Roundcube 只是 Webmail 客户端,不包含邮件服务器。请先准备可用的 IMAP/SMTP 服务,例如已有邮箱服务或应用商店中的 Maddy Mail Server。 + +## 端口 +| 变量 | 说明 | 默认值 | 必填 | +| --- | --- | --- | --- | +| PANEL_APP_PORT_HTTP | Web 访问端口 | 18090 | 是 | + +## 数据持久化 +| 变量 | 说明 | 默认值 | 必填 | +| --- | --- | --- | --- | +| APP_DATA_DIR | SQLite 数据库、自定义配置和 Enigma 插件数据目录 | ./data | 是 | + +升级或迁移前,请先在 1Panel 中备份上述数据目录。 + +## 参数说明 +| 变量 | 说明 | 默认值 | 必填 | +| --- | --- | --- | --- | +| ROUNDCUBEMAIL_DEFAULT_HOST | IMAP 主机,可使用 `tls://` 或 `ssl://` 前缀 | ssl://mail.example.com | 是 | +| ROUNDCUBEMAIL_DEFAULT_PORT | IMAP 端口 | 993 | 是 | +| ROUNDCUBEMAIL_SMTP_SERVER | SMTP 主机,可使用 `tls://` 或 `ssl://` 前缀 | tls://mail.example.com | 是 | +| ROUNDCUBEMAIL_SMTP_PORT | SMTP 端口 | 587 | 是 | +| ROUNDCUBEMAIL_USERNAME_DOMAIN | 登录用户名自动补全域名,留空表示不补全 | 空 | 否 | +| ROUNDCUBEMAIL_REQUEST_PATH | 反向代理子路径 | / | 是 | +| ROUNDCUBEMAIL_PLUGINS | 启用的内置插件列表 | archive,zipdownload | 是 | +| ROUNDCUBEMAIL_DES_KEY | Roundcube 加密密钥,安装后不要随意修改 | 随机生成 | 是 | + +## 使用说明 +- 如果 IMAP/SMTP 使用隐式 TLS,主机通常写成 `ssl://mail.example.com`,端口使用 `993` 或 `465`。 +- 如果 IMAP/SMTP 使用 STARTTLS,主机通常写成 `tls://mail.example.com`,端口使用 `143` 或 `587`。 +- `ROUNDCUBEMAIL_DES_KEY` 会影响 Roundcube 保存的加密数据,迁移或重建容器时应保持不变。 +- 自定义 Roundcube 配置可放入数据目录的 `config` 子目录,文件名需以 `.php` 结尾。 + +## 参考资料 +- 官网: +- 项目仓库: +- 官方 Docker 镜像文档: +- 官方镜像: diff --git a/apps/roundcube/data.yml b/apps/roundcube/data.yml new file mode 100644 index 000000000..c6d2d8b5d --- /dev/null +++ b/apps/roundcube/data.yml @@ -0,0 +1,31 @@ +name: Roundcube +tags: + - 邮件服务 +title: 现代 Webmail 客户端 +description: 现代 Webmail 客户端 +additionalProperties: + key: roundcube + name: Roundcube + tags: + - Email + shortDescZh: 现代 Webmail 客户端 + shortDescEn: Modern Webmail client + description: + en: A browser-based IMAP Webmail client for existing mail servers. + zh: 面向已有邮件服务器的浏览器 IMAP Webmail 客户端。 + zh-Hant: 面向既有郵件伺服器的瀏覽器 IMAP Webmail 用戶端。 + ja: 既存のメールサーバー向けのブラウザベース IMAP Webmail クライアントです。 + ko: 기존 메일 서버용 브라우저 기반 IMAP Webmail 클라이언트입니다. + ru: Браузерный IMAP Webmail-клиент для существующих почтовых серверов. + ms: Klien Webmail IMAP berasaskan pelayar untuk pelayan mel sedia ada. + pt-br: Cliente Webmail IMAP baseado em navegador para servidores de e-mail existentes. + type: website + crossVersionUpdate: false + limit: 0 + recommend: 0 + website: https://roundcube.net/ + github: https://github.com/roundcube/roundcubemail + document: https://github.com/roundcube/roundcubemail-docker + architectures: + - amd64 + - arm64 diff --git a/apps/roundcube/latest/.env.sample b/apps/roundcube/latest/.env.sample new file mode 100644 index 000000000..aa77398f2 --- /dev/null +++ b/apps/roundcube/latest/.env.sample @@ -0,0 +1,11 @@ +PANEL_APP_PORT_HTTP=18090 +APP_DATA_DIR=./data +ROUNDCUBEMAIL_DEFAULT_HOST=ssl://mail.example.com +ROUNDCUBEMAIL_DEFAULT_PORT=993 +ROUNDCUBEMAIL_SMTP_SERVER=tls://mail.example.com +ROUNDCUBEMAIL_SMTP_PORT=587 +ROUNDCUBEMAIL_USERNAME_DOMAIN= +ROUNDCUBEMAIL_REQUEST_PATH=/ +ROUNDCUBEMAIL_PLUGINS=archive,zipdownload +ROUNDCUBEMAIL_DES_KEY=roundcube_des_key_change +CONTAINER_NAME=roundcube diff --git a/apps/roundcube/latest/data.yml b/apps/roundcube/latest/data.yml new file mode 100644 index 000000000..468ea82ea --- /dev/null +++ b/apps/roundcube/latest/data.yml @@ -0,0 +1,167 @@ +additionalProperties: + formFields: + - default: 18090 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Web Port + labelZh: Web 端口 + label: + en: Web Port + zh: Web 端口 + zh-Hant: Web 埠 + ja: Web ポート + ko: Web 포트 + ru: Web-порт + ms: Port Web + pt-br: Porta Web + required: true + rule: paramPort + type: number + - default: ./data + edit: true + envKey: APP_DATA_DIR + labelEn: Data Directory + labelZh: 数据目录 + label: + en: Data Directory + zh: 数据目录 + zh-Hant: 資料目錄 + ja: データディレクトリ + ko: 데이터 디렉터리 + ru: Каталог данных + ms: Direktori data + pt-br: Diretorio de dados + required: true + type: text + - default: ssl://mail.example.com + edit: true + envKey: ROUNDCUBEMAIL_DEFAULT_HOST + labelEn: IMAP Host + labelZh: IMAP 主机 + label: + en: IMAP Host + zh: IMAP 主机 + zh-Hant: IMAP 主機 + ja: IMAP ホスト + ko: IMAP 호스트 + ru: IMAP-хост + ms: Hos IMAP + pt-br: Host IMAP + required: true + type: text + - default: 993 + edit: true + envKey: ROUNDCUBEMAIL_DEFAULT_PORT + labelEn: IMAP Port + labelZh: IMAP 端口 + label: + en: IMAP Port + zh: IMAP 端口 + zh-Hant: IMAP 埠 + ja: IMAP ポート + ko: IMAP 포트 + ru: IMAP-порт + ms: Port IMAP + pt-br: Porta IMAP + required: true + rule: paramPort + type: number + - default: tls://mail.example.com + edit: true + envKey: ROUNDCUBEMAIL_SMTP_SERVER + labelEn: SMTP Host + labelZh: SMTP 主机 + label: + en: SMTP Host + zh: SMTP 主机 + zh-Hant: SMTP 主機 + ja: SMTP ホスト + ko: SMTP 호스트 + ru: SMTP-хост + ms: Hos SMTP + pt-br: Host SMTP + required: true + type: text + - default: 587 + edit: true + envKey: ROUNDCUBEMAIL_SMTP_PORT + labelEn: SMTP Port + labelZh: SMTP 端口 + label: + en: SMTP Port + zh: SMTP 端口 + zh-Hant: SMTP 埠 + ja: SMTP ポート + ko: SMTP 포트 + ru: SMTP-порт + ms: Port SMTP + pt-br: Porta SMTP + required: true + rule: paramPort + type: number + - default: "" + edit: true + envKey: ROUNDCUBEMAIL_USERNAME_DOMAIN + labelEn: Login Domain + labelZh: 登录域名 + label: + en: Login Domain + zh: 登录域名 + zh-Hant: 登入網域 + ja: ログインドメイン + ko: 로그인 도메인 + ru: Домен входа + ms: Domain log masuk + pt-br: Dominio de login + required: false + type: text + - default: / + edit: true + envKey: ROUNDCUBEMAIL_REQUEST_PATH + labelEn: Request Path + labelZh: 请求路径 + label: + en: Request Path + zh: 请求路径 + zh-Hant: 請求路徑 + ja: リクエストパス + ko: 요청 경로 + ru: Путь запроса + ms: Laluan permintaan + pt-br: Caminho de requisicao + required: true + type: text + - default: archive,zipdownload + edit: true + envKey: ROUNDCUBEMAIL_PLUGINS + labelEn: Built-in Plugins + labelZh: 内置插件 + label: + en: Built-in Plugins + zh: 内置插件 + zh-Hant: 內建外掛 + ja: 組み込みプラグイン + ko: 기본 제공 플러그인 + ru: Встроенные плагины + ms: Pemalam terbina dalam + pt-br: Plugins integrados + required: true + type: text + - default: roundcube_des_key_change + edit: true + envKey: ROUNDCUBEMAIL_DES_KEY + labelEn: Encryption Key + labelZh: 加密密钥 + label: + en: Encryption Key + zh: 加密密钥 + zh-Hant: 加密金鑰 + ja: 暗号化キー + ko: 암호화 키 + ru: Ключ шифрования + ms: Kunci penyulitan + pt-br: Chave de criptografia + random: true + required: true + rule: paramComplexity + type: password diff --git a/apps/roundcube/latest/docker-compose.yml b/apps/roundcube/latest/docker-compose.yml new file mode 100644 index 000000000..684953d0c --- /dev/null +++ b/apps/roundcube/latest/docker-compose.yml @@ -0,0 +1,37 @@ +services: + roundcube: + image: "roundcube/roundcubemail:1.7.1-apache-nonroot" + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:8000" + environment: + - ROUNDCUBEMAIL_DB_TYPE=sqlite + - ROUNDCUBEMAIL_DB_DIR=/var/roundcube/db + - ROUNDCUBEMAIL_DB_NAME=roundcube + - ROUNDCUBEMAIL_DEFAULT_HOST=${ROUNDCUBEMAIL_DEFAULT_HOST} + - ROUNDCUBEMAIL_DEFAULT_PORT=${ROUNDCUBEMAIL_DEFAULT_PORT} + - ROUNDCUBEMAIL_SMTP_SERVER=${ROUNDCUBEMAIL_SMTP_SERVER} + - ROUNDCUBEMAIL_SMTP_PORT=${ROUNDCUBEMAIL_SMTP_PORT} + - ROUNDCUBEMAIL_USERNAME_DOMAIN=${ROUNDCUBEMAIL_USERNAME_DOMAIN} + - ROUNDCUBEMAIL_REQUEST_PATH=${ROUNDCUBEMAIL_REQUEST_PATH} + - ROUNDCUBEMAIL_PLUGINS=${ROUNDCUBEMAIL_PLUGINS} + - ROUNDCUBEMAIL_SKIN=elastic + - ROUNDCUBEMAIL_DES_KEY=${ROUNDCUBEMAIL_DES_KEY} + volumes: + - "${APP_DATA_DIR}/db:/var/roundcube/db" + - "${APP_DATA_DIR}/config:/var/roundcube/config:ro" + - "${APP_DATA_DIR}/enigma:/var/roundcube/enigma" + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8000/ >/dev/null || exit 1"] + interval: 10s + timeout: 5s + retries: 10 + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/roundcube/latest/scripts/init.sh b/apps/roundcube/latest/scripts/init.sh new file mode 100755 index 000000000..0baabc162 --- /dev/null +++ b/apps/roundcube/latest/scripts/init.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +DATA_DIR="${APP_DATA_DIR:-./data}" +mkdir -p "${DATA_DIR}/db" "${DATA_DIR}/config" "${DATA_DIR}/enigma" +chown -R 33:33 "${DATA_DIR}/db" "${DATA_DIR}/enigma" 2>/dev/null || true +chmod 755 "${DATA_DIR}/config" 2>/dev/null || true diff --git a/apps/roundcube/latest/scripts/uninstall.sh b/apps/roundcube/latest/scripts/uninstall.sh new file mode 100755 index 000000000..ab8a8d674 --- /dev/null +++ b/apps/roundcube/latest/scripts/uninstall.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker-compose down --volumes diff --git a/apps/roundcube/latest/scripts/upgrade.sh b/apps/roundcube/latest/scripts/upgrade.sh new file mode 100755 index 000000000..9879df4c3 --- /dev/null +++ b/apps/roundcube/latest/scripts/upgrade.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -euo pipefail +exit 0 diff --git a/apps/roundcube/logo.png b/apps/roundcube/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b37854589b8df9649ebc8e28c64d191380f8f9af GIT binary patch literal 3090 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