Convert to full-stack app with Docker support
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

- Restructured app with backend/ and public/ directories
- Created Express backend with /api/search endpoint
- Added health check endpoint at /api/health
- Optimized Dockerfile with multi-stage build
- Added docker-compose.yml for easy deployment
- Updated README with comprehensive documentation
- Added .dockerignore for optimized builds
- Backend listens on 0.0.0.0 for Docker compatibility
This commit is contained in:
dvirlabs 2026-03-24 08:47:26 +02:00
parent 20f41d6030
commit 5a7585f755
7 changed files with 325 additions and 5 deletions

50
.dockerignore Normal file
View File

@ -0,0 +1,50 @@
# Dependencies
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Git
.git/
.gitignore
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Docker
Dockerfile
docker-compose.yml
.dockerignore
# Kubernetes
oramap/
# Build artifacts
dist/
build/
# Other
old-project/
frontend/node_modules/
README copy.md
*.md
!backend/
!public/
run_ora_map.sh
nfsshare/
nul

View File

@ -1,10 +1,35 @@
FROM node:24-slim # Multi-stage build for Ora Map Application
FROM node:20-alpine AS base
# Production stage
FROM base AS production
WORKDIR /app WORKDIR /app
COPY package*.json ./ # Copy backend package files
RUN npm install COPY backend/package*.json ./backend/
WORKDIR /app/backend
RUN npm install --production
COPY . . # Copy backend source and data
COPY backend/ ./
WORKDIR /app
# Copy public frontend files
COPY public/ ./public/
# Expose port
EXPOSE 3000
# Set environment variable
ENV NODE_ENV=production
ENV PORT=3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
# Start the application
WORKDIR /app/backend
CMD ["node", "server.js"] CMD ["node", "server.js"]

180
README.md
View File

