Skip to content

Astro content not updated from the changes of Keystatic #1473

@simple-ky

Description

@simple-ky

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions