Compare commits

..

7 Commits

Author SHA1 Message Date
Kailasdevdas dd5d46c58d feat: update favicon and title 2026-04-21 11:51:14 +05:30
Kailasdevdas 64d720143e feat: add create user script 2026-04-21 11:50:48 +05:30
Kailasdevdas 69d6d5a8f3 fix: align ports and docker config 2026-04-20 16:05:38 +05:30
kailasdevdas 3fc4100a72 Merge pull request 'feat: add bulk excel data import functionality' (#14) from feat/import-excel-data into dev
Reviewed-on: #14
2026-04-20 10:02:06 +00:00
kailasdevdas ddb87d6789 Merge pull request 'feat/docker-setup' (#13) from feat/docker-setup into dev
Reviewed-on: #13
2026-04-20 10:01:35 +00:00
Kailasdevdas 671a3c4e3a feat: docker dev setup 2026-04-20 14:39:29 +05:30
Kailasdevdas e356aa8fd9 chore: remove unused package 2026-04-20 12:35:38 +05:30
13 changed files with 248 additions and 22 deletions
+87
View File
@@ -0,0 +1,87 @@
# Docker Setup (Backend + Frontend + PostgreSQL)
This project provides a complete development environment using **Docker Compose** for:
- Backend (Node.js / Express / Prisma)
- Frontend (Vite / React)
- PostgreSQL Database
---
## Project Structure
```
.
├── backend/
├── frontend/
├── docker/
│ └── dev/
│ ├── Dockerfile.main
│ └── Dockerfile.frontend
├── docker-compose.dev.yml
```
---
## Prerequisites
Make sure you have installed:
- Docker
- Docker Compose
---
## Environment Variables
### Backend (`backend/.env`)
```env
DATABASE_URL=postgresql://user:password@db:5432/mydb
PORT=3000
JWT_SECRET=your_secret_here
CORS_ALLOWED_ORIGINS=http://localhost:5173
BYTESCALE_SECRET_API_KEY=your_key
POSTMARK_API_KEY=your_key
EMAIL_FROM=admin@example.com
```
### Frontend (`frontend/.env`)
```env
VITE_API_BASE_URL=http://localhost:5000
```
---
## Running the Project
### Start containers
```bash
docker compose -f docker-compose.dev.yml up --build
```
---
### Stop containers
```bash
docker compose -f docker-compose.dev.yml down
```
---
## Database (PostgreSQL)
- User: `user`
- Password: `password`
- DB: `mydb`
Data is persisted using Docker volume:
```
postgres_data
```
+2 -1
View File
@@ -8,7 +8,8 @@
"start": "node src/app.js",
"prisma": "prisma",
"migrate": "npx prisma migrate dev",
"generate": "npx prisma generate"
"generate": "npx prisma generate",
"create-user": "node src/utils/createUser.js"
},
"keywords": [],
"author": "",
+1 -2
View File
@@ -1,9 +1,8 @@
import express from "express";
import {register, login} from "../controllers/auth.controller.js";
import { login } from "../controllers/auth.controller.js";
const router = express.Router();
router.post("/register", register);
router.post("/login", login);
export default router;
+47
View File
@@ -0,0 +1,47 @@
import prisma from "../prisma/client.js";
import { hashPassword } from "./password.js";
async function main() {
const username = process.argv[2];
const password = process.argv[3];
const role = process.argv[4] || "admin";
if (!username || !password) {
console.log(
"Usage: node scripts/createUser.js <username> <password> [role]",
);
process.exit(1);
}
const existingUser = await prisma.user.findUnique({
where: { username },
});
if (existingUser) {
console.log("User already exists");
process.exit(1);
}
const hashedPassword = await hashPassword(password);
const user = await prisma.user.create({
data: {
username,
password: hashedPassword,
role,
},
});
console.log("User created:", {
id: user.id,
username: user.username,
role: user.role,
});
}
main()
.catch((e) => {
console.error(e);
})
.finally(async () => {
await prisma.$disconnect();
});
+44
View File
@@ -0,0 +1,44 @@
version: "3.8"
services:
backend:
build:
context: .
dockerfile: docker/dev/Dockerfile.main
ports:
- "5000:3000"
env_file:
- ./backend/.env
depends_on:
db:
condition: service_healthy
restart: unless-stopped
frontend:
build:
context: .
dockerfile: docker/dev/Dockerfile.frontend
ports:
- "3000:3000"
env_file:
- ./frontend/.env
restart: unless-stopped
db:
image: postgres:15-alpine
container_name: postgres_db
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
postgres_data:
+19
View File
@@ -0,0 +1,19 @@
ARG NODE_VERSION=22.11.0
FROM node:${NODE_VERSION}-alpine
WORKDIR /usr/src/app
COPY ./frontend/package*.json ./
RUN npm ci
COPY ./frontend .
# Build the app
RUN npm run build
RUN npm install -g serve
EXPOSE 3000
# Serve built app
CMD ["serve", "-s", "dist"]
+24
View File
@@ -0,0 +1,24 @@
ARG NODE_VERSION=22.11.0
FROM node:${NODE_VERSION}-alpine
WORKDIR /usr/src/app
# Use cache mounts for faster installs
RUN --mount=type=bind,source=backend/package.json,target=package.json \
--mount=type=bind,source=backend/package-lock.json,target=package-lock.json \
--mount=type=cache,target=/root/.npm \
npm ci
# Copy the backend source
COPY ./backend .
# Copy and setup entrypoint
COPY ./docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
EXPOSE 5000
ENTRYPOINT [ "entrypoint.sh" ]
# This '$@' will be replaced by the CMD
CMD ["npm", "start"]
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
set -e # Exit immediately if a command exits with a non-zero status
echo "Generating Prisma Client..."
npx prisma generate
# echo "Running migrate..."
# npx prisma migrate deploy
echo "Running PUSH..."
npx prisma db push
echo "Executing command: $@"
exec "$@"
+10 -10
View File
@@ -1,13 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>frontend</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GG Admin Dashboard</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
-7
View File
@@ -8,7 +8,6 @@
"name": "frontend",
"version": "0.0.0",
"dependencies": {
"@bytescale/sdk": "^3.53.0",
"@editorjs/code": "^2.9.4",
"@editorjs/delimiter": "^1.4.2",
"@editorjs/editorjs": "^2.31.5",
@@ -525,12 +524,6 @@
"node": ">=6.9.0"
}
},
"node_modules/@bytescale/sdk": {
"version": "3.53.0",
"resolved": "https://registry.npmjs.org/@bytescale/sdk/-/sdk-3.53.0.tgz",
"integrity": "sha512-qCeNup3pSjaklXuBrO9JeKbozZEs/PjQEvuqCiOAWLBRl6lDjd0V9gRVYqyttPimXYFoV+J/7dmPWtK6RfOABQ==",
"license": "MIT"
},
"node_modules/@codexteam/icons": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@codexteam/icons/-/icons-0.3.3.tgz",
-1
View File
@@ -10,7 +10,6 @@
"preview": "vite preview"
},
"dependencies": {
"@bytescale/sdk": "^3.53.0",
"@editorjs/code": "^2.9.4",
"@editorjs/delimiter": "^1.4.2",
"@editorjs/editorjs": "^2.31.5",
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB