mirror of
https://github.com/ZeroCatDev/ClassworksKV.git
synced 2025-07-02 04:39: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:
parent
1f56b8032f
commit
f3c24c24b8
29
Dockerfile
29
Dockerfile
@ -1,24 +1,25 @@
|
|||||||
FROM node:alpine
|
FROM node:alpine
|
||||||
|
|
||||||
# Required build argument for database type
|
WORKDIR /app
|
||||||
ARG DATABASE_TYPE
|
|
||||||
|
|
||||||
# Set production environment
|
# Set production environment by default
|
||||||
ENV NODE_ENV=production \
|
ENV NODE_ENV=production
|
||||||
DATABASE_TYPE=${DATABASE_TYPE}
|
|
||||||
|
|
||||||
# Copy all application files
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Copy specific database files based on DATABASE_TYPE and clean up
|
# Install dependencies
|
||||||
RUN cp -r /prisma/database/${DATABASE_TYPE}/* /prisma/ && \
|
RUN npm install
|
||||||
rm -rf /prisma/database
|
|
||||||
|
|
||||||
# Install dependencies and generate Prisma client
|
# Copy all application files
|
||||||
RUN npm install && \
|
|
||||||
npx prisma generate
|
|
||||||
|
# Make the management script executable
|
||||||
|
RUN chmod +x classworks.js
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
# Run different commands based on DATABASE_TYPE
|
# Use the management script as entrypoint
|
||||||
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"]
|
ENTRYPOINT ["node", "classworks.js"]
|
||||||
|
|
||||||
|
# Default command (can be overridden)
|
||||||
|
CMD []
|
99
classworks.js
Normal file
99
classworks.js
Normal 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);
|
||||||
|
});
|
@ -1,70 +1,17 @@
|
|||||||
version: '3.8'
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
app-mysql:
|
app:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
args:
|
dockerfile: Dockerfile
|
||||||
DATABASE_TYPE: mysql
|
container_name: classworks
|
||||||
environment:
|
ports:
|
||||||
- NODE_ENV=production
|
- "3000:3000"
|
||||||
- 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
|
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
|
- DATABASE_TYPE=sqlite
|
||||||
|
- DATABASE_URL=
|
||||||
volumes:
|
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:
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user