Thinkmill / Thinkmill/keystatic

Astro content not updated from the changes of Keystatic

Open
#1,473 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.4k
Forks
159
Avg merge
21h 41m
Merged PRs (30d)
2

Description

What Happened

  1. I have dockerized the astro app and using GitHub as the Keystatic storage mode.
  2. Deployed to Cloudflare.
  3. Now when I edited the content in /keystatic admin portal, the content in the public views is not reflected.
  4. I saw the Git commit did push to the GitHub

Expected Result

  1. The changes of content in /keystatic route on live site should reflect the content shown in the public view.

docker-compose.yml

Dockerfile

Multi-stage build for optimized Astro application

Stage 1: Dependencies

FROM node:20-alpine AS deps

WORKDIR /app

Copy package files

COPY package.json package-lock.json ./

Install dependencies

RUN npm ci --only=production &&
npm cache clean --force

Stage 2: Builder

FROM node:20-alpine AS builder

WORKDIR /app

Copy package files

COPY package.json package-lock.json ./

Install all dependencies (including dev dependencies)

RUN npm ci

Copy source code

COPY . .

Build the application

RUN npm run build

Stage 3: Runner

FROM node:20-alpine AS runner

WORKDIR /app

Set production environment

ENV NODE_ENV=production
ENV HOST=0.0.0.0
ENV PORT=4321

Create non-root user for security

RUN addgroup --system --gid 1001 nodejs &&
adduser --system --uid 1001 astro

Copy necessary files from previous stages

COPY --from=deps --chown=astro:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=astro:nodejs /app/dist ./dist
COPY --from=builder --chown=astro:nodejs /app/package.json ./package.json

Switch to non-root user

USER astro

Expose the application port

EXPOSE 4321

Health check

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD node -e "require('http').get('http://localhost:4321/', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

Start the application

CMD ["node", "./dist/server/entry.mjs", "--host", "0.0.0.0"]

keystatic.config.ts

import { config, fields, collection } from "@keystatic/core";

export default config({
// Storage configuration:
// - Production (Docker/deployed): Uses GitHub storage with OAuth
// - Development (npm run dev): Uses local file system storage
//
// To test GitHub OAuth locally in Docker, this will use 'github' mode
// because Docker containers run with NODE_ENV=production
storage: import.meta.env.PROD
? {
kind: "github",
repo: {
owner: import.meta.env.PUBLIC_GITHUB_OWNER,
name: import.meta.env.PUBLIC_GITHUB_REPO,
},
// Optional: specify branch (defaults to main)
branchPrefix: import.meta.env.PUBLIC_GITHUB_BRANCH_PREFIX,
}
: {
kind: "local",
},
collections: {
// -------------------------------------------------------
// LOYALTY FOR ALL
// -------------------------------------------------------
appB: collection({
label: "Loyalty For All",
slugField: "title",
path: "src/content/docs/app-b/**",
format: { contentField: "content" },
schema: {
title: fields.slug({ name: { label: "Title" } }),
description: fields.text({ label: "Description", multiline: true }),
content: fields.markdoc({ label: "Content" }),
},
}),
},
});

astro.config.mjs

// @ts-check
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";

import react from "@astrojs/react";

import keystatic from "@keystatic/astro";
import starlightUtils from "@lorenzo_lewis/starlight-utils";
import markdoc from "@astrojs/markdoc";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({
adapter: node({
mode: "standalone",
}),
integrations: [
react(),
markdoc(),
keystatic(),
starlight({
title: "My Docs",
social: [
{
icon: "github",
label: "GitHub",
href: "https://github.com/withastro/starlight",
},
],
// Override components to customize behavior
components: {
// Custom Pagination component that respects app boundaries
Pagination: "./src/components/Pagination.astro",
},
plugins: [
// This plugin handles the sidebar separation
starlightUtils({
multiSidebar: {
switcherStyle: "hidden", // 'hidden' makes it feel like separate sites
},
}),
],
sidebar: [
{
label: "Guides",
items: [
// Each item here is one entry in the navigation menu.
{ label: "Example Guide", slug: "guides/example" },
],
},
{
label: "Reference",
autogenerate: { directory: "reference" },
},
// -------------------------------------------------------
// LOYALTY FOR ALL
// -------------------------------------------------------
{
label: "Loyalty For All", // Logic: If URL starts with /app-b/, show this sidebar
autogenerate: { directory: "app-b" },
},
],
}),
],
output: "server",
});

I need help on this, am I missing some configuration or I just need to restart the container whenever received a webhook of git commits or something.

Appreciate your time.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with keystatic.config.ts, astro.config.mjs, and the Dockerfile, then trace how a GitHub storage commit reaches the deployed Astro server and public content. Reproduce an edit through the /keystatic route and inspect the resulting deployment behavior. Done means the public view reflects the edit automatically, or the required webhook/restart workflow is clearly established.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, github, node.js, typescript
Domain
cloud, content, devops, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.