Synaplan
开源 AI 软件平台,面向企业:自托管 AI 代理,符合 GDPR 的聊天机器人小部件,RAG 知识库,WhatsApp 与 Outlook AI,MCP,多模型路由。支持 Docker、Kubernetes 或在 Germ 托管。
AI 翻译
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A multi-tenant web mail service built on Cloudflare Email Service (Sending + Routing), with a Laravel + Filament admin panel and a headless Vue SPA (PWA) mailbox portal. Send and receive email on your own domains, manage routing, and give each address its own installable, push-notified inbox.
See docs/ARCHITECTURE.md for the full design.
Populated with demo data — reproduce locally with
php artisan migrate:fresh && php artisan db:seed --class=DemoSeeder(admin[email protected]/password, mailbox[email protected]/password).
Admin panel (Filament)
| Dashboard | Domains | Sent log |
|---|---|---|
Mailbox portal (Vue PWA)
| Inbox | Conversation | Calendar |
|---|---|---|
| People | Tasks | Mobile (installable PWA) |
|---|---|---|
/admin, Filament, multi-tenant — one Cloudflare account = one
tenant): one-click token onboarding, domain/address/routing-rule sync & management,
compose & sent log, inbox, inbound-Worker deploy./, Vue SPA + PWA): per-address login (email + password),
native-feeling inbox, compose, and Web Push "new mail" notifications — installable
on Android & iOS.cf/) parses inbound mail and posts
it to a signed webhook; Laravel stores it and pushes a notification.mailserver/, shipped as the ready-to-deploy
docker-compose.native.yaml) plus CalDAV/CardDAV
served at /dav and mail-client autodiscovery, so Apple Mail / Outlook /
Thunderbird and native calendar & contacts can connect. See
Native mail apps below.wrangler are needed to deploy the Worker)composer install
cp .env.example .env
php artisan key:generate
touch database/database.sqlite
php artisan migrate --seed # seeds [email protected] / password
php artisan webpush:vapid # VAPID keys for Web Push
npm install
npm run build # or: npm run dev
php artisan serve
http://localhost:8000/admin ([email protected] / password)http://localhost:8000/In the admin panel, add a Cloudflare account (tenant). Click "Cloudflare token oluştur" — it opens Cloudflare's token page with the exact permissions pre-selected (Email Routing: Edit, Email Sending: Edit, Zone: Read). Create the token, paste it, and the app auto-detects your account. Then Full Sync, then Deploy Worker.
The inbound Email Worker lives in cf/ and is deployed from Laravel:
php artisan cf:deploy-worker {tenant} # render wrangler.toml + deploy + set secret
php artisan cf:worker:status # up-to-date / drifted / never deployed
php artisan cf:worker:sync # redeploy drifted tenants (idempotent)
Everything above is a self-contained web app. This section is entirely optional — the plain Laravel deploy runs fine without any of it, and none of it is enabled by default. Turn it on only if you also want to reach your mailboxes from native clients.
CalDAV and CardDAV are HTTP-based, so Laravel serves them itself at /dav (via
sabre/dav) — no extra ports, no Docker, behind the same Coolify/Cloudflare HTTPS.
Enable with:
MAIL_CLIENT_DAV=true
Each mailbox then syncs its calendar (the events table) and contacts to iOS/macOS
(native Calendar/Contacts) and Android (via the DAVx5 app). RFC 6764 discovery
(.well-known/caldav|carddav + _caldavs/_carddavs SRV records) lets clients set up
from just email + password, and there's a one-tap Apple configuration profile at
/mail/profile/<email>.mobileconfig that bundles Mail + Calendar + Contacts.
Reading and sending over IMAP/SMTP needs a small extra service: IMAP/SMTP are
raw-TCP protocols, so (unlike CalDAV/CardDAV) they can't run inside the HTTP app. The
bridge lives in mailserver/ — a stateless Go service that stores
nothing and proxies every IMAP/SMTP action to the Laravel mailbox API.
Rather than bolt it on, the deployment offers two complete, production-ready compose files — pick one:
| Deploy this file | You get |
|---|---|
docker-compose.yaml | The web PWA stack (app + worker + scheduler + MySQL + Redis). No native mail apps. |
docker-compose.native.yaml | Everything above plus the IMAP/SMTP bridge (and CalDAV/CardDAV turned on), wired together internally. |
So to add native mail apps you don't run a second Coolify resource — you just point the
Docker Compose Location at docker-compose.native.yaml instead. The bridge talks to
the app over the internal Docker network (http://app:8080), so there's no public
round-trip and it's one shared deploy. The extra env for that file:
# Public host clients use for IMAP/SMTP — a GREY-CLOUD (DNS-only) record at this
# server's IP (Cloudflare's proxy can't carry raw IMAP/SMTP).
MAIL_CLIENT_SERVER_HOST=mail.example.com
# Optional: real IMAP/SMTP TLS certs (else a self-signed cert is generated).
TLS_DIR=/path/with/certs # mounted at /certs
TLS_CERT=/certs/fullchain.pem
TLS_KEY=/certs/privkey.pem
With it on, the app serves autodiscover/autoconfig XML so Apple Mail / Outlook /
Thunderbird configure themselves from just the address, and the DNS records
(autodiscover/autoconfig/mail CNAMEs, _imaps/_submission + CalDAV/CardDAV SRV) are
provisioned per domain automatically (MAIL_CLIENT_AUTO_DNS) or on demand from the
admin panel's Domains → "Mail istemci DNS" action.
Advanced:
docker-compose.mailserver.ymlruns the bridge on its own (as a separate Coolify resource reaching the app by its public URL) — only needed if the app isn't deployed fromdocker-compose.native.yaml(e.g. a Dockerfile build pack or a separate host).
See mailserver/README.md for the full walkthrough — env
vars, TLS, and scope/limitations.
Deploy the whole stack — app + MySQL + Redis + queue worker + scheduler — from the
included docker-compose.yaml. It builds the
Dockerfile (php-fpm + nginx via serversideup/php, plus Node +
wrangler so the inbound Worker deploys from the container).
Docker Compose (Configuration → General). Set Docker Compose
Location to /docker-compose.yaml. (Not Nixpacks — it would ship without
wrangler and break Deploy-Worker.)AWS_ACCESS_KEY_ID=… AWS_SECRET_ACCESS_KEY=…
AWS_BUCKET=… AWS_ENDPOINT=https://<id>.r2.cloudflarestorage.com
Everything else is automatic: Coolify generates & persists APP_KEY
(SERVICE_REALBASE64_APPKEY), the domain (SERVICE_URL_APP → APP_URL), and the
MySQL password (SERVICE_PASSWORD_MYSQL); VAPID_SUBJECT defaults to the app URL.
MySQL, Redis, the queue worker and the scheduler come up on their own; migrations
run on boot (serversideup AUTORUN). Web Push is off until you set a VAPID keypair
(see below).php artisan app:create-admin [email protected] --name="You"
It prompts for a password, then you can log in at https://<your-domain>/admin.php artisan cf:worker:sync).APP_KEY and VAPID_SUBJECT are generated automatically. Attachments need the
AWS_* (R2/S3) vars; mail send/receive works without them.
Push is off until you set a VAPID keypair. It can't be auto-generated (it's a stable EC keypair — rotating it breaks every existing subscription), so generate it once and set two env vars:
--show flag prints the keys instead of
writing a .env, which the container doesn't have):
php artisan webpush:vapid --show
It prints a VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY.VAPID_SUBJECT must be a mailto: or https:// URL — it identifies you to the
push services (Apple/iOS is strict and silently rejects an invalid value, so no
notification arrives). Set it to a contact address, e.g.:
VAPID_SUBJECT=mailto:[email protected]
If you leave it unset it falls back to APP_URL (a valid https:// URL). A bare
value like mailbox is invalid; the app normalises an email-looking value to
mailto:<email> and otherwise falls back to APP_URL, but set it explicitly to be safe.
Keep the keys stable across deploys (rotating them invalidates every existing subscription — users must re-enable notifications). On iOS (16.4+), push only works once the user installs the PWA to the Home Screen (Add to Home Screen), opens it from the Home Screen icon, and grants permission via the in-app "Bildirimleri aç" prompt.
{APP_URL}/api/cf/incoming) and the SPA service-worker scope. The compose file
wires it from Coolify's generated domain automatically.php artisan cf:deploy-worker / cf:worker:sync need outbound HTTPS to Cloudflare
from the container (allowed on standard Coolify networking).Dockerfile build pack
and add MySQL/Redis as separate Coolify resources, wiring DB_*/REDIS_* env vars
yourself — but the compose stack above is simpler and self-contained.php artisan test # full feature suite (108 tests)
vendor/bin/pint # code style
MIT.