Skip to content

Commit 0bc2e92

Browse files
committed
ci: publish website Docker image to GHCR; standalone compose
Adds .github/workflows/docker.yml which builds the website on every push to main and every v* tag, pushes it to ghcr.io/IamCoder18/synapse-website, and tags it: - latest (on main) - 0.3.1 / 0.3 (on each v* tag, syncing with the Maven/Java release) - <short-sha> (every commit, for reproducibility) The image is multi-arch (linux/amd64 + linux/arm64) and uses GHA cache. PRs from any branch run the same build with push: false so the recipe stays exercised without writing to the registry. Build configuration lives in website/docker-bake.hcl (the build target, platforms, Dockerfile path) so the Dockerfile, tags, cache, and platform declarations stay co-located with the website source. website/docker-compose.yaml now references the prebuilt image and drops the build context. It works standalone — no checkout required — and accepts SYNAPSE_SITE_IMAGE for pinning. A copy of the same compose file is added at the repo root (docker-compose.yaml) with a comment header explaining usage, so the recipe is reachable from a single file copy. website/DOCKER.md documents image layout, tag strategy, and how to override the image or build it locally with docker buildx bake.
1 parent b784bc4 commit 0bc2e92

5 files changed

Lines changed: 207 additions & 2 deletions

File tree

‎.github/workflows/docker.yml‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Docker image
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['v*']
7+
pull_request:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
env:
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: ${{ github.repository }}/synapse-website
14+
15+
jobs:
16+
build:
17+
name: Build & push image
18+
runs-on: ubuntu-latest
19+
# Skip on PRs from forks (no GHCR write access) and on this repo's PRs
20+
# where we still want to verify the build succeeds without pushing.
21+
if: github.event_name != 'pull_request'
22+
permissions:
23+
contents: read
24+
packages: write
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Log in to GHCR
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ghcr.io
36+
username: ${{ github.actor }}
37+
password: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- name: Extract metadata
40+
id: meta
41+
uses: docker/metadata-action@v5
42+
with:
43+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
44+
tags: |
45+
type=ref,event=branch
46+
type=ref,event=pr
47+
type=semver,pattern={{version}}
48+
type=semver,pattern={{major}}.{{minor}}
49+
type=sha,format=short
50+
type=raw,value=latest,enable={{is_default_branch}}
51+
bake-target: synapse-website
52+
flavor: |
53+
latest=auto
54+
55+
- name: Build (and push)
56+
uses: docker/bake-action@v5
57+
with:
58+
source: website
59+
files: |
60+
website/docker-bake.hcl
61+
${{ steps.meta.outputs.bake-file }}
62+
targets: synapse-website
63+
push: true
64+
tags: ${{ steps.meta.outputs.tags }}
65+
labels: ${{ steps.meta.outputs.labels }}
66+
cache-from: type=gha
67+
cache-to: type=gha,mode=max
68+
69+
build-pr:
70+
name: Build (PR only)
71+
runs-on: ubuntu-latest
72+
if: github.event_name == 'pull_request'
73+
permissions:
74+
contents: read
75+
steps:
76+
- name: Checkout
77+
uses: actions/checkout@v4
78+
79+
- name: Set up Docker Buildx
80+
uses: docker/setup-buildx-action@v3
81+
82+
- name: Build
83+
uses: docker/bake-action@v5
84+
with:
85+
source: website
86+
files: |
87+
website/docker-bake.hcl
88+
targets: synapse-website
89+
push: false
90+
cache-from: type=gha

‎docker-compose.yaml‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Standalone docker compose for the Synapse website. The image is published
2+
# to GitHub Container Registry from this repo's main branch and from any
3+
# `v*` tag (see `.github/workflows/docker.yml`).
4+
#
5+
# Usage:
6+
#
7+
# docker compose up -d # pulls :latest
8+
# docker compose pull && docker compose up -d # refresh
9+
#
10+
# Pin a specific version:
11+
#
12+
# SYNAPSE_SITE_IMAGE=ghcr.io/iamcoder18/synapse-website:0.3.1 \
13+
# docker compose up -d
14+
#
15+
# Verify:
16+
#
17+
# curl http://localhost:8080/healthz # → ok
18+
# open http://localhost:8080/ # → Synapse home
19+
#
20+
# The container serves the static site on port 8080 and answers /healthz
21+
# with `ok` text plus a 200 status for compose healthchecks.
22+
23+
services:
24+
web:
25+
image: ${SYNAPSE_SITE_IMAGE:-ghcr.io/iamcoder18/synapse-website:latest}
26+
container_name: synapse-website
27+
restart: unless-stopped
28+
ports:
29+
- "8080:8080"
30+
healthcheck:
31+
test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"]
32+
interval: 30s
33+
timeout: 3s
34+
retries: 3

