generated from bisco/codex-bootstrap
feat: use host bind mounts for persistent data
This commit is contained in:
@@ -22,3 +22,18 @@ LETSENCRYPT_STAGING=1
|
|||||||
LETSENCRYPT_RENEW_INTERVAL_SECONDS=43200
|
LETSENCRYPT_RENEW_INTERVAL_SECONDS=43200
|
||||||
LETSENCRYPT_RETRY_SECONDS=300
|
LETSENCRYPT_RETRY_SECONDS=300
|
||||||
TLS_RELOAD_INTERVAL_SECONDS=30
|
TLS_RELOAD_INTERVAL_SECONDS=30
|
||||||
|
|
||||||
|
# Host-based persistent volumes. Relative paths are resolved from the project root.
|
||||||
|
DB_DATA_PATH=./runtime/db
|
||||||
|
WORDPRESS_DATA_PATH=./runtime/wordpress
|
||||||
|
LETSENCRYPT_DATA_PATH=./runtime/letsencrypt
|
||||||
|
CERTBOT_CHALLENGES_PATH=./runtime/certbot/www
|
||||||
|
|
||||||
|
# Expected container owners for host-based volumes.
|
||||||
|
# MariaDB's official image normally uses mysql 999:999; WordPress uses www-data 33:33.
|
||||||
|
MARIADB_VOLUME_UID=999
|
||||||
|
MARIADB_VOLUME_GID=999
|
||||||
|
WORDPRESS_VOLUME_UID=33
|
||||||
|
WORDPRESS_VOLUME_GID=33
|
||||||
|
CERTBOT_VOLUME_UID=0
|
||||||
|
CERTBOT_VOLUME_GID=0
|
||||||
|
|||||||
@@ -3,5 +3,6 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
backups/
|
backups/
|
||||||
|
runtime/
|
||||||
tests/functional/test-results/
|
tests/functional/test-results/
|
||||||
tests/functional/playwright-report/
|
tests/functional/playwright-report/
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ No host PHP, database, Node.js, or WordPress installation is required.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
|
./scripts/prepare-host-volumes.sh
|
||||||
docker compose up --build -d
|
docker compose up --build -d
|
||||||
docker compose --profile tools run --rm wp-cli /scripts/bootstrap.sh
|
docker compose --profile tools run --rm wp-cli /scripts/bootstrap.sh
|
||||||
docker compose ps
|
docker compose ps
|
||||||
@@ -44,6 +45,20 @@ Open:
|
|||||||
Use the development credentials copied into `.env` only locally. Change them before
|
Use the development credentials copied into `.env` only locally. Change them before
|
||||||
sharing the environment.
|
sharing the environment.
|
||||||
|
|
||||||
|
Persistent data uses host-based bind mounts by default:
|
||||||
|
|
||||||
|
- `./runtime/db` for MariaDB;
|
||||||
|
- `./runtime/wordpress` for WordPress core, uploads, themes, and mu-plugins copied at
|
||||||
|
container startup;
|
||||||
|
- `./runtime/letsencrypt` for certificates;
|
||||||
|
- `./runtime/certbot/www` for ACME HTTP-01 challenges.
|
||||||
|
|
||||||
|
Run `./scripts/prepare-host-volumes.sh` before the first start, especially on Linux
|
||||||
|
hosts. The script reads `.env`, creates the directories, and assigns the expected
|
||||||
|
container owners (`999:999` for MariaDB, `33:33` for WordPress, `0:0` for Certbot).
|
||||||
|
Override the `*_DATA_PATH` and `*_VOLUME_UID/GID` variables in `.env` if your runtime
|
||||||
|
uses different host paths or image user IDs.
|
||||||
|
|
||||||
## Edit content
|
## Edit content
|
||||||
|
|
||||||
- **Appearance > Customize**: hero, manifesto, laboratory, teacher, lessons, contacts,
|
- **Appearance > Customize**: hero, manifesto, laboratory, teacher, lessons, contacts,
|
||||||
@@ -109,10 +124,10 @@ docker compose config --quiet
|
|||||||
Back up the database and WordPress files at the same logical point in time:
|
Back up the database and WordPress files at the same logical point in time:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p backups/wordpress-files
|
|
||||||
docker compose stop wordpress
|
docker compose stop wordpress
|
||||||
|
mkdir -p backups
|
||||||
docker compose exec -T db sh -c 'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE"' > backups/database.sql
|
docker compose exec -T db sh -c 'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE"' > backups/database.sql
|
||||||
docker compose cp wordpress:/var/www/html/. backups/wordpress-files/
|
tar -C runtime -czf backups/wordpress-files.tgz wordpress
|
||||||
docker compose start wordpress
|
docker compose start wordpress
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -121,6 +136,7 @@ Do not commit backups or `.env`. Encrypt and test real backups off-host. See
|
|||||||
|
|
||||||
## Rollback
|
## Rollback
|
||||||
|
|
||||||
Revert the application commit and rebuild containers. Preserve `db_data`,
|
Revert the application commit and rebuild containers. Preserve the host directories
|
||||||
`wordpress_data`, and certificate volumes. Database restoration is a separate,
|
configured by `DB_DATA_PATH`, `WORDPRESS_DATA_PATH`, `LETSENCRYPT_DATA_PATH`, and
|
||||||
destructive operation and requires a verified backup.
|
`CERTBOT_CHALLENGES_PATH`. Database restoration is a separate, destructive operation
|
||||||
|
and requires a verified backup.
|
||||||
|
|||||||
+37
-13
@@ -12,7 +12,11 @@ services:
|
|||||||
entrypoint: ["/bin/sh", "/usr/local/bin/check-environment.sh"]
|
entrypoint: ["/bin/sh", "/usr/local/bin/check-environment.sh"]
|
||||||
command: ["mariadbd"]
|
command: ["mariadbd"]
|
||||||
volumes:
|
volumes:
|
||||||
- db_data:/var/lib/mysql
|
- type: bind
|
||||||
|
source: ${DB_DATA_PATH:-./runtime/db}
|
||||||
|
target: /var/lib/mysql
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
- ./db/check-environment.sh:/usr/local/bin/check-environment.sh:ro
|
- ./db/check-environment.sh:/usr/local/bin/check-environment.sh:ro
|
||||||
networks:
|
networks:
|
||||||
- data
|
- data
|
||||||
@@ -55,7 +59,11 @@ services:
|
|||||||
define('DISALLOW_FILE_MODS', true);
|
define('DISALLOW_FILE_MODS', true);
|
||||||
}
|
}
|
||||||
volumes:
|
volumes:
|
||||||
- wordpress_data:/var/www/html
|
- type: bind
|
||||||
|
source: ${WORDPRESS_DATA_PATH:-./runtime/wordpress}
|
||||||
|
target: /var/www/html
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
networks:
|
networks:
|
||||||
- web
|
- web
|
||||||
- data
|
- data
|
||||||
@@ -85,8 +93,18 @@ services:
|
|||||||
TLS_RELOAD_INTERVAL_SECONDS: ${TLS_RELOAD_INTERVAL_SECONDS:-30}
|
TLS_RELOAD_INTERVAL_SECONDS: ${TLS_RELOAD_INTERVAL_SECONDS:-30}
|
||||||
TRUST_PROXY_HEADERS: ${TRUST_PROXY_HEADERS:-0}
|
TRUST_PROXY_HEADERS: ${TRUST_PROXY_HEADERS:-0}
|
||||||
volumes:
|
volumes:
|
||||||
- letsencrypt_data:/etc/letsencrypt:ro
|
- type: bind
|
||||||
- certbot_challenges:/var/www/certbot:ro
|
source: ${LETSENCRYPT_DATA_PATH:-./runtime/letsencrypt}
|
||||||
|
target: /etc/letsencrypt
|
||||||
|
read_only: true
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
|
- type: bind
|
||||||
|
source: ${CERTBOT_CHALLENGES_PATH:-./runtime/certbot/www}
|
||||||
|
target: /var/www/certbot
|
||||||
|
read_only: true
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
networks:
|
networks:
|
||||||
- web
|
- web
|
||||||
ports:
|
ports:
|
||||||
@@ -119,8 +137,16 @@ services:
|
|||||||
entrypoint: ["/bin/sh", "/opt/certbot/renew.sh"]
|
entrypoint: ["/bin/sh", "/opt/certbot/renew.sh"]
|
||||||
volumes:
|
volumes:
|
||||||
- ./certbot/renew.sh:/opt/certbot/renew.sh:ro
|
- ./certbot/renew.sh:/opt/certbot/renew.sh:ro
|
||||||
- letsencrypt_data:/etc/letsencrypt
|
- type: bind
|
||||||
- certbot_challenges:/var/www/certbot
|
source: ${LETSENCRYPT_DATA_PATH:-./runtime/letsencrypt}
|
||||||
|
target: /etc/letsencrypt
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
|
- type: bind
|
||||||
|
source: ${CERTBOT_CHALLENGES_PATH:-./runtime/certbot/www}
|
||||||
|
target: /var/www/certbot
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
tmpfs:
|
tmpfs:
|
||||||
- /tmp
|
- /tmp
|
||||||
- /var/lib/letsencrypt
|
- /var/lib/letsencrypt
|
||||||
@@ -159,7 +185,11 @@ services:
|
|||||||
entrypoint: ["/bin/sh"]
|
entrypoint: ["/bin/sh"]
|
||||||
command: ["/scripts/bootstrap.sh"]
|
command: ["/scripts/bootstrap.sh"]
|
||||||
volumes:
|
volumes:
|
||||||
- wordpress_data:/var/www/html
|
- type: bind
|
||||||
|
source: ${WORDPRESS_DATA_PATH:-./runtime/wordpress}
|
||||||
|
target: /var/www/html
|
||||||
|
bind:
|
||||||
|
create_host_path: true
|
||||||
- ./wp-cli/bootstrap.sh:/scripts/bootstrap.sh:ro
|
- ./wp-cli/bootstrap.sh:/scripts/bootstrap.sh:ro
|
||||||
networks:
|
networks:
|
||||||
- data
|
- data
|
||||||
@@ -175,12 +205,6 @@ services:
|
|||||||
- ALL
|
- ALL
|
||||||
pids_limit: 100
|
pids_limit: 100
|
||||||
|
|
||||||
volumes:
|
|
||||||
db_data:
|
|
||||||
wordpress_data:
|
|
||||||
letsencrypt_data:
|
|
||||||
certbot_challenges:
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
web:
|
web:
|
||||||
data:
|
data:
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ sanitized theme modifications, while a must-use plugin owns Shows and Gallery cu
|
|||||||
post types so structured content is not lost when changing themes.
|
post types so structured content is not lost when changing themes.
|
||||||
|
|
||||||
NGINX is the only public entry point. WP-CLI provides an idempotent opt-in bootstrap;
|
NGINX is the only public entry point. WP-CLI provides an idempotent opt-in bootstrap;
|
||||||
Certbot provides opt-in direct TLS. Docker networks isolate the database and functional
|
Certbot provides opt-in direct TLS. Docker networks isolate the database. Runtime state
|
||||||
tests use separate volumes.
|
uses host-based bind mounts with a preparation script for ownership/mode, while
|
||||||
|
functional tests use separate Docker volumes.
|
||||||
|
|
||||||
## Consequences
|
## Consequences
|
||||||
|
|
||||||
@@ -48,11 +49,12 @@ headers, and fail-closed TLS. Admin MFA and allowlisting remain external control
|
|||||||
## Operational impact
|
## Operational impact
|
||||||
|
|
||||||
Database and WordPress files are coordinated state and must be backed up together.
|
Database and WordPress files are coordinated state and must be backed up together.
|
||||||
|
Host bind-mount paths must be permissioned for the image users before startup.
|
||||||
Operators must monitor upstream security releases and rebuild pinned images. SMTP and
|
Operators must monitor upstream security releases and rebuild pinned images. SMTP and
|
||||||
off-host storage are not part of this minimal base.
|
off-host storage are not part of this minimal base.
|
||||||
|
|
||||||
## Rollback
|
## Rollback
|
||||||
|
|
||||||
Revert the implementation commit and rebuild. Preserve WordPress, database, and
|
Revert the implementation commit and rebuild. Preserve the configured WordPress,
|
||||||
certificate volumes unless data deletion is intentional. Restore data only from a
|
database, and certificate host directories unless data deletion is intentional. Restore
|
||||||
verified coordinated backup.
|
data only from a verified coordinated backup.
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ activates the theme, configures the site, and creates realistic demo content. Ce
|
|||||||
another optional service, enabled only for direct deployments. It shares challenge and
|
another optional service, enabled only for direct deployments. It shares challenge and
|
||||||
certificate volumes with NGINX but has no container-control access.
|
certificate volumes with NGINX but has no container-control access.
|
||||||
|
|
||||||
Persistent state lives in `db_data`, `wordpress_data`, and the certificate volumes.
|
Persistent state lives in host-based bind mounts configured by `DB_DATA_PATH`,
|
||||||
Functional tests replace the first two with isolated test volumes and reach NGINX via
|
`WORDPRESS_DATA_PATH`, `LETSENCRYPT_DATA_PATH`, and `CERTBOT_CHALLENGES_PATH`.
|
||||||
an internal `azionelab.org` network alias.
|
Functional tests replace the database and WordPress mounts with isolated Docker test
|
||||||
|
volumes and reach NGINX via an internal `azionelab.org` network alias.
|
||||||
|
|
||||||
See [ADR-0001](adr/0001-wordpress-single-page.md).
|
See [ADR-0001](adr/0001-wordpress-single-page.md).
|
||||||
|
|||||||
+18
-4
@@ -12,6 +12,19 @@ docker compose --profile tools run --rm wp-cli /scripts/bootstrap.sh
|
|||||||
NGINX binds to loopback ports 8080/8443. WordPress and MariaDB remain private. The
|
NGINX binds to loopback ports 8080/8443. WordPress and MariaDB remain private. The
|
||||||
bootstrap is safe to rerun and does not duplicate demo records.
|
bootstrap is safe to rerun and does not duplicate demo records.
|
||||||
|
|
||||||
|
The default persistent paths are host-based bind mounts under `./runtime`. Before the
|
||||||
|
first start, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/prepare-host-volumes.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The script reads `.env`, creates the configured paths, and applies the expected
|
||||||
|
container ownership. For Linux hosts this avoids the common problem where Docker
|
||||||
|
creates missing bind-mount directories as `root:root` and WordPress or MariaDB later
|
||||||
|
cannot write to them. If a platform uses different image UIDs/GIDs, override
|
||||||
|
`MARIADB_VOLUME_UID/GID`, `WORDPRESS_VOLUME_UID/GID`, or `CERTBOT_VOLUME_UID/GID`.
|
||||||
|
|
||||||
## Production
|
## Production
|
||||||
|
|
||||||
Required controls:
|
Required controls:
|
||||||
@@ -35,7 +48,8 @@ behavior, removing only the staging certificate volume when necessary.
|
|||||||
|
|
||||||
## State and rollback
|
## State and rollback
|
||||||
|
|
||||||
Database and WordPress file volumes must be backed up together. Code rollback is a
|
Database and WordPress file directories must be backed up together. Code rollback is a
|
||||||
container rebuild from a prior commit and does not require deleting volumes. Never use
|
container rebuild from a prior commit and does not require deleting host data
|
||||||
`docker compose down --volumes` where content must survive. Test database restoration
|
directories. Never delete the paths configured by `DB_DATA_PATH`, `WORDPRESS_DATA_PATH`,
|
||||||
in a disposable environment before any production restore.
|
or `LETSENCRYPT_DATA_PATH` where content/certificates must survive. Test database
|
||||||
|
restoration in a disposable environment before any production restore.
|
||||||
|
|||||||
+10
-4
@@ -6,6 +6,7 @@
|
|||||||
docker compose up --build -d
|
docker compose up --build -d
|
||||||
docker compose ps
|
docker compose ps
|
||||||
docker compose logs -f proxy wordpress db certbot
|
docker compose logs -f proxy wordpress db certbot
|
||||||
|
./scripts/prepare-host-volumes.sh
|
||||||
docker compose --profile tools run --rm wp-cli -c 'wp core version'
|
docker compose --profile tools run --rm wp-cli -c 'wp core version'
|
||||||
docker compose down
|
docker compose down
|
||||||
```
|
```
|
||||||
@@ -24,9 +25,11 @@ image rebuilds are the update path.
|
|||||||
|
|
||||||
## Backup and restore
|
## Backup and restore
|
||||||
|
|
||||||
Create database and `wordpress_data` backups in one maintenance window. Backups contain
|
Create database and WordPress file backups in one maintenance window. The default host
|
||||||
credentials, accounts, contact information, and uploaded media; encrypt them, restrict
|
paths are `./runtime/db`, `./runtime/wordpress`, `./runtime/letsencrypt`, and
|
||||||
access, set retention, and store copies off-host.
|
`./runtime/certbot/www`, unless overridden in `.env`. Backups contain credentials,
|
||||||
|
accounts, contact information, and uploaded media; encrypt them, restrict access, set
|
||||||
|
retention, and store copies off-host.
|
||||||
|
|
||||||
A restore is destructive. Validate it on isolated volumes, then stop WordPress, restore
|
A restore is destructive. Validate it on isolated volumes, then stop WordPress, restore
|
||||||
the database and file volume together, restart, and verify the homepage, media,
|
the database and file volume together, restart, and verify the homepage, media,
|
||||||
@@ -34,7 +37,10 @@ the database and file volume together, restart, and verify the homepage, media,
|
|||||||
|
|
||||||
## Known risks
|
## Known risks
|
||||||
|
|
||||||
- Local named volumes are not backups.
|
- Local host directories are not backups.
|
||||||
|
- A host-based volume may be unreadable by the application if created with the wrong
|
||||||
|
owner or mode; run `./scripts/prepare-host-volumes.sh` after changing paths or image
|
||||||
|
user IDs.
|
||||||
- SMTP is not configured; WordPress password-reset email needs an external mail service.
|
- SMTP is not configured; WordPress password-reset email needs an external mail service.
|
||||||
- Admin MFA and network allowlisting are deployment concerns and are not bundled.
|
- Admin MFA and network allowlisting are deployment concerns and are not bundled.
|
||||||
- WordPress plugins expand the attack surface; install only reviewed, maintained,
|
- WordPress plugins expand the attack surface; install only reviewed, maintained,
|
||||||
|
|||||||
+11
-3
@@ -14,10 +14,17 @@
|
|||||||
|
|
||||||
## Images or theme are missing
|
## Images or theme are missing
|
||||||
|
|
||||||
1. Confirm `wordpress_data` is mounted in both WordPress and WP-CLI.
|
1. Confirm `WORDPRESS_DATA_PATH` is mounted in both WordPress and WP-CLI.
|
||||||
2. Run `docker compose --profile tools run --rm wp-cli -c 'wp theme status azionelab'`.
|
2. Run `docker compose --profile tools run --rm wp-cli -c 'wp theme status azionelab'`.
|
||||||
3. Verify file ownership before changing permissions; never make the tree world-writable.
|
3. Verify file ownership before changing permissions; never make the tree world-writable.
|
||||||
|
|
||||||
|
## A service cannot write to its volume
|
||||||
|
|
||||||
|
1. Stop the affected service.
|
||||||
|
2. Confirm the relevant `.env` path points to the intended host directory.
|
||||||
|
3. Run `./scripts/prepare-host-volumes.sh`.
|
||||||
|
4. Start the service and inspect logs without printing secret values.
|
||||||
|
|
||||||
## Certificate issuance fails
|
## Certificate issuance fails
|
||||||
|
|
||||||
Verify public DNS, inbound port 80, the operator email, and staging mode. Request a
|
Verify public DNS, inbound port 80, the operator email, and staging mode. Request a
|
||||||
@@ -26,5 +33,6 @@ Avoid repeated production-CA retries while debugging.
|
|||||||
|
|
||||||
## Rollback
|
## Rollback
|
||||||
|
|
||||||
Revert the deployment commit and rebuild while preserving all named volumes. Restore
|
Revert the deployment commit and rebuild while preserving all host data directories.
|
||||||
database/files only for a data rollback and only from a verified coordinated backup.
|
Restore database/files only for a data rollback and only from a verified coordinated
|
||||||
|
backup.
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
- Containers are not privileged and do not use host networking or the Docker socket.
|
- Containers are not privileged and do not use host networking or the Docker socket.
|
||||||
WordPress/Apache retains the capabilities needed by the official image internally,
|
WordPress/Apache retains the capabilities needed by the official image internally,
|
||||||
but no WordPress port is published.
|
but no WordPress port is published.
|
||||||
|
- Persistent state uses host-based bind mounts. Keep those paths outside the public web
|
||||||
|
root, restrict host access, never make them world-writable, and run
|
||||||
|
`./scripts/prepare-host-volumes.sh` when paths or image user IDs change.
|
||||||
- WordPress/Apache access logs are disabled to avoid duplicate client metadata and
|
- WordPress/Apache access logs are disabled to avoid duplicate client metadata and
|
||||||
healthcheck noise; NGINX remains the single request log and PHP warnings/errors stay
|
healthcheck noise; NGINX remains the single request log and PHP warnings/errors stay
|
||||||
visible.
|
visible.
|
||||||
|
|||||||
+6
-5
@@ -14,11 +14,12 @@ docker compose config --quiet
|
|||||||
LETSENCRYPT_ENABLED=1 docker compose config --quiet
|
LETSENCRYPT_ENABLED=1 docker compose config --quiet
|
||||||
```
|
```
|
||||||
|
|
||||||
The override replaces normal database and WordPress volumes, maps `azionelab.org` to
|
The normal stack uses host-based bind mounts under `./runtime` by default. The test
|
||||||
the internal proxy, and never publishes an extra port. Browser tests cover content and
|
override replaces database and WordPress state with isolated Docker volumes, maps
|
||||||
section order, contact actions, mobile overflow/navigation, semantic landmarks, image
|
`azionelab.org` to the internal proxy, and never publishes an extra port. Browser tests
|
||||||
alternatives, admin routing, security headers, blocked sensitive routes, and unknown
|
cover content and section order, contact actions, mobile overflow/navigation, semantic
|
||||||
virtual hosts.
|
landmarks, image alternatives, admin routing, security headers, blocked sensitive
|
||||||
|
routes, and unknown virtual hosts.
|
||||||
|
|
||||||
Subjective visual review and a real-device accessibility audit remain manual release
|
Subjective visual review and a real-device accessibility audit remain manual release
|
||||||
checks.
|
checks.
|
||||||
|
|||||||
Executable
+99
@@ -0,0 +1,99 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
||||||
|
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
|
||||||
|
|
||||||
|
DB_DATA_PATH="${DB_DATA_PATH:-./runtime/db}"
|
||||||
|
WORDPRESS_DATA_PATH="${WORDPRESS_DATA_PATH:-./runtime/wordpress}"
|
||||||
|
LETSENCRYPT_DATA_PATH="${LETSENCRYPT_DATA_PATH:-./runtime/letsencrypt}"
|
||||||
|
CERTBOT_CHALLENGES_PATH="${CERTBOT_CHALLENGES_PATH:-./runtime/certbot/www}"
|
||||||
|
|
||||||
|
MARIADB_VOLUME_UID="${MARIADB_VOLUME_UID:-999}"
|
||||||
|
MARIADB_VOLUME_GID="${MARIADB_VOLUME_GID:-999}"
|
||||||
|
WORDPRESS_VOLUME_UID="${WORDPRESS_VOLUME_UID:-33}"
|
||||||
|
WORDPRESS_VOLUME_GID="${WORDPRESS_VOLUME_GID:-33}"
|
||||||
|
CERTBOT_VOLUME_UID="${CERTBOT_VOLUME_UID:-0}"
|
||||||
|
CERTBOT_VOLUME_GID="${CERTBOT_VOLUME_GID:-0}"
|
||||||
|
|
||||||
|
load_env_file() {
|
||||||
|
[ -f "$ENV_FILE" ] || return 0
|
||||||
|
|
||||||
|
while IFS= read -r line || [ -n "$line" ]; do
|
||||||
|
case "$line" in
|
||||||
|
"" | \#*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
key="${line%%=*}"
|
||||||
|
value="${line#*=}"
|
||||||
|
value="${value%\"}"
|
||||||
|
value="${value#\"}"
|
||||||
|
value="${value%\'}"
|
||||||
|
value="${value#\'}"
|
||||||
|
|
||||||
|
case "$key" in
|
||||||
|
DB_DATA_PATH) DB_DATA_PATH="$value" ;;
|
||||||
|
WORDPRESS_DATA_PATH) WORDPRESS_DATA_PATH="$value" ;;
|
||||||
|
LETSENCRYPT_DATA_PATH) LETSENCRYPT_DATA_PATH="$value" ;;
|
||||||
|
CERTBOT_CHALLENGES_PATH) CERTBOT_CHALLENGES_PATH="$value" ;;
|
||||||
|
MARIADB_VOLUME_UID) MARIADB_VOLUME_UID="$value" ;;
|
||||||
|
MARIADB_VOLUME_GID) MARIADB_VOLUME_GID="$value" ;;
|
||||||
|
WORDPRESS_VOLUME_UID) WORDPRESS_VOLUME_UID="$value" ;;
|
||||||
|
WORDPRESS_VOLUME_GID) WORDPRESS_VOLUME_GID="$value" ;;
|
||||||
|
CERTBOT_VOLUME_UID) CERTBOT_VOLUME_UID="$value" ;;
|
||||||
|
CERTBOT_VOLUME_GID) CERTBOT_VOLUME_GID="$value" ;;
|
||||||
|
esac
|
||||||
|
done < "$ENV_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_path() {
|
||||||
|
case "$1" in
|
||||||
|
/*) printf '%s\n' "$1" ;;
|
||||||
|
*) printf '%s/%s\n' "$ROOT_DIR" "$1" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_ownership() {
|
||||||
|
path="$1"
|
||||||
|
uid="$2"
|
||||||
|
gid="$3"
|
||||||
|
|
||||||
|
if chown -R "$uid:$gid" "$path" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
echo "WARN: cannot chown $path to $uid:$gid." >&2
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v sudo >/dev/null 2>&1; then
|
||||||
|
if sudo -n chown -R "$uid:$gid" "$path" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "WARN: sudo cannot chown $path to $uid:$gid without a password." >&2
|
||||||
|
echo "WARN: run this script with sudo if the service cannot write this path." >&2
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "WARN: cannot chown $path to $uid:$gid; rerun as root or install sudo." >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_dir() {
|
||||||
|
path="$1"
|
||||||
|
uid="$2"
|
||||||
|
gid="$3"
|
||||||
|
mode="$4"
|
||||||
|
|
||||||
|
mkdir -p "$path"
|
||||||
|
apply_ownership "$path" "$uid" "$gid"
|
||||||
|
chmod "$mode" "$path"
|
||||||
|
echo "Prepared $path as $uid:$gid mode $mode"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_env_file
|
||||||
|
|
||||||
|
prepare_dir "$(resolve_path "$DB_DATA_PATH")" "$MARIADB_VOLUME_UID" "$MARIADB_VOLUME_GID" 750
|
||||||
|
prepare_dir "$(resolve_path "$WORDPRESS_DATA_PATH")" "$WORDPRESS_VOLUME_UID" "$WORDPRESS_VOLUME_GID" 755
|
||||||
|
prepare_dir "$(resolve_path "$LETSENCRYPT_DATA_PATH")" "$CERTBOT_VOLUME_UID" "$CERTBOT_VOLUME_GID" 750
|
||||||
|
prepare_dir "$(resolve_path "$CERTBOT_CHALLENGES_PATH")" "$CERTBOT_VOLUME_UID" "$CERTBOT_VOLUME_GID" 755
|
||||||
Reference in New Issue
Block a user