feat: add Easypanel persistent volume support for Astro DB
- Change Dockerfile from nginx (static) to Node.js (SSR) - Add @astrojs/node adapter for SSR mode - Add OUT_DIR=/data for persistent SQLite storage - Add .env.example with persistent storage config - Update README with Easypanel deployment instructions - Database persists across redeployments at /data/astro.db
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
# Astro + Tina CMS Environment Variables
|
||||||
|
|
||||||
|
# Site URL
|
||||||
|
PUBLIC_SITE_URL=https://your-domain.com
|
||||||
|
|
||||||
|
# Tina CMS (optional - for production Tina admin)
|
||||||
|
TINA_TOKEN=your-tina-token-from-tina-cloud
|
||||||
|
TINA_CLIENT_ID=your-client-id
|
||||||
|
|
||||||
|
# Astro DB - Persistent Storage
|
||||||
|
# IMPORTANT: Set OUT_DIR to /data for Docker/Easypanel persistent volume
|
||||||
|
# This ensures database persists across redeployments
|
||||||
|
OUT_DIR=/data
|
||||||
|
|
||||||
|
# Optional: External Turso database (if using external DB instead of local SQLite)
|
||||||
|
# TURSO_DATABASE_URL=libsql://your-db.turso.io
|
||||||
|
# TURSO_AUTH_TOKEN=your-auth-token
|
||||||
@@ -3,17 +3,23 @@ FROM node:20-alpine AS builder
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
|
|
||||||
RUN npm install
|
RUN npm install
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
FROM nginx:alpine AS runner
|
FROM node:20-alpine AS runner
|
||||||
|
|
||||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
WORKDIR /app
|
||||||
|
RUN mkdir -p /data
|
||||||
|
|
||||||
EXPOSE 80
|
COPY --from=builder /app/dist ./dist
|
||||||
|
COPY --from=builder /app/package.json ./
|
||||||
|
RUN npm install --omit=dev
|
||||||
|
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
ENV HOST=0.0.0.0
|
||||||
|
ENV PORT=4321
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
EXPOSE 4321
|
||||||
|
|
||||||
|
CMD ["node", "dist/server/entry.mjs"]
|
||||||
@@ -4,10 +4,11 @@ Astro 6.1.7 + Tina CMS starter template with Tailwind CSS 4.x
|
|||||||
|
|
||||||
## Tech Stack
|
## Tech Stack
|
||||||
|
|
||||||
- **Framework:** Astro 6.1.7
|
- **Framework:** Astro 6.1.7 (SSR mode)
|
||||||
- **CMS:** Tina CMS (self-hosted)
|
- **CMS:** Tina CMS (self-hosted)
|
||||||
- **Styling:** Tailwind CSS 4.x with `@tailwindcss/vite`
|
- **Styling:** Tailwind CSS 4.x with `@tailwindcss/vite`
|
||||||
- **Database:** Astro DB (LibSQL)
|
- **Database:** Astro DB (LibSQL/SQLite)
|
||||||
|
- **Adapter:** @astrojs/node (SSR)
|
||||||
- **State:** Nano Stores + React
|
- **State:** Nano Stores + React
|
||||||
- **Language:** TypeScript
|
- **Language:** TypeScript
|
||||||
|
|
||||||
@@ -16,9 +17,9 @@ Astro 6.1.7 + Tina CMS starter template with Tailwind CSS 4.x
|
|||||||
- Self-hosted Tina CMS with schema-based content
|
- Self-hosted Tina CMS with schema-based content
|
||||||
- Tailwind CSS 4.x using `@tailwindcss/vite` plugin
|
- Tailwind CSS 4.x using `@tailwindcss/vite` plugin
|
||||||
- Astro DB for consent logging (PDPA compliant)
|
- Astro DB for consent logging (PDPA compliant)
|
||||||
- Nano Stores for client-side state management
|
- SSR mode for API routes
|
||||||
|
- Docker-ready with persistent storage
|
||||||
- Thai language support foundation
|
- Thai language support foundation
|
||||||
- Docker-ready deployment
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
@@ -40,6 +41,41 @@ During development, access Tina CMS at:
|
|||||||
|
|
||||||
For production, you'll need a TINA_TOKEN environment variable.
|
For production, you'll need a TINA_TOKEN environment variable.
|
||||||
|
|
||||||
|
## Easypanel Deployment
|
||||||
|
|
||||||
|
This template is designed for **Easypanel** with persistent volume support.
|
||||||
|
|
||||||
|
### Important: Persistent Storage
|
||||||
|
|
||||||
|
**Astro DB stores SQLite at `/data/`** - this directory is mounted as a persistent volume in Easypanel.
|
||||||
|
|
||||||
|
When deploying:
|
||||||
|
1. Set environment variable `OUT_DIR=/data`
|
||||||
|
2. Mount persistent volume to `/data` in Easypanel
|
||||||
|
3. Database will persist across redeployments
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Required for persistent storage
|
||||||
|
OUT_DIR=/data
|
||||||
|
|
||||||
|
# Optional - Tina CMS
|
||||||
|
TINA_TOKEN=your-tina-token
|
||||||
|
|
||||||
|
# Optional - External database (instead of local SQLite)
|
||||||
|
# TURSO_DATABASE_URL=libsql://your-db.turso.io
|
||||||
|
# TURSO_AUTH_TOKEN=your-auth-token
|
||||||
|
```
|
||||||
|
|
||||||
|
### Easypanel Setup
|
||||||
|
|
||||||
|
1. Create new service from Git repo
|
||||||
|
2. Set build command: `npm run build`
|
||||||
|
3. Set start command: `node dist/server/entry.mjs`
|
||||||
|
4. Add environment variable: `OUT_DIR=/data`
|
||||||
|
5. Mount persistent volume to `/data`
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -56,12 +92,13 @@ astro-tina-starter/
|
|||||||
│ ├── layouts/
|
│ ├── layouts/
|
||||||
│ │ └── Layout.astro
|
│ │ └── Layout.astro
|
||||||
│ ├── pages/
|
│ ├── pages/
|
||||||
│ │ └── index.astro
|
│ │ ├── index.astro
|
||||||
|
│ │ └── api/ # API routes (consent, etc.)
|
||||||
│ ├── components/
|
│ ├── components/
|
||||||
│ │ └── Header.astro
|
│ │ └── Header.astro
|
||||||
│ └── content/
|
│ └── content/
|
||||||
│ └── config.ts # Tina content collections
|
│ └── config.ts # Tina content collections
|
||||||
├── Dockerfile
|
├── Dockerfile # Multi-stage Node.js (not nginx)
|
||||||
└── package.json
|
└── package.json
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -85,20 +122,28 @@ The template includes a consent-log table for PDPA compliance:
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
// db/config.ts
|
// db/config.ts
|
||||||
export const ConsentLog = defineTable({
|
import { defineDb, defineTable, column } from 'astro:db';
|
||||||
|
|
||||||
|
const ConsentLog = defineTable({
|
||||||
columns: {
|
columns: {
|
||||||
action: text(),
|
id: column.number({ primaryKey: true }),
|
||||||
purpose: text(),
|
action: column.text(),
|
||||||
analytics: boolean(),
|
purpose: column.text(),
|
||||||
marketing: boolean(),
|
analytics: column.boolean({ default: false }),
|
||||||
functional: boolean(),
|
marketing: column.boolean({ default: false }),
|
||||||
userAgent: text(),
|
functional: column.boolean({ default: false }),
|
||||||
ip: text(),
|
userAgent: column.text({ optional: true }),
|
||||||
timestamp: text(),
|
ip: column.text({ optional: true }),
|
||||||
|
timestamp: column.date(),
|
||||||
|
sessionId: column.text({ optional: true }),
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
|
export default defineDb({ tables: { ConsentLog } });
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Database file location: `/data/astro.db` (persistent across redeployments)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { defineConfig } from 'astro/config'
|
import { defineConfig } from 'astro/config'
|
||||||
import tailwindcss from '@tailwindcss/vite'
|
import tailwindcss from '@tailwindcss/vite'
|
||||||
import tina from 'tinacms'
|
import tina from 'tinacms'
|
||||||
|
import node from '@astrojs/node'
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
@@ -27,7 +28,10 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: 'static',
|
output: 'server',
|
||||||
|
adapter: node({
|
||||||
|
mode: 'standalone'
|
||||||
|
}),
|
||||||
build: {
|
build: {
|
||||||
assets: '_assets',
|
assets: '_assets',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/check": "^0.9.4",
|
"@astrojs/check": "^0.9.4",
|
||||||
"@astrojs/db": "^0.14.3",
|
"@astrojs/db": "^0.14.3",
|
||||||
|
"@astrojs/node": "^9.0.0",
|
||||||
"@nanostores/react": "^0.7.3",
|
"@nanostores/react": "^0.7.3",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
"@tailwindcss/vite": "^4.0.0",
|
"@tailwindcss/vite": "^4.0.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user