@ -0,0 +1,180 @@
# 🗺️ Ora Map - Family Location Mapping Application
A full-stack web application for mapping and searching family locations in Yemen using interactive maps.
## 📋 Table of Contents
- [Features](#features)
- [Tech Stack](#tech-stack)
- [Project Structure](#project-structure)
- [Getting Started](#getting-started)
- [Docker Deployment](#docker-deployment)
- [Development](#development)
- [API Endpoints](#api-endpoints)
## ✨ Features
- 🔍 **Family Search**: Search for families by name with autocomplete suggestions
- 🗺️ **Interactive Map**: Leaflet-based map with multiple tile layer options
- 📍 **Location Markers**: View family locations with city information
- 🎨 **Modern UI**: Clean and responsive design
- 🐳 **Docker Ready**: Containerized for easy deployment
- 💚 **Health Checks**: Built-in health monitoring
## 🛠️ Tech Stack
**Backend:**
- Node.js
- Express.js
- JSON data storage
**Frontend:**
- HTML5/CSS3
- JavaScript (ES6+)
- Leaflet.js (interactive maps)
- Fuse.js (fuzzy search)
**DevOps:**
- Docker
- Docker Compose
## 📁 Project Structure
```
oramap/
├── backend/
│ ├── server.js # Express server
│ ├── package.json # Backend dependencies
│ └── data/
│ └── families.json # Family location data
├── public/
│ ├── index.html # Frontend HTML
│ ├── script.js # Frontend JavaScript
│ └── style.css # Styles
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Docker Compose configuration
└── .dockerignore # Docker ignore rules
```
## 🚀 Getting Started
### Prerequisites
- Node.js (v18 or higher)
- Docker & Docker Compose (optional, for containerized deployment)
### Local Development
1. **Install backend dependencies:**
```bash
cd backend
npm install
```
2. **Start the server:**
```bash
npm start
```
3. **Open your browser:**
Navigate to `http://localhost:3000`
## 🐳 Docker Deployment
### Using Docker Compose (Recommended)
1. **Build and start the application:**
```bash
docker-compose up -d
```
2. **View logs:**
```bash
docker-compose logs -f
```
3. **Stop the application:**
```bash
docker-compose down
```
### Using Docker directly
1. **Build the image:**
```bash
docker build -t oramap:latest .
```
2. **Run the container:**
```bash
docker run -d -p 3000:3000 --name oramap-app oramap:latest
```
3. **Check health:**
```bash
docker ps
```
## 💻 Development
### Running in Development Mode
```bash
cd backend
npm run dev
```
### Adding New Families
Edit `backend/data/families.json` and add entries in the following format:
```json
{
"family": "Family Name (Hebrew)",
"city": "City Name (Hebrew)",
"lat": 15.3545,
"lng": 44.2064
}
```
## 📡 API Endpoints
### Search Families
```
GET /api/search?family={familyName}
```
Returns matching family records with location data.
**Example:**
```bash
curl "http://localhost:3000/api/search?family=Kafe"
```
### Health Check
```
GET /api/health
```
Returns server health status.
**Example Response:**
```json
{
"status": "ok",
"timestamp": "2026-03-24T10:30:00.000Z"
}
```
## 🗺️ Available Family Names
- Kafe (קאפח)
- Shiheb (שחב-שבח)
- Uzeyri (עזירי-עוזרי)
- Salumi (סלומי-שלומי)
- Afgin (עפג'ין)
- Eraki (עראקי)
## 📝 License
ISC
## 🤝 Contributing
Contributions, issues, and feature requests are welcome!

View File

@ -0,0 +1,10 @@
[
{ "family": "Kafe (קאפח)", "city": "Sana'a (צנעא)", "lat": 15.3545, "lng": 44.2064 },
{ "family": "Shiheb (שחב-שבח)", "city": "Sana'a (צנעא)", "lat": 15.3545, "lng": 44.2064 },
{ "family": "Uzeyri (עזירי-עוזרי)", "city": "Sana'a (צנעא)", "lat": 15.3545, "lng": 44.2064 },
{ "family": "Uzeyri (עזירי-עוזרי)", "city": "Manakhah (מנאכה)", "lat": 15.3019, "lng": 43.5983 },
{ "family": "Uzeyri (עזירי-עוזרי)", "city": "Dhamar (ד'מאר)", "lat": 14.5424, "lng": 44.4056 },
{ "family": "Salumi (סלומי-שלומי)", "city": "Al Kafla (אל קפלה)", "lat": 16.0240, "lng": 43.9790 },
{ "family": "Afgin (עפג'ין)", "city": "Sa'dah (צעדה)", "lat": 16.9402, "lng": 43.7639 },
{ "family": "Eraki (עראקי)", "city": "Sana'a (צנעא)", "lat": 15.3545, "lng": 44.2064 }
]

28
backend/server.js Normal file
View File

@ -0,0 +1,28 @@
const express = require('express');
const path = require('path');
const app = express();
const families = require('./data/families.json');
// Serve static files from the public directory
app.use(express.static(path.join(__dirname, '../public')));
// API endpoint for family search
app.get('/api/search', (req, res) => {
const query = req.query.family?.toLowerCase();
if (!query) {
return res.json([]);
}
const matches = families.filter(fam => fam.family.toLowerCase().includes(query));
res.json(matches);
});
// Health check endpoint
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
const port = process.env.PORT || 3000;
app.listen(port, '0.0.0.0', () => {
console.log(`🗺️ Ora Map Server running at http://localhost:${port}`);
console.log(`📍 API endpoint: http://localhost:${port}/api/search`);
});

27
docker-compose.yml Normal file
View File

@ -0,0 +1,27 @@
version: '3.8'
services:
oramap:
build:
context: .
dockerfile: Dockerfile
image: oramap:latest
container_name: oramap-app
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
restart: unless-stopped
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
networks:
- oramap-network
networks:
oramap-network:
driver: bridge

View File

@ -32,7 +32,7 @@ async function searchFamily() {
} }
try { try {
const response = await fetch(`/search?family=${encodeURIComponent(familyName)}`); const response = await fetch(`/api/search?family=${encodeURIComponent(familyName)}`);
const familyResult = await response.json(); const familyResult = await response.json();
if (!familyResult.length) { if (!familyResult.length) {