All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
🗺️ 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
- 🔍 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
│ ├── Dockerfile # Backend container image
│ └── data/
│ └── families.json # Family location data
├── frontend/
│ ├── Dockerfile # Frontend Nginx container
│ ├── nginx.conf # Nginx configuration
│ └── public/
│ ├── index.html # Frontend HTML
│ ├── script.js # Frontend JavaScript
│ └── style.css # Styles
├── public/
│ ├── index.html # Shared frontend files
│ ├── script.js
│ └── style.css
├── Dockerfile # Monolith Docker build
├── docker-compose.yml # Monolith deployment
├── docker-compose.microservices.yml # Microservices deployment
├── .woodpecker.yaml # CI/CD pipeline config
└── .dockerignore # Docker ignore rules
🏗️ Architecture
The application supports two deployment modes:
1. Monolith Mode (Simple)
- Single container with Express serving both API and static files
- Best for: Development, simple deployments
- Use:
docker-compose up
2. Microservices Mode (Production)
- Frontend: Nginx serving static files (Port 80)
- Backend: Express API server (Internal Port 3000)
- Nginx proxies
/api/*requests to backend - Best for: Production, scalability, CI/CD pipelines
- Use:
docker-compose -f docker-compose.microservices.yml up
🚀 Getting Started
Prerequisites
- Node.js (v18 or higher)
- Docker & Docker Compose (optional, for containerized deployment)
Local Development
- Install backend dependencies:
cd backend
npm install
- Start the server:
npm start
- Open your browser:
Navigate to
http://localhost:3000
🐳 Docker Deployment
Monolith Mode (Recommended for Development)
- Build and start:
docker-compose up -d
-
Access: http://localhost:3000
-
Stop:
docker-compose down
Microservices Mode (Recommended for Production)
- Build and start:
docker-compose -f docker-compose.microservices.yml up -d
-
Access: http://localhost (Port 80)
-
View logs:
docker logs oramap-frontend
docker logs oramap-backend
- Stop:
docker-compose -f docker-compose.microservices.yml down
Using Docker directly
Monolith:
docker build -t oramap:latest .
docker run -d -p 3000:3000 --name oramap-app oramap:latest
Microservices:
# Build images
docker build -t oramap-backend -f backend/Dockerfile backend/
docker build -t oramap-frontend -f frontend/Dockerfile frontend/
# Run with network
docker network create oramap-network
docker run -d --name oramap-backend --network oramap-network oramap-backend
docker run -d --name oramap-frontend --network oramap-network -p 80:80 oramap-frontend
🔄 CI/CD Pipeline
The project includes a Woodpecker CI configuration (.woodpecker.yaml) that automatically:
- Builds separate frontend and backend Docker images on push
- Tags images with branch name and commit SHA
- Pushes to Harbor registry (
harbor.dvirlabs.com) - Updates Kubernetes manifests with new image tags
- Triggers on changes to
frontend/**orbackend/**paths
Pipeline Steps:
build-frontend: Build and push frontend Nginx imagebuild-backend: Build and push backend API imageupdate-values-frontend: Update frontend image tag in values.yamlupdate-values-backend: Update backend image tag in values.yaml
💻 Development
Running in Development Mode
cd backend
npm run dev
Adding New Families
Edit backend/data/families.json and add entries in the following format:
{
"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:
curl "http://localhost:3000/api/search?family=Kafe"
Health Check
GET /api/health
Returns server health status.
Example Response:
{
"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!
Description
Languages
JavaScript
61.6%
CSS
23.4%
HTML
7.9%
Dockerfile
6.2%
Smarty
0.9%