commit cd3d9608521697994df97dfb7b2800ed321dbe65 Author: jpmvaz Date: Sun Sep 13 20:18:51 2026 +0100 v_1 diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..615380d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +node_modules +npm-debug.log +.git +.gitignore +README.md +.env +.DS_Store +backup_*.json \ No newline at end of file diff --git a/Martinhal_Contact_Site.7z b/Martinhal_Contact_Site.7z new file mode 100644 index 0000000..90d4f6f Binary files /dev/null and b/Martinhal_Contact_Site.7z differ diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..0f56b9c --- /dev/null +++ b/Readme.md @@ -0,0 +1,183 @@ +# Martinhal Contact Management System - Docker Setup + +## 🐳 Docker Installation (Recommended) + +### Prerequisites +- Docker installed: https://docs.docker.com/get-docker/ +- Docker Compose installed (usually comes with Docker Desktop) + +### Quick Start with Docker + +1. **Make sure you have all files in the same directory:** +``` +martinhal-contacts/ +├── Dockerfile +├── docker-compose.yml +├── .dockerignore +├── index.html +├── credentials.json +├── server.js +├── package.json +└── contacts_data.json (will be created automatically) +``` + +2. **Build and start the container:** +```bash +docker-compose up -d +``` + +3. **Access the application:** +Open your browser and go to: `http://localhost:8000` + +4. **Stop the application:** +```bash +docker-compose down +``` + +5. **View logs:** +```bash +docker-compose logs -f +``` + +### Docker Commands Reference + +**Start the application:** +```bash +docker-compose up -d +``` + +**Stop the application:** +```bash +docker-compose down +``` + +**Restart the application:** +```bash +docker-compose restart +``` + +**View logs:** +```bash +docker-compose logs -f martinhal-contacts +``` + +**Rebuild after code changes:** +```bash +docker-compose down +docker-compose build +docker-compose up -d +``` + +**Access container shell:** +```bash +docker exec -it martinhal-contacts sh +``` + +## 📦 Data Persistence + +Docker volumes ensure your data persists: +- **contacts_data.json** - Your contact database (automatically backed up) +- **backups/** - Directory for backup files + +Even if you delete and recreate containers, your data remains safe! + +## 🔄 Updating the Application + +1. Update your files (index.html, server.js, etc.) +2. Rebuild and restart: +```bash +docker-compose down +docker-compose build +docker-compose up -d +``` + +## 🔐 Current Passwords + +- **Frontend Password**: `ZaAhdf4h8k79598pHD5H3` +- **Backend Username**: `admin` +- **Backend Password**: `yt33PdH9WgAGR5z4SFDf6` + +## 🛠 Troubleshooting + +**Port 8000 already in use:** +Edit `docker-compose.yml` and change the port mapping: +```yaml +ports: + - "3000:8000" # Access via http://localhost:3000 +``` + +**Container won't start:** +```bash +docker-compose logs martinhal-contacts +``` + +**Remove everything and start fresh:** +```bash +docker-compose down +docker system prune -a +docker-compose up -d +``` + +## 📋 Alternative: Manual Setup (No Docker) + +If you don't want to use Docker: + +### Step 1: Install Node.js +Download from: https://nodejs.org/ + +### Step 2: Install Dependencies +```bash +npm install +``` + +### Step 3: Start Server +```bash +npm start +``` + +### Step 4: Open Browser +``` +http://localhost:8000 +``` + +## 🎯 Production Deployment + +For production deployment with Docker: + +1. **Use environment variables for sensitive data** +2. **Set up HTTPS with reverse proxy (nginx)** +3. **Configure automated backups** +4. **Set resource limits in docker-compose.yml** + +Example production docker-compose.yml: +```yaml +version: '3.8' +services: + martinhal-contacts: + build: . + container_name: martinhal-contacts + ports: + - "8000:8000" + volumes: + - ./contacts_data.json:/app/contacts_data.json + - ./backups:/app/backups + restart: always + environment: + - NODE_ENV=production + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M +``` + +## ✅ Benefits of Docker + +- ✅ **Consistent environment** - Works the same everywhere +- ✅ **Easy deployment** - One command to start +- ✅ **Isolated** - Doesn't interfere with other apps +- ✅ **Easy updates** - Rebuild and restart +- ✅ **Data persistence** - Your data is safe +- ✅ **Easy backups** - Just copy the volume + +That's it! Your Martinhal Contact Management System is now running in Docker! 🎉 \ No newline at end of file diff --git a/credentials.json b/credentials.json new file mode 100644 index 0000000..079905e --- /dev/null +++ b/credentials.json @@ -0,0 +1,10 @@ +{ + "salt": "Mh7pQ2xR9nF8sT4vY3", + "frontend": { + "password": "Fwl2GDVUTDoBBXEBRm0MBhF3eCAE" + }, + "backend": { + "username": "LAxaGT8=", + "password": "NBwEQwFWMGtuCQd/IWFOQgp1CQ4B" + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..32c08ae --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.8' + +services: + martinhal-contacts: + build: . + container_name: martinhal-contacts + ports: + - "8000:8000" + volumes: + - contacts-data:/app/data + restart: unless-stopped + environment: + - NODE_ENV=production + +volumes: + contacts-data: \ No newline at end of file diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..6236aa2 --- /dev/null +++ b/dockerfile @@ -0,0 +1,24 @@ +FROM node:18-alpine + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package.json ./ + +# Install dependencies +RUN npm install + +# Copy application files +COPY index.html ./ +COPY credentials.json ./ +COPY server.js ./ + +# Create backups directory +RUN mkdir -p /app/backups + +# Expose port +EXPOSE 8000 + +# Start the server +CMD ["npm", "start"] \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..2475bdc --- /dev/null +++ b/index.html @@ -0,0 +1,425 @@ + + + + + +Martinhal Contacts + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..4c7649a --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "martinhal-contacts", + "version": "1.0.0", + "description": "Martinhal Contact Management System", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "express": "^4.18.2", + "cors": "^2.8.5" + } +} \ No newline at end of file diff --git a/server.js b/server.js new file mode 100644 index 0000000..a75f0c9 --- /dev/null +++ b/server.js @@ -0,0 +1,95 @@ +const express = require('express'); +const fs = require('fs'); +const path = require('path'); +const cors = require('cors'); + +const app = express(); +const PORT = 8000; + +// Middleware +app.use(cors()); +app.use(express.json({ limit: '50mb' })); // Increased limit for base64 images +app.use(express.static(__dirname)); // Serve static files from current directory + +const DATA_FILE = path.join(__dirname, 'contacts_data.json'); +const CREDENTIALS_FILE = path.join(__dirname, 'credentials.json'); + +// Initialize data file if it doesn't exist +if (!fs.existsSync(DATA_FILE)) { + const initialData = { + contacts: [ + { id: 1, name: 'John Smith', unit: 'Marketing', phone: '+351 123 456 789', mobile: '+351 987 654 321', email: 'john.smith@company.com', department: 'IT', locations: ['Martinhal Oriente'], photo: 'https://i.pravatar.cc/150?img=12' }, + { id: 2, name: 'Maria Santos', unit: 'Finance', phone: '+351 123 456 790', mobile: '+351 987 654 322', email: 'maria.santos@company.com', department: 'Accounting', locations: ['Martinhal Lisbon', 'Martinhal Quinta'], photo: 'https://i.pravatar.cc/150?img=5' }, + { id: 3, name: 'Pedro Costa', unit: 'Operations', phone: '+351 123 456 791', mobile: '+351 987 654 323', email: 'pedro.costa@company.com', department: 'Maintenance', locations: ['Martinhal Sagres'], photo: 'https://i.pravatar.cc/150?img=33' } + ], + departments: ['IT', 'Accounting', 'Board', 'Housekeeping', 'Maintenance'], + locations: ['Martinhal Oriente', 'Martinhal Lisbon', 'Martinhal Quinta', 'Martinhal Sagres'] + }; + fs.writeFileSync(DATA_FILE, JSON.stringify(initialData, null, 2)); + console.log('Created initial data file:', DATA_FILE); +} + +// Check if credentials.json exists +if (!fs.existsSync(CREDENTIALS_FILE)) { + console.error('WARNING: credentials.json not found!'); + console.error('Please make sure credentials.json is in the same directory as server.js'); +} + +// Get credentials (for debugging) +app.get('/api/credentials', (req, res) => { + try { + if (!fs.existsSync(CREDENTIALS_FILE)) { + return res.status(404).json({ error: 'credentials.json not found' }); + } + const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_FILE, 'utf8')); + res.json(credentials); + } catch (error) { + console.error('Error reading credentials:', error); + res.status(500).json({ error: 'Failed to read credentials' }); + } +}); + +// Get all data +app.get('/api/data', (req, res) => { + try { + const data = JSON.parse(fs.readFileSync(DATA_FILE, 'utf8')); + res.json(data); + } catch (error) { + console.error('Error reading data:', error); + res.status(500).json({ error: 'Failed to read data' }); + } +}); + +// Save all data +app.post('/api/data', (req, res) => { + try { + fs.writeFileSync(DATA_FILE, JSON.stringify(req.body, null, 2)); + res.json({ success: true }); + } catch (error) { + console.error('Error saving data:', error); + res.status(500).json({ error: 'Failed to save data' }); + } +}); + +// Backup endpoint (optional - creates timestamped backup) +app.post('/api/backup', (req, res) => { + try { + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const backupFile = path.join(__dirname, `backup_${timestamp}.json`); + const data = fs.readFileSync(DATA_FILE, 'utf8'); + fs.writeFileSync(backupFile, data); + res.json({ success: true, file: backupFile }); + } catch (error) { + console.error('Error creating backup:', error); + res.status(500).json({ error: 'Failed to create backup' }); + } +}); + +app.listen(PORT, () => { + console.log('================================='); + console.log(`Server running at http://localhost:${PORT}`); + console.log(`Data file: ${DATA_FILE}`); + console.log(`Credentials file: ${CREDENTIALS_FILE}`); + console.log(`Credentials exists: ${fs.existsSync(CREDENTIALS_FILE)}`); + console.log('================================='); +}); \ No newline at end of file