1
0
mirror of https://github.com/ZeroCatDev/ClassworksKV.git synced 2025-07-01 20:09:23 +00:00

Refactor Docker setup to consolidate services into a single app container using SQLite. Update Dockerfile to streamline dependency installation and set entrypoint for the application.

This commit is contained in:
SunWuyuan 2025-05-24 17:50:51 +08:00
parent 1f56b8032f
commit f3c24c24b8
No known key found for this signature in database
GPG Key ID: A6A54CF66F56BB64
3 changed files with 122 additions and 75 deletions

View File

@ -1,24 +1,25 @@
FROM node:alpine
# Required build argument for database type
ARG DATABASE_TYPE
WORKDIR /app
# Set production environment
ENV NODE_ENV=production \
DATABASE_TYPE=${DATABASE_TYPE}
# Set production environment by default
ENV NODE_ENV=production
# Copy all application files
COPY . .
# Copy specific database files based on DATABASE_TYPE and clean up
RUN cp -r /prisma/database/${DATABASE_TYPE}/* /prisma/ && \
rm -rf /prisma/database
# Install dependencies
RUN npm install
# Install dependencies and generate Prisma client
RUN npm install && \
npx prisma generate
# Copy all application files
# Make the management script executable
RUN chmod +x classworks.js
EXPOSE 3000
# Run different commands based on DATABASE_TYPE
CMD ["sh", "-c", "if [ \"$DATABASE_TYPE\" = \"sqlite\" ]; then (if [ ! -f /data/db.db ]; then npx prisma migrate dev --name init; else npx prisma migrate deploy; fi); else npx prisma migrate deploy; fi && npx prisma generate && npm run start"]
# Use the management script as entrypoint
ENTRYPOINT ["node", "classworks.js"]
# Default command (can be overridden)
CMD []

99
classworks.js Normal file
View File

@ -0,0 +1,99 @@
#!/usr/bin/env node
import { execSync } from "child_process";
import fs from "fs";
import path from "path";
import dotenv from "dotenv";
dotenv.config();
const PRISMA_DIR = path.join(process.cwd(), "prisma");
const DATABASE_TYPE = process.env.DATABASE_TYPE || "postgres";
const DATABASE_URL =
DATABASE_TYPE === "sqlite"
? "file:/data/db.sqlite"
: process.env.DATABASE_URL;
function setupDatabase() {
try {
// Create data directory for SQLite if needed
if (DATABASE_TYPE === "sqlite") {
if (!fs.existsSync("/data")) {
fs.mkdirSync("/data", { recursive: true });
}
} else if (!DATABASE_URL) {
console.error("❌ DATABASE_URL is required for non-SQLite databases");
process.exit(1);
}
// Copy files from database type directory
const sourceDir = path.join(PRISMA_DIR, "database", DATABASE_TYPE);
if (!fs.existsSync(sourceDir)) {
console.error(`❌ Database configuration not found at ${sourceDir}`);
process.exit(1);
}
// Read all files from source directory
const files = fs.readdirSync(sourceDir);
for (const file of files) {
const sourcePath = path.join(sourceDir, file);
const targetPath = path.join(PRISMA_DIR, file);
fs.copyFileSync(sourcePath, targetPath);
}
console.log(`✅ Copied ${DATABASE_TYPE} database configuration files`);
// Set DATABASE_URL for Prisma
process.env.DATABASE_URL = DATABASE_URL;
} catch (error) {
console.error("❌ Database setup failed:", error.message);
process.exit(1);
}
}
function buildLocal() {
try {
execSync("npm install", { stdio: "inherit" });
execSync("npx prisma generate", { stdio: "inherit" });
console.log("✅ Build completed");
} catch (error) {
console.error("❌ Build failed:", error.message);
process.exit(1);
}
}
function startServer() {
try {
console.log(`🚀 Starting server with ${DATABASE_TYPE} database...`);
execSync("npm run start", { stdio: "inherit" });
} catch (error) {
console.error("❌ Server start failed:", error.message);
process.exit(1);
}
}
function runPrismaCommand(args) {
try {
const command = `npx prisma ${args.join(" ")}`;
execSync(command, { stdio: "inherit" });
} catch (error) {
console.error("❌ Prisma command failed:", error.message);
process.exit(1);
}
}
async function main() {
const args = process.argv.slice(2);
if (args[0] === "prisma") {
// Run Prisma command
runPrismaCommand(args.slice(1));
} else {
// Setup environment and database
setupDatabase();
buildLocal();
startServer();
}
}
main().catch((error) => {
console.error("❌ Script failed:", error);
process.exit(1);
});

View File

@ -1,70 +1,17 @@
version: '3.8'
services:
app-mysql:
app:
build:
context: .
args:
DATABASE_TYPE: mysql
environment:
- NODE_ENV=production
- DATABASE_URL=mysql://user:password@mysql:3306/classworks
depends_on:
mysql:
condition: service_healthy
app-postgres:
build:
context: .
args:
DATABASE_TYPE: postgres
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@postgres:5432/classworks
depends_on:
postgres:
condition: service_healthy
app-sqlite:
build:
context: .
args:
DATABASE_TYPE: sqlite
dockerfile: Dockerfile
container_name: classworks
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_TYPE=sqlite
- DATABASE_URL=
volumes:
- sqlite_data:/data
- cs-data:/data
mysql:
image: mysql:8
environment:
- MYSQL_DATABASE=classworks
- MYSQL_USER=user
- MYSQL_PASSWORD=password
- MYSQL_ROOT_PASSWORD=rootpassword
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_DB=classworks
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d classworks"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mysql_data:
postgres_data:
sqlite_data: