Skip to content

feat: ssr:coolify publish target (SSR image → registry → Coolify deploy webhook) - #37

Merged
vianmora merged 2 commits into
mainfrom
feat/coolify-ssr-target
Sep 8, 2026
Merged

vianmora merged 2 commits into
mainfrom
feat/coolify-ssr-target

Conversation

@vianmora

@vianmora vianmora commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Publisher side of webstudio-self-host#23. Two commits.

1. refactor: extract buildDockerImage()

Pull sync → generate → patch → Dockerfile → docker build out of publishBuildSsr into buildDockerImage({ buildId, domain, workDir, imageTag }). publishBuildSsr keeps the local docker run + state + proxy registration. No behaviour change.

2. feat: ssr:coolify

The publisher owns no Coolify credentials. Each site is hosted on its owner's Coolify (potentially a different server per client):

  • The owner creates a Docker Image app pulling ${REGISTRY_URL}/ws-<slug> (port 3000) and copies its deploy webhook URL.
  • That URL (+ optional token) is passed per publish in the /publish body — coolifyWebhookUrl / coolifyWebhookToken.
  • publishBuildCoolifySsr: tear down local serving → buildDockerImage() tagged ${REGISTRY_URL}/ws-<slug>:latest (+ :<buildId>) → docker login (token via env, never logged) + docker push both tags → POST the webhook → state.json { mode: "coolify" }.
  • No Coolify API calls, no Traefik, no polling — a 2xx from the webhook means "deploy queued".
  • isSafeWebhookUrl rejects non-https / loopback / private hosts (SSRF guard).

Config:

  • REGISTRY_URL (+ REGISTRY_USER / REGISTRY_TOKEN if private) gates the target — instance-wide, one registry the publisher pushes to and every client's Coolify pulls from (ghcr.io public = simplest, or your own registry:2).
  • /capabilitiescoolify: !!REGISTRY_URL, lists ssr:coolify in targets.
  • DOCKER_SITE_DOCKERFILE gains ENV IPX_HTTP_ALLOW_ALL_DOMAINS=true + EXPOSE 3000 so a Coolify-hosted app needs no manual env.

Not here

Test

node --check + resolver smoke tests. No test suite in this repo — e2e (build → push → webhook) on the Coolify bench once the fork + self-host PRs land.

🤖 Generated with Claude Code

https://claude.ai/code/session_017rF3HMB1Z7V3LLsYaUrELs

vianmora and others added 2 commits September 8, 2026 22:04
Pull sync → generate → patch → Dockerfile → docker build into
buildDockerImage({ buildId, domain, workDir, imageTag }). publishBuildSsr
keeps only the local docker run + state + proxy registration. A remote
pipeline (Coolify) can now build the same image with a registry-prefixed
tag and push it. No behaviour change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rF3HMB1Z7V3LLsYaUrELs
New host "coolify" for SSR: the publisher owns no Coolify credentials.
Each site is hosted on its owner's Coolify (a different server per
client). The owner creates a "Docker Image" app pulling
${REGISTRY_URL}/ws-<slug> and hands us its deploy webhook URL, passed
per-publish in the /publish body (coolifyWebhookUrl / coolifyWebhookToken?).

publishBuildCoolifySsr: tear down any local serving → buildDockerImage()
tagged ${REGISTRY_URL}/ws-<slug>:latest (+ :<buildId>) → docker login
(token via env, never logged) + push both tags → POST the webhook so
Coolify pulls :latest and redeploys → state.json { mode: "coolify" }.
No Coolify API calls, no Traefik, no polling — a 2xx webhook = queued.
isSafeWebhookUrl rejects non-https / loopback / private hosts (SSRF).

REGISTRY_URL (+ REGISTRY_USER / REGISTRY_TOKEN) gates the target;
/capabilities reports coolify + lists ssr:coolify in targets.
DOCKER_SITE_DOCKERFILE gains ENV IPX_HTTP_ALLOW_ALL_DOMAINS=true + EXPOSE
3000 so a Coolify-hosted app needs no manual config.

webstudio-self-host#23. Fork side (webhook field in the Publish panel) is
a separate PR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rF3HMB1Z7V3LLsYaUrELs
@vianmora
vianmora merged commit 6008570 into main Sep 8, 2026
1 check passed
@vianmora
vianmora deleted the feat/coolify-ssr-target branch September 8, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant