Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/deploy-demo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Deploy Demo Instance

on:
push:
branches:
- main
- dev

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install Frontend Dependencies & Build
env:
VITE_API_BASE_URL: "https://nester-demo.philip.ps/backend/api"
run: |
echo "Building with VITE_API_BASE_URL=$VITE_API_BASE_URL"
npm ci
npm run build
echo "Verifying compiled output does not contain tabit:"
grep -r "tabit" dist/ || echo "OK: no 'tabit' found in build output"
# Move compiled frontend to root so rsync uploads it to the base path
rsync -a dist/ ./

- name: Deploy via rsync
uses: easingthemes/ssh-deploy@v5.0.3
with:
SSH_PRIVATE_KEY: ${{ secrets.DEMO_SSH_KEY }}
ARGS: "-avzr --delete"
SOURCE: "/"
TARGET: "/home/philippsnesterdemo/web/nester-demo/"
REMOTE_HOST: ${{ secrets.DEMO_HOST }}
REMOTE_USER: ${{ secrets.DEMO_USERNAME }}
EXCLUDE: "/node_modules/, /.git/, /.github/, /src/, /public/, /vite.config.js, /package.json, /package-lock.json, /README.md, /eslint.config.js, /docs/, /CONTRIBUTING.md, /sync_www.command, /backend/uploads/, /backend/create_admin.php, /.DS_Store, /.env, /dist/, /INSTALLATION.md, /LICENSE, /.gitignore, /.env.example"

- name: Redeploy Database & Set Permissions
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.DEMO_HOST }}
username: ${{ secrets.DEMO_USERNAME }}
key: ${{ secrets.DEMO_SSH_KEY }}
script: |
cd /home/philippsnesterdemo/web/nester-demo/backend

# Since you wanted the database redeployed on every deployment,
# we run a PHP script to clean it, apply schema, and create users.
php -r "
require 'api/db.php';
try {
\$pdo->query('SET FOREIGN_KEY_CHECKS = 0');
\$tables = \$pdo->query('SHOW TABLES')->fetchAll(PDO::FETCH_COLUMN);
foreach (\$tables as \$table) {
\$pdo->query('DROP TABLE IF EXISTS \`' . \$table . '\`');
}

\$sql = file_get_contents('schema.sql');
// Strip statements that might cause permission errors on shared hosting
\$sql = preg_replace('/\bCREATE\s+DATABASE\b[^;]+;/i', '', \$sql);
\$sql = preg_replace('/\bUSE\b\s+[^;]+;/i', '', \$sql);
\$pdo->exec(\$sql);

\$pdo->query('SET FOREIGN_KEY_CHECKS = 1');

\$adminHash = password_hash('admin123', PASSWORD_DEFAULT);
\$demoHash = password_hash('demo123', PASSWORD_DEFAULT);

\$stmt = \$pdo->prepare('INSERT INTO users (id, username, email, password_hash, is_admin) VALUES (?, ?, ?, ?, ?)');
\$stmt->execute([bin2hex(random_bytes(18)), 'admin', 'admin@example.com', \$adminHash, 1]);
\$stmt->execute([bin2hex(random_bytes(18)), 'demo', 'demo@example.com', \$demoHash, 0]);

echo \"Database successfully cleaned, schema imported, and users created!\n\";
} catch (Exception \$e) {
echo \"DB Error: \" . \$e->getMessage() . \"\n\";
exit(1);
}
"

# Fix permissions for the webserver (assuming the usual www-data or client user)
# chown -R web21:client1 /home/philippsnesterdemo/web/nester-demo/ || true
# find /home/philippsnesterdemo/web/nester-demo/ -type d -exec chmod 755 {} \;
# find /home/philippsnesterdemo/web/nester-demo/ -type f -exec chmod 644 {} \;
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ NesterApp ist eine Open-Source-Webanwendung zur Erfassung und Verwaltung von Tau
- **Standortverfolgung**: Automatische Benennung basierend auf OpenStreetMap-Einrichtungen oder Straßenadressen.
- **PWA-fähig**: Kann auf Mobilgeräten für die Berichterstattung von unterwegs installiert werden.

## Demo

Eine Live-Demo ist verfügbar unter: **[nester-demo.philip.ps](https://nester-demo.philip.ps)**

> **Hinweis:** Die Demo-Datenbank wird bei jedem Deployment automatisch zurückgesetzt.

| Konto | Benutzername | Passwort | Rolle |
|-------|-------------|----------|-------|
| Admin | `admin` | `admin123` | Administrator |
| Demo | `demo` | `demo123` | Standardbenutzer |

## Erste Schritte

Siehe [INSTALLATION.md](INSTALLATION.md) für Anweisungen zur Einrichtung der lokalen Entwicklungsumgebung und zur Bereitstellung in der Produktion.
Expand Down
43 changes: 22 additions & 21 deletions backend/api/db.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@

require_once dirname(__DIR__) . '/config.php';

// Function to handle CORS so the React app can communicate with this API
function set_cors_headers()
{
// Allow any localhost origin (like frontend on 5173)
if (isset($_SERVER['HTTP_ORIGIN']) && strpos($_SERVER['HTTP_ORIGIN'], 'localhost') !== false) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
} else {
header("Access-Control-Allow-Origin: *");
}
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");

// Handle preflight requests
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
exit(0);
}
}

// Set JSON header and CORS for all API endpoints including this file
header('Content-Type: application/json');
set_cors_headers();

$host = get_config('DB_HOST', 'localhost');
$db = get_config('DB_NAME', 'nester_db');
$user = get_config('DB_USER', 'root');
Expand All @@ -26,25 +48,4 @@
exit;
}

// Function to handle CORS so the React app (port 5173) can communicate with this API
function set_cors_headers()
{
// Allow any localhost origin (like frontend on 5173)
if (isset($_SERVER['HTTP_ORIGIN']) && strpos($_SERVER['HTTP_ORIGIN'], 'localhost') !== false) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
} else {
header("Access-Control-Allow-Origin: *");
}
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");

// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
exit(0);
}
}

// Set JSON header and CORS for all API endpoints including this file
header('Content-Type: application/json');
set_cors_headers();
?>
11 changes: 4 additions & 7 deletions backend/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@ ALTER TABLE `taubennest_logs`
ADD KEY `nest_id` (`nest_id`),
ADD KEY `user_id` (`user_id`);

--
-- Constraints
--
ALTER TABLE `taubennest_logs`
ADD CONSTRAINT `taubennest_logs_ibfk_1` FOREIGN KEY (`nest_id`) REFERENCES `taubennester` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `taubennest_logs_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL;

-- --------------------------------------------------------

--
Expand Down Expand Up @@ -119,6 +112,10 @@ ALTER TABLE `password_resets`
ALTER TABLE `user_tokens`
ADD CONSTRAINT `user_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE;

ALTER TABLE `taubennest_logs`
ADD CONSTRAINT `taubennest_logs_ibfk_1` FOREIGN KEY (`nest_id`) REFERENCES `taubennester` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `taubennest_logs_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL;

-- --------------------------------------------------------

--
Expand Down
Loading