Enhance Docker setup and local development: bind database directory, update PHP server command, and add local dev router to prevent exposure of sensitive files
This commit is contained in:
1 parent
02551eebbc
commit
3286bce6b1
6 files changed
+84
-3
No files matched your search
@@ -16,8 +16,15 @@ services:
|
|||||||
- type: bind
|
- type: bind
|
||||||
source: /DATA/AppData/theoldfitz/www
|
source: /DATA/AppData/theoldfitz/www
|
||||||
target: /var/www/html
|
target: /var/www/html
|
||||||
|
# Database lives outside the web root so Apache can't serve it.
|
||||||
|
# FITZ_DATA_DIR defaults to the CasaOS dev host's path; set it in a
|
||||||
|
# .env file next to this compose file on the VPS.
|
||||||
|
- type: bind
|
||||||
|
source: ${FITZ_DATA_DIR:-/DATA/AppData/theoldfitz/data}
|
||||||
|
target: /var/www/data
|
||||||
environment:
|
environment:
|
||||||
- TZ=America/Indiana/Indianapolis
|
- TZ=America/Indiana/Indianapolis
|
||||||
|
- FITZ_DB_PATH=/var/www/data/fitz.sqlite
|
||||||
labels:
|
labels:
|
||||||
icon: https://www.php.net/images/logos/php-logo.svg
|
icon: https://www.php.net/images/logos/php-logo.svg
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -11,12 +11,15 @@ function get_db(): PDO {
|
|||||||
return $pdo;
|
return $pdo;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbDir = __DIR__ . '/../db';
|
// In Docker, FITZ_DB_PATH points outside the web root (see
|
||||||
|
// docker-compose.yaml), so Apache can never serve the file. Local dev
|
||||||
|
// falls back to db/ in the project, which the dev router refuses to serve.
|
||||||
|
$dbPath = getenv('FITZ_DB_PATH') ?: __DIR__ . '/../db/fitz.sqlite';
|
||||||
|
$dbDir = dirname($dbPath);
|
||||||
if (!is_dir($dbDir)) {
|
if (!is_dir($dbDir)) {
|
||||||
mkdir($dbDir, 0755, true);
|
mkdir($dbDir, 0755, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbPath = $dbDir . '/fitz.sqlite';
|
|
||||||
$isNew = !file_exists($dbPath);
|
$isNew = !file_exists($dbPath);
|
||||||
|
|
||||||
$pdo = new PDO('sqlite:' . $dbPath, null, null, [
|
$pdo = new PDO('sqlite:' . $dbPath, null, null, [
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently --kill-others-on-fail \"npm:dev:php\" \"npm:dev:sass\" \"npm:dev:browser\"",
|
"dev": "concurrently --kill-others-on-fail \"npm:dev:php\" \"npm:dev:sass\" \"npm:dev:browser\"",
|
||||||
"dev:php": "php -S localhost:8000",
|
"dev:php": "php -S localhost:8000 scripts/dev-router.php",
|
||||||
"dev:sass": "sass --watch --source-map src/scss/styles.scss:styles.css",
|
"dev:sass": "sass --watch --source-map src/scss/styles.scss:styles.css",
|
||||||
"dev:browser": "browser-sync start --proxy http://localhost:8000 --files \"*.php,admin/**/*.php,inc/**/*.php,main.js,styles.css\" --no-open --no-ui",
|
"dev:browser": "browser-sync start --proxy http://localhost:8000 --files \"*.php,admin/**/*.php,inc/**/*.php,main.js,styles.css\" --no-open --no-ui",
|
||||||
"build:sass": "sass --no-source-map src/scss/styles.scss:styles.css",
|
"build:sass": "sass --no-source-map src/scss/styles.scss:styles.css",
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Router for local dev (`php -S localhost:8000 scripts/dev-router.php`).
|
||||||
|
*
|
||||||
|
* PHP's built-in server ignores .htaccess, so without this it would serve
|
||||||
|
* the SQLite database, includes, and project files to anyone who can
|
||||||
|
* reach it — including other devices on the LAN via browser-sync.
|
||||||
|
* Anything not blocked falls through to the built-in server as normal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$path = rawurldecode(parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/');
|
||||||
|
$path = preg_replace('#/+#', '/', $path);
|
||||||
|
|
||||||
|
// Case-insensitive: macOS's filesystem is, so /DB/fitz.sqlite would match.
|
||||||
|
$blocked = '#^/(?:db|inc|bin|scripts|src|dist|node_modules)(?:/|$)'
|
||||||
|
. '|(?:^|/)\.'
|
||||||
|
. '|^/(?:package(?:-lock)?\.json|docker-compose\.ya?ml|config(?:\.example)?\.php)$#i';
|
||||||
|
|
||||||
|
if (preg_match($blocked, $path)) {
|
||||||
|
http_response_code(404);
|
||||||
|
echo 'Not Found';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
@@ -46,6 +46,30 @@ textarea.form-control {
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Selects: drop the native (rounded, shorter) control so they match the
|
||||||
|
text inputs, and draw the chevron with two gradients instead of an
|
||||||
|
SVG data URI — it can use the theme tokens and needs no `data:` in the
|
||||||
|
CSP's img-src. color-scheme gives the native option list dark colors. */
|
||||||
|
select.form-control {
|
||||||
|
appearance: none;
|
||||||
|
color-scheme: dark;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-right: 2.5rem;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, transparent 50%, var(--gold) 50%),
|
||||||
|
linear-gradient(135deg, var(--gold) 50%, transparent 50%);
|
||||||
|
background-position:
|
||||||
|
calc(100% - 1.2rem) 50%,
|
||||||
|
calc(100% - 0.85rem) 50%;
|
||||||
|
background-size: 0.35rem 0.35rem;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.form-control:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
.error-msg,
|
.error-msg,
|
||||||
.alert-error {
|
.alert-error {
|
||||||
background: var(--danger-bg);
|
background: var(--danger-bg);
|
||||||
|
|||||||
+20
@@ -912,6 +912,26 @@ textarea.form-control {
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Selects: drop the native (rounded, shorter) control so they match the
|
||||||
|
text inputs, and draw the chevron with two gradients instead of an
|
||||||
|
SVG data URI — it can use the theme tokens and needs no `data:` in the
|
||||||
|
CSP's img-src. color-scheme gives the native option list dark colors. */
|
||||||
|
select.form-control {
|
||||||
|
appearance: none;
|
||||||
|
color-scheme: dark;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-right: 2.5rem;
|
||||||
|
background-image: linear-gradient(45deg, transparent 50%, var(--gold) 50%), linear-gradient(135deg, var(--gold) 50%, transparent 50%);
|
||||||
|
background-position: calc(100% - 1.2rem) 50%, calc(100% - 0.85rem) 50%;
|
||||||
|
background-size: 0.35rem 0.35rem;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.form-control:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
.error-msg,
|
.error-msg,
|
||||||
.alert-error {
|
.alert-error {
|
||||||
background: var(--danger-bg);
|
background: var(--danger-bg);
|
||||||
|
|||||||
Reference in new issue
Block a user