Add Sanity Studio served at /studio via Docker multi-stage build
Builds studio/ separately during Docker build and copies output to public/studio/ so it is served as static files by the Astro Node adapter. Catch-all route redirects deep studio links back to /studio for SPA routing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fc644510af
commit
9ca50a1da8
8 changed files with 15357 additions and 291 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -1,5 +1,12 @@
|
|||
node_modules
|
||||
dist
|
||||
public/studio
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
studio/.env
|
||||
studio/.env.local
|
||||
studio/.sanity
|
||||
.DS_Store
|
||||
server/public
|
||||
vite.config.ts.*
|
||||
|
|
|
|||
45
Dockerfile
Normal file
45
Dockerfile
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
FROM node:20-alpine AS base
|
||||
WORKDIR /app
|
||||
|
||||
# ── 1. Install main project deps ─────────────────────────────────────────────
|
||||
FROM base AS deps
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
# ── 2. Install studio deps ────────────────────────────────────────────────────
|
||||
FROM base AS studio-deps
|
||||
COPY studio/package.json studio/package-lock.json* ./
|
||||
RUN npm ci
|
||||
|
||||
# ── 3. Build Sanity Studio ────────────────────────────────────────────────────
|
||||
FROM base AS studio-build
|
||||
COPY --from=studio-deps /app/node_modules ./node_modules
|
||||
COPY studio/ ./
|
||||
ARG SANITY_STUDIO_PROJECT_ID
|
||||
ARG SANITY_STUDIO_DATASET=production
|
||||
ENV SANITY_STUDIO_PROJECT_ID=$SANITY_STUDIO_PROJECT_ID
|
||||
ENV SANITY_STUDIO_DATASET=$SANITY_STUDIO_DATASET
|
||||
RUN npm run build
|
||||
|
||||
# ── 4. Build Astro site (with studio output as static files) ──────────────────
|
||||
FROM base AS build
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
COPY --from=studio-build /app/dist ./public/studio
|
||||
ARG SANITY_PROJECT_ID
|
||||
ARG SANITY_DATASET=production
|
||||
ARG SANITY_API_TOKEN
|
||||
ENV SANITY_PROJECT_ID=$SANITY_PROJECT_ID
|
||||
ENV SANITY_DATASET=$SANITY_DATASET
|
||||
ENV SANITY_API_TOKEN=$SANITY_API_TOKEN
|
||||
RUN npm run build
|
||||
|
||||
# ── 5. Runtime ────────────────────────────────────────────────────────────────
|
||||
FROM node:20-alpine AS runtime
|
||||
WORKDIR /app
|
||||
COPY --from=build /app/dist ./dist
|
||||
COPY --from=build /app/node_modules ./node_modules
|
||||
ENV HOST=0.0.0.0
|
||||
ENV PORT=4321
|
||||
EXPOSE 4321
|
||||
CMD ["node", "./dist/server/entry.mjs"]
|
||||
1176
package-lock.json
generated
1176
package-lock.json
generated
File diff suppressed because it is too large
Load diff
7
src/pages/studio/[...path].ts
Normal file
7
src/pages/studio/[...path].ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import type { APIRoute } from "astro";
|
||||
|
||||
// Redirect deep studio links (e.g. /studio/desk/post) back to /studio so the
|
||||
// SPA can boot and handle its own routing. Static assets under /studio/assets/*
|
||||
// are served before this route ever fires.
|
||||
export const GET: APIRoute = () =>
|
||||
new Response(null, { status: 302, headers: { Location: "/studio" } });
|
||||
6
studio/.env.example
Normal file
6
studio/.env.example
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# ── Sanity Studio ────────────────────────────────────────────────────────────
|
||||
# Copy to .env and fill in your values from https://www.sanity.io/manage
|
||||
# SANITY_STUDIO_ prefix is required — Sanity injects these into the studio bundle.
|
||||
|
||||
SANITY_STUDIO_PROJECT_ID=
|
||||
SANITY_STUDIO_DATASET=production
|
||||
14402
studio/package-lock.json
generated
Normal file
14402
studio/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,7 @@
|
|||
"dependencies": {
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"sanity": "^3.66.0"
|
||||
"sanity": "^3.66.0",
|
||||
"styled-components": "^6.4.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { defineConfig } from 'sanity';
|
||||
import { structureTool } from 'sanity/structure';
|
||||
import { visionTool } from '@sanity/vision';
|
||||
import { schemaTypes } from './schemaTypes';
|
||||
|
||||
export default defineConfig({
|
||||
|
|
@ -13,7 +12,6 @@ export default defineConfig({
|
|||
|
||||
plugins: [
|
||||
structureTool(),
|
||||
visionTool(), // GROQ query playground — remove in production if desired
|
||||
],
|
||||
|
||||
schema: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue