feat: add Dockerfile and .dockerignore, refactor backend to use DATA_DIR for database and uploads
Now able to use docker image
This commit is contained in:
10
.dockerignore
Normal file
10
.dockerignore
Normal file
@@ -0,0 +1,10 @@
|
||||
node_modules
|
||||
frontend/node_modules
|
||||
backend/node_modules
|
||||
frontend/dist
|
||||
backend/dist
|
||||
backend/db.sqlite
|
||||
backend/uploads
|
||||
*.log
|
||||
.DS_Store
|
||||
.env
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -8,26 +8,19 @@ dist/
|
||||
frontend/dist/
|
||||
backend/dist/
|
||||
|
||||
# SQLite database and uploads
|
||||
backend/db.sqlite
|
||||
backend/uploads/
|
||||
# Persistent backend data (database and uploads)
|
||||
backend/data/
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/
|
||||
.idea/
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# Environment files (if any)
|
||||
.env
|
||||
|
||||
26
Dockerfile
Normal file
26
Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Build frontend
|
||||
FROM node:24-alpine AS frontend
|
||||
WORKDIR /app/frontend
|
||||
COPY frontend/package*.json ./
|
||||
RUN npm install
|
||||
COPY frontend ./
|
||||
RUN npm run build
|
||||
|
||||
# Build backend
|
||||
FROM node:24-alpine AS backend
|
||||
WORKDIR /app
|
||||
COPY backend/package*.json ./backend/
|
||||
COPY backend/ ./backend/
|
||||
RUN cd backend && npm install
|
||||
|
||||
RUN mkdir -p /data/uploads && chmod -R 777 /data
|
||||
|
||||
# Copy built frontend into backend
|
||||
COPY --from=frontend /app/frontend/dist ./frontend/dist
|
||||
|
||||
WORKDIR /app/backend
|
||||
EXPOSE 3000
|
||||
|
||||
ENV DATA_DIR=/data
|
||||
|
||||
CMD ["node", "index.js"]
|
||||
@@ -6,13 +6,19 @@ const multer = require('multer');
|
||||
const fs = require('fs');
|
||||
|
||||
const app = express();
|
||||
const dbPath = path.join(__dirname, 'db.sqlite');
|
||||
const db = new sqlite3.Database(dbPath);
|
||||
const upload = multer({ dest: path.join(__dirname, 'uploads/') });
|
||||
|
||||
// Use DATA_DIR env var if set, otherwise use local "data" folder
|
||||
const DATA_DIR = process.env.DATA_DIR || path.join(__dirname, 'data');
|
||||
|
||||
const dbPath = path.join(DATA_DIR, 'db.sqlite');
|
||||
const db = new sqlite3.Database(dbPath);
|
||||
const upload = multer({ dest: path.join(DATA_DIR, 'uploads/') });
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
|
||||
app.use('/uploads', express.static(path.join(DATA_DIR, 'uploads')));
|
||||
|
||||
// Create uploads directory if it doesn't exist
|
||||
fs.mkdirSync(path.join(DATA_DIR, 'uploads'), { recursive: true });
|
||||
|
||||
// Initialize database and ensure counters table exists
|
||||
db.serialize(() => {
|
||||
@@ -38,7 +44,6 @@ app.get('/api/counters', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Create a new counter with image
|
||||
app.post('/api/counters', upload.single('image'), (req, res) => {
|
||||
const { name = 'Counter', value = 0 } = req.body;
|
||||
@@ -97,12 +102,20 @@ const clientBuildPath = path.join(__dirname, '..', 'frontend', 'dist');
|
||||
app.use(express.static(clientBuildPath));
|
||||
|
||||
// For SPA: serve index.html for any unknown route (after API and uploads)
|
||||
// app.get('*', (req, res) => {
|
||||
// if (req.path.startsWith('/api') || req.path.startsWith('/uploads')) return res.status(404).end();
|
||||
// res.sendFile(path.join(clientBuildPath, 'index.html'));
|
||||
// });
|
||||
app.get('/*path', (req, res) => {
|
||||
if (req.path.startsWith('/api') || req.path.startsWith('/uploads')) return res.status(404).end();
|
||||
res.sendFile(path.join(clientBuildPath, 'index.html'));
|
||||
});
|
||||
|
||||
const PORT = 3000;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`API server running on http://localhost:${PORT}`);
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('SIGTERM received, shutting down gracefully...');
|
||||
db.close(() => {
|
||||
console.log('Database connection closed.');
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user