29 Commits
Author SHA1 Message Date
renovate 93ed2c0e38 chore(deps): update nginxinc/nginx-unprivileged:1.31.7 docker digest to 09b0d3e (#88)
lingonpaj-site / build (push) Successful in 2m22s
lingonpaj-site / deploy-prod-frostmoln (push) Successful in 2m1s
2026-10-19 05:12:06 +00:00
renovate d8e556f1db chore(deps): update nginxinc/nginx-unprivileged docker tag to v1.31.7 (#87)
lingonpaj-site / build (push) Successful in 2m33s
lingonpaj-site / deploy-prod-frostmoln (push) Successful in 1m44s
2026-10-15 20:13:36 +00:00
argoyle 4da73fb025 feat: deploy to Frostmoln production (#86)
lingonpaj-site / build (push) Successful in 2m32s
lingonpaj-site / deploy-prod-frostmoln (push) Successful in 1m46s
Moves the production deploy from AWS to the Frostmoln production cluster (namespace `sites`).

- `deploy-prod` (AWS) has failed since CI left AWS: the runners have no `k8s.unbound.se` context, so the site on AWS still runs an older image. It's replaced by `deploy-prod-frostmoln`, the same pattern as Shiny's `deploy-frostmoln-staging`: `FROSTMOLN_PRODUCTION_DEPLOY_KEY` + `FROSTMOLN_PRODUCTION_CLUSTER_ID` (org), `BUILDTOOLS_FROSTMOLN_PRODUCTION` (org, target `prod-frostmoln`), `deploy prod-frostmoln -n sites`.
- Frostmoln enforces restricted Pod Security: the served image is `nginxinc/nginx-unprivileged` (uid 101, port 8080), with a matching securityContext; the Service is ClusterIP.
- `ingress-prod.yaml` (ALB) → `ingress-prod-frostmoln.yaml` (Traefik, Let's Encrypt).

Checked locally: the image serves `/health` and `/` (200) as uid 101 with all capabilities dropped.

**Merge after** infra's `feat/frostmoln-production-sites` is applied (namespace + org secret). The hostnames keep pointing at AWS until the Route 53 switch, a separate step; the certificate is issued after that.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01Ma8eHhW59hLAJuLzBnLvUu
Reviewed-on: #86
2026-10-14 17:53:36 +00:00
renovate 0b066ee2a4 chore(deps): update nginx:1.31.6 docker digest to 9a54e7e (#85)
lingonpaj-site / deploy-prod (push) Successful in 1m42s
lingonpaj-site / build (push) Successful in 1m25s
2026-10-06 03:27:36 +00:00
argoyle e8b28ba011 chore(k8s): take the image reference from build-tools (#84)
lingonpaj-site / build (push) Successful in 1m13s
lingonpaj-site / deploy-prod (push) Successful in 1m25s
## Summary

`k8s/deploy.yaml` takes the image from build-tools: `image: ${IMAGE}` instead of the hard-coded `oci.unbound.se/unboundsoftware/lingonpaj-site:${COMMIT}`.

`deploy` substitutes `${IMAGE}` with `<registry>/<owner>/<name>:<tag>`, where the registry comes from the build-tools config and the tag is the value `${COMMIT}` gets today. The rendered reference is unchanged. Moving off `oci.unbound.se` later becomes one change in infra.

Validated on shiny/time-service#864: merged and deployed to AWS staging and Frostmoln staging with the same image. Prerequisites, all merged:
- unboundsoftware/infra#1808: registry in `BUILDTOOLS_FROSTMOLN_STAGING`
- shiny/acctest#952: acctest pins build-tools to the Gitea registry

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: https://gitea.unbound.se/unboundsoftware/lingonpaj-site/pulls/84
2026-10-02 22:52:44 +00:00
renovate 6d4088416d chore(deps): update nginx:1.31.6 docker digest to 8e1fce8 (#83)
lingonpaj-site / build (push) Successful in 45s
lingonpaj-site / deploy-prod (push) Successful in 1m28s
2026-09-19 02:14:24 +00:00
renovate 7b1d640e6e chore(deps): update nginx docker tag to v1.31.6 (#82)
lingonpaj-site / build (push) Successful in 43s
lingonpaj-site / deploy-prod (push) Successful in 1m25s
2026-09-16 01:10:30 +00:00
renovate a987b83b04 chore(deps): update nginx docker tag to v1.31.5 (#81)
lingonpaj-site / build (push) Successful in 52s
lingonpaj-site / deploy-prod (push) Successful in 1m24s
2026-09-02 22:08:49 +00:00
renovate 39f7291aa0 chore(deps): update nginx:1.31.4 docker digest to 69a292b (#80)
lingonpaj-site / build (push) Successful in 43s
lingonpaj-site / deploy-prod (push) Successful in 1m25s
2026-08-25 03:10:24 +00:00
renovate 92bb7f8d10 chore(deps): update nginx docker tag to v1.31.4 (#79)
lingonpaj-site / build (push) Successful in 1m49s
lingonpaj-site / deploy-prod (push) Successful in 1m26s
2026-08-19 21:29:21 +00:00
renovate 93798866a4 chore(deps): update nginx:1.31.3 docker digest to 48d15d5 (#78)
lingonpaj-site / build (push) Successful in 44s
lingonpaj-site / deploy-prod (push) Successful in 1m23s
2026-08-08 07:17:40 +00:00
renovate 0eeaa0f3be chore(deps): update nginx docker tag to v1.31.3 (#77)
lingonpaj-site / build (push) Successful in 1m13s
lingonpaj-site / deploy-prod (push) Successful in 1m40s
2026-07-19 19:34:25 +00:00
renovate c5fee02f77 chore(deps): update nginx:1.31.2 docker digest to 43ace28 (#76)
lingonpaj-site / build (push) Successful in 44s
lingonpaj-site / deploy-prod (push) Successful in 1m27s
2026-07-14 04:08:14 +00:00
renovate 8c3a51a7d5 chore(deps): update nginx:1.31.2 docker digest to 1aa5260 (#75)
lingonpaj-site / build (push) Successful in 1m19s
lingonpaj-site / deploy-prod (push) Successful in 1m52s
2026-06-24 03:12:53 +00:00
renovate c6d374dd6c chore(deps): update nginx docker tag to v1.31.2 (#74)
lingonpaj-site / build (push) Successful in 1m29s
lingonpaj-site / deploy-prod (push) Successful in 1m52s
2026-06-21 16:37:29 +00:00
renovate a4d454fc3b chore(deps): update actions/checkout action to v7 (#73)
lingonpaj-site / build (push) Successful in 1m29s
lingonpaj-site / deploy-prod (push) Successful in 1m51s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://github.com/actions/checkout) | action | major | `v6` → `v7` |

---

### Release Notes

<details>
<summary>actions/checkout (actions/checkout)</summary>

### [`v7.0.0`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v700)

[Compare Source](https://github.com/actions/checkout/compare/v7.0.0...v7.0.0)

- Block checking out fork PR for pull\_request\_target and workflow\_run by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2454](https://github.com/actions/checkout/pull/2454)
- Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2458](https://github.com/actions/checkout/pull/2458)
- Bump flatted from 3.3.1 to 3.4.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2460](https://github.com/actions/checkout/pull/2460)
- Bump js-yaml from 4.1.0 to 4.2.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2461](https://github.com/actions/checkout/pull/2461)
- Bump [@&#8203;actions/core](https://github.com/actions/core) and [@&#8203;actions/tool-cache](https://github.com/actions/tool-cache) and Remove uuid by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2459](https://github.com/actions/checkout/pull/2459)
- upgrade module to esm and update dependencies by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2463](https://github.com/actions/checkout/pull/2463)
- Bump the minor-npm-dependencies group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2462](https://github.com/actions/checkout/pull/2462)

### [`v7`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v700)

[Compare Source](https://github.com/actions/checkout/compare/v6.0.3...v7.0.0)

- Block checking out fork PR for pull\_request\_target and workflow\_run by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2454](https://github.com/actions/checkout/pull/2454)
- Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2458](https://github.com/actions/checkout/pull/2458)
- Bump flatted from 3.3.1 to 3.4.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2460](https://github.com/actions/checkout/pull/2460)
- Bump js-yaml from 4.1.0 to 4.2.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2461](https://github.com/actions/checkout/pull/2461)
- Bump [@&#8203;actions/core](https://github.com/actions/core) and [@&#8203;actions/tool-cache](https://github.com/actions/tool-cache) and Remove uuid by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2459](https://github.com/actions/checkout/pull/2459)
- upgrade module to esm and update dependencies by [@&#8203;aiqiaoy](https://github.com/aiqiaoy) in [#&#8203;2463](https://github.com/actions/checkout/pull/2463)
- Bump the minor-npm-dependencies group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;2462](https://github.com/actions/checkout/pull/2462)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMjAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIyMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: https://gitea.unbound.se/unboundsoftware/lingonpaj-site/pulls/73
Co-authored-by: Renovate Bot <renovate@unbound.se>
Co-committed-by: Renovate Bot <renovate@unbound.se>
2026-06-21 15:45:23 +00:00
renovate 683b0400ac chore(deps): update nginx:1.31.1 docker digest to c81b9fb (#72)
lingonpaj-site / build (push) Successful in 1m9s
lingonpaj-site / deploy-prod (push) Successful in 2m7s
2026-06-11 04:08:25 +00:00
renovate a7b5920fb7 chore(deps): update nginx docker tag to v1.31.1 (#71)
lingonpaj-site / build (push) Successful in 1m35s
lingonpaj-site / deploy-prod (push) Successful in 1m56s
2026-05-25 18:46:38 +00:00
renovate 2b0876ac19 chore(deps): update nginx:1.31.0 docker digest to ff3292d (#70)
lingonpaj-site / build (push) Successful in 1m32s
lingonpaj-site / deploy-prod (push) Successful in 1m47s
2026-05-20 01:09:53 +00:00
renovate 95d3a90558 chore(deps): update nginx:1.31.0 docker digest to fa7c6d4 (#69)
lingonpaj-site / build (push) Successful in 1m31s
lingonpaj-site / deploy-prod (push) Successful in 1m59s
2026-05-19 23:08:37 +00:00
renovate 0cf47b0281 chore(deps): update nginx docker tag to v1.31.0 (#68)
lingonpaj-site / build (push) Successful in 1m10s
lingonpaj-site / deploy-prod (push) Successful in 1m52s
2026-05-16 20:10:04 +00:00
renovate c8401d405f chore(deps): update nginx:1.30.0 docker digest to 56b5242 (#67)
lingonpaj-site / build (push) Successful in 1m19s
lingonpaj-site / deploy-prod (push) Successful in 2m6s
2026-05-09 00:08:12 +00:00
renovate 252e5b47a6 chore(deps): update nginx:1.30.0 docker digest to 67c70b6 (#66)
lingonpaj-site / build (push) Successful in 1m49s
lingonpaj-site / deploy-prod (push) Successful in 2m6s
2026-04-22 04:08:02 +00:00
renovate 3044d45361 chore(deps): update nginx docker tag to v1.30.0 (#65)
lingonpaj-site / build (push) Successful in 1m16s
lingonpaj-site / deploy-prod (push) Successful in 2m6s
2026-04-18 02:09:31 +00:00
renovate 1b03bd7a16 chore(deps): update nginx docker tag to v1.29.8 (#64)
lingonpaj-site / build (push) Successful in 1m47s
lingonpaj-site / deploy-prod (push) Successful in 1m57s
2026-04-10 18:15:34 +00:00
renovate 6c4b2e5dc2 chore(deps): update nginx:1.29.7 docker digest to e024ff0 (#63)
lingonpaj-site / build (push) Successful in 1m27s
lingonpaj-site / deploy-prod (push) Successful in 1m48s
2026-04-07 03:08:40 +00:00
renovate df68f71126 chore(deps): update nginx docker tag to v1.29.7 (#62)
lingonpaj-site / build (push) Successful in 1m50s
lingonpaj-site / deploy-prod (push) Successful in 1m57s
2026-03-25 01:09:45 +00:00
renovate c2ba5f7c4e chore(deps): update nginx:1.29.6 docker digest to d1073a7 (#61)
lingonpaj-site / build (push) Successful in 1m16s
lingonpaj-site / deploy-prod (push) Successful in 1m57s
2026-03-17 00:12:22 +00:00
renovate af8a060643 chore(deps): update nginx docker tag to v1.29.6 (#60)
lingonpaj-site / build (push) Successful in 1m59s
lingonpaj-site / deploy-prod (push) Successful in 3m6s
2026-03-10 23:08:51 +00:00
6 changed files with 56 additions and 36 deletions

No files matched your search

+20 -6
View File
@@ -13,21 +13,35 @@ jobs:
BUILDTOOLS_CONTENT: ${{ secrets.BUILDTOOLS_CONTENT }} BUILDTOOLS_CONTENT: ${{ secrets.BUILDTOOLS_CONTENT }}
GITEA_REPOSITORY: ${{ gitea.repository }} GITEA_REPOSITORY: ${{ gitea.repository }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: buildtool/setup-buildtools-action@v1 - uses: buildtool/setup-buildtools-action@v1
- name: Build and push - name: Build and push
run: unset GITEA_TOKEN && build && push run: unset GITEA_TOKEN && build && push
deploy-prod: deploy-prod-frostmoln:
needs: build needs: build
if: gitea.ref == 'refs/heads/main' if: gitea.ref == 'refs/heads/main'
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
BUILDTOOLS_CONTENT: ${{ secrets.BUILDTOOLS_CONTENT }} BUILDTOOLS_CONTENT: ${{ secrets.BUILDTOOLS_FROSTMOLN_PRODUCTION }}
GITEA_REPOSITORY: ${{ gitea.repository }} GITEA_REPOSITORY: ${{ gitea.repository }}
FM_TENANT: 9ae61342-0f76-476f-8176-e46f6b0b0c32
environment: prod environment: prod
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
- uses: buildtool/setup-buildtools-action@v1 - uses: buildtool/setup-buildtools-action@v1
- name: Deploy to production - name: Install fm
run: deploy prod run: |
sudo install -d -m 0755 /etc/apt/keyrings
sudo curl -fsSL -o /etc/apt/keyrings/frostmoln.gpg https://get.frostmoln.cloud/deb/frostmoln.gpg
sudo curl -fsSL -o /etc/apt/sources.list.d/frostmoln.sources https://get.frostmoln.cloud/deb/frostmoln.sources
sudo apt-get update && sudo apt-get install -y fm
- name: Deploy to Frostmoln production
env:
FROSTMOLN_API_KEY: ${{ secrets.FROSTMOLN_PRODUCTION_DEPLOY_KEY }}
# The cluster API is private: the kubeconfig's exec plugin opens an fm
# tunnel on demand. fm reads the key from its config file, not the env.
run: |
fm auth api-key set "$FROSTMOLN_API_KEY" > /dev/null
fm kubernetes cluster kubeconfig ${{ vars.FROSTMOLN_PRODUCTION_CLUSTER_ID }} --exec --file "$RUNNER_TEMP/kubeconfig"
KUBECONFIG_CONTENT="$(cat "$RUNNER_TEMP/kubeconfig")" deploy prod-frostmoln -n sites
+2 -1
View File
@@ -1,4 +1,5 @@
FROM amd64/nginx:1.29.5@sha256:e5e99d386e625a3ae9492f8496903a42bac0abc0b9103852f180679aef9bf8a2 # Unprivileged (uid 101, port 8080): Frostmoln enforces restricted Pod Security.
FROM nginxinc/nginx-unprivileged:1.31.7@sha256:09b0d3eda2aa592d2487f284519419015cab010d7df16cd0fe224b585fc60eb6
MAINTAINER Joakim Olsson <joakim@unbound.se> MAINTAINER Joakim Olsson <joakim@unbound.se>
ADD files/*.html files/*.jpg files/*.mp3 /usr/share/nginx/html/ ADD files/*.html files/*.jpg files/*.mp3 /usr/share/nginx/html/
+1 -1
View File
@@ -1,5 +1,5 @@
server { server {
listen 80; listen 8080;
server_name localhost; server_name localhost;
access_log /dev/stdout combined; access_log /dev/stdout combined;
+13 -5
View File
@@ -22,6 +22,11 @@ spec:
labels: labels:
app.kubernetes.io/name: lingonpaj-site app.kubernetes.io/name: lingonpaj-site
spec: spec:
securityContext:
runAsNonRoot: true
runAsUser: 101
seccompProfile:
type: RuntimeDefault
affinity: affinity:
podAntiAffinity: podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution: preferredDuringSchedulingIgnoredDuringExecution:
@@ -39,14 +44,18 @@ spec:
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /health path: /health
port: 80 port: 8080
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 5 periodSeconds: 5
timeoutSeconds: 5 timeoutSeconds: 5
imagePullPolicy: Always imagePullPolicy: Always
image: oci.unbound.se/unboundsoftware/lingonpaj-site:${COMMIT} image: ${IMAGE}
ports: ports:
- containerPort: 80 - containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
resources: resources:
requests: requests:
cpu: 5m cpu: 5m
@@ -64,9 +73,8 @@ metadata:
labels: labels:
app.kubernetes.io/name: lingonpaj-site app.kubernetes.io/name: lingonpaj-site
spec: spec:
type: NodePort
selector: selector:
app.kubernetes.io/name: lingonpaj-site app.kubernetes.io/name: lingonpaj-site
ports: ports:
- port: 80 - port: 80
targetPort: 80 targetPort: 8080
+20
View File
@@ -0,0 +1,20 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: lingonpaj-site
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt
spec:
ingressClassName: traefik
rules:
- host: "lingonpaj.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lingonpaj-site
port:
number: 80
-23
View File
@@ -1,23 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: lingonpaj-site-ingress
annotations:
kubernetes.io/ingress.class: "alb"
alb.ingress.kubernetes.io/group.name: default
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS": 443}]'
alb.ingress.kubernetes.io/ssl-redirect: "443"
spec:
rules:
- host: "lingonpaj.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lingonpaj-site
port:
number: 80