‎website/DOCKER.md‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Synapse website container
2+
3+
The Synapse marketing + docs site is published as a prebuilt Docker image at **GitHub Container Registry**:
4+
5+
```
6+
ghcr.io/iamcoder18/synapse-website
7+
```
8+
9+
Tags:
10+
11+
- `:latest` — updated on every merge to `main`
12+
- `:0.3.1`, `:0.3`, … — updated on every `v*` Git tag (synced with the Maven/Java package version)
13+
- `:<sha>` — every commit, for reproducibility
14+
15+
## Run with docker compose
16+
17+
Copy `docker-compose.yaml` to any directory and:
18+
19+
```bash
20+
docker compose up -d
21+
curl http://localhost:8080/healthz # → ok
22+
open http://localhost:8080/
23+
```
24+
25+
Pin a version:
26+
27+
```bash
28+
SYNAPSE_SITE_IMAGE=ghcr.io/iamcoder18/synapse-website:0.3.1 \
29+
docker compose up -d
30+
```
31+
32+
## Run without compose
33+
34+
```bash
35+
docker run --rm -p 8080:8080 --name synapse-website \
36+
ghcr.io/iamcoder18/synapse-website:latest
37+
```
38+
39+
## Image contents
40+
41+
- `node:lts-alpine` build stage compiles the Astro site to `dist/`.
42+
- `nginx:alpine` runtime serves the static files on port `8080` with the
43+
custom `nginx.conf` from this repo (immutable cache for hashed assets,
44+
revalidatable cache for HTML, gzip/brotli for text, `Link` headers for
45+
AI endpoints, `=404` fallback).
46+
- `/healthz` returns `200 ok` for compose healthchecks.
47+
48+
## Build locally (optional)
49+
50+
The image is built by `.github/workflows/docker.yml`. To build it yourself:
51+
52+
```bash
53+
cd website
54+
docker buildx bake synapse-website --push \
55+
--set "synapse-website.tags=ghcr.io/iamcoder18/synapse-website:dev"
56+
```
57+
58+
## Source
59+
60+
See [`website/Dockerfile`](./website/Dockerfile), [`website/nginx.conf`](./website/nginx.conf), and [`website/docker-bake.hcl`](./website/docker-bake.hcl).

‎website/docker-bake.hcl‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Build targets consumed by docker/bake-action (see .github/workflows/docker.yml).
2+
# Defining the build here keeps the Dockerfile, tags, cache config, and platform
3+
# declarations in one file under the website/ source tree.
4+
group "default" {
5+
targets = ["synapse-website"]
6+
}
7+
8+
target "synapse-website" {
9+
context = "."
10+
dockerfile = "Dockerfile"
11+
platforms = ["linux/amd64", "linux/arm64"]
12+
tags = [""]
13+
}

‎website/docker-compose.yaml‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
# Standalone compose file. The image is published to GitHub Container
2+
# Registry from this repo's main branch and tags — see
3+
# .github/workflows/docker.yml. Pull a specific tag in production:
4+
#
5+
# SYNAPSE_SITE_IMAGE=ghcr.io/iamcoder18/synapse-website:0.3.1 \
6+
# docker compose up -d
7+
#
8+
# Override `SYNAPSE_SITE_IMAGE` to pin a tag; omit it for `:latest`.
9+
110
services:
211
web:
3-
build: .
4-
image: synapse-website:local
12+
image: ${SYNAPSE_SITE_IMAGE:-ghcr.io/iamcoder18/synapse-website:latest}
513
container_name: synapse-website
614
restart: unless-stopped
715
ports:

0 commit comments

Comments
 (0)