Fix markdown lint issues in README (107 IDE warnings -> 0)
- Auto-fix MD060 table column style, MD012 multiple blanks, MD031/MD032 list/fence spacing - Add language tags to 4 bare code fences (MD040) - Add .markdownlint.json disabling MD013 (wide tables/commands are intentional) - Verified: markdownlint-cli2 reports 0 issues across README and docs/
This commit is contained in:
parent
1a999c7548
commit
7523c882a6
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
// Line length is not enforced: this README uses wide tables and long
|
||||||
|
// inline-command lines that would be unreadable if wrapped.
|
||||||
|
"MD013": false
|
||||||
|
}
|
||||||
53
README.md
53
README.md
|
|
@ -36,7 +36,7 @@ Work proceeds in two phases: `--bootstrap` hardens the host and stands up the pl
|
||||||
**Solution:** `wp-engine.sh` performs two phases:
|
**Solution:** `wp-engine.sh` performs two phases:
|
||||||
|
|
||||||
| Phase | Command | Purpose |
|
| Phase | Command | Purpose |
|
||||||
|---|---|---|
|
| --- | --- | --- |
|
||||||
| **Phase 1 — Host Hardening & Platform** | `./wp-engine.sh --bootstrap` | Installs packages, container runtime, hardened SSH, UFW firewall, Fail2ban jails, container networks, ingress reverse proxy, and the Grafana/Prometheus monitoring stack. |
|
| **Phase 1 — Host Hardening & Platform** | `./wp-engine.sh --bootstrap` | Installs packages, container runtime, hardened SSH, UFW firewall, Fail2ban jails, container networks, ingress reverse proxy, and the Grafana/Prometheus monitoring stack. |
|
||||||
| **Phase 2 — Site Provisioning** | `./wp-engine.sh create <slug> <domain> ...` | Creates an isolated WordPress site (container, database, DB user, Redis cache index, TLS route, WP-CLI automated install). |
|
| **Phase 2 — Site Provisioning** | `./wp-engine.sh create <slug> <domain> ...` | Creates an isolated WordPress site (container, database, DB user, Redis cache index, TLS route, WP-CLI automated install). |
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ Supporting design documents live in [`docs/`](docs/):
|
||||||
## 2. Requirements
|
## 2. Requirements
|
||||||
|
|
||||||
| Requirement | Detail |
|
| Requirement | Detail |
|
||||||
|---|---|
|
| --- | --- |
|
||||||
| **OS** | Clean Debian 11/12 or Ubuntu 22.04/24.04 LTS installation (bare-metal, Proxmox VM, or Proxmox LXC) with `apt` and `systemd` (the script calls `apt-get`, `systemctl`, `ufw`). Not compatible with RHEL/Alpine/Windows hosts. |
|
| **OS** | Clean Debian 11/12 or Ubuntu 22.04/24.04 LTS installation (bare-metal, Proxmox VM, or Proxmox LXC) with `apt` and `systemd` (the script calls `apt-get`, `systemctl`, `ufw`). Not compatible with RHEL/Alpine/Windows hosts. |
|
||||||
| **Privileges** | Must be run as `root` (the script exits if `EUID != 0`). |
|
| **Privileges** | Must be run as `root` (the script exits if `EUID != 0`). |
|
||||||
| **Network** | Outbound internet access to pull packages and container images (Docker Hub, download.docker.com, etc.). |
|
| **Network** | Outbound internet access to pull packages and container images (Docker Hub, download.docker.com, etc.). |
|
||||||
|
|
@ -105,6 +105,7 @@ chmod +x /usr/local/bin/wp-engine.sh
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> **Do not close your current SSH terminal** after running `--bootstrap`. Open a secondary terminal and verify that you can connect over your chosen port before disconnecting:
|
> **Do not close your current SSH terminal** after running `--bootstrap`. Open a secondary terminal and verify that you can connect over your chosen port before disconnecting:
|
||||||
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> ssh -p <PORT> user@<HOST_IP>
|
> ssh -p <PORT> user@<HOST_IP>
|
||||||
> ```
|
> ```
|
||||||
|
|
@ -113,7 +114,7 @@ chmod +x /usr/local/bin/wp-engine.sh
|
||||||
|
|
||||||
## 4. CLI Reference & Options
|
## 4. CLI Reference & Options
|
||||||
|
|
||||||
```
|
```text
|
||||||
Usage:
|
Usage:
|
||||||
Interactive Bootstrap:
|
Interactive Bootstrap:
|
||||||
./wp-engine.sh --bootstrap
|
./wp-engine.sh --bootstrap
|
||||||
|
|
@ -132,7 +133,7 @@ Examples:
|
||||||
### Actions
|
### Actions
|
||||||
|
|
||||||
| Action | Description |
|
| Action | Description |
|
||||||
|---|---|
|
| --- | --- |
|
||||||
| `--bootstrap` | Runs the 6-step host provisioning sequence, then deploys the monitoring stack. Prompts for any option not supplied via flags. |
|
| `--bootstrap` | Runs the 6-step host provisioning sequence, then deploys the monitoring stack. Prompts for any option not supplied via flags. |
|
||||||
| `create <slug> <domain> [admin_user] [admin_email]` | Provisions a new WordPress site. If the ingress proxy isn't running yet, bootstrap runs automatically; if the shared DB/cache core isn't up, it is initialized automatically. |
|
| `create <slug> <domain> [admin_user] [admin_email]` | Provisions a new WordPress site. If the ingress proxy isn't running yet, bootstrap runs automatically; if the shared DB/cache core isn't up, it is initialized automatically. |
|
||||||
| *(no/unknown action)* | Prints the usage text above and exits with code 1. |
|
| *(no/unknown action)* | Prints the usage text above and exits with code 1. |
|
||||||
|
|
@ -140,7 +141,7 @@ Examples:
|
||||||
### Flags (used with `--bootstrap`)
|
### Flags (used with `--bootstrap`)
|
||||||
|
|
||||||
| Flag | Values | Default | Effect |
|
| Flag | Values | Default | Effect |
|
||||||
|---|---|---|---|
|
| --- | --- | --- | --- |
|
||||||
| `--ssh-port` | `1–65535` | `48222` | Moves SSH off port 22; written to `sshd_config.d/99-hardened.conf`, the `ssh.socket` unit (if present), UFW, and the Fail2ban `sshd` jail. |
|
| `--ssh-port` | `1–65535` | `48222` | Moves SSH off port 22; written to `sshd_config.d/99-hardened.conf`, the `ssh.socket` unit (if present), UFW, and the Fail2ban `sshd` jail. |
|
||||||
| `--engine` | `docker` \| `podman` | `docker` | Container runtime. Docker installs from Docker's official apt repo; Podman installs `podman`, `podman-compose`, `podman-docker` from distro repos. |
|
| `--engine` | `docker` \| `podman` | `docker` | Container runtime. Docker installs from Docker's official apt repo; Podman installs `podman`, `podman-compose`, `podman-docker` from distro repos. |
|
||||||
| `--proxy` | `npm` \| `traefik` \| `caddy` | `npm` | Ingress reverse proxy. Determines the proxy compose file, extra firewall openings, TLS automation, and how sites get routed. |
|
| `--proxy` | `npm` \| `traefik` \| `caddy` | `npm` | Ingress reverse proxy. Determines the proxy compose file, extra firewall openings, TLS automation, and how sites get routed. |
|
||||||
|
|
@ -150,7 +151,7 @@ Examples:
|
||||||
### `create` arguments
|
### `create` arguments
|
||||||
|
|
||||||
| Position | Argument | Default | Description |
|
| Position | Argument | Default | Description |
|
||||||
|---|---|---|---|
|
| --- | --- | --- | --- |
|
||||||
| 1 | `slug` | *(required)* | Directory/container name, e.g. `teetimeprints`. Hyphens are converted to underscores for DB identifiers. |
|
| 1 | `slug` | *(required)* | Directory/container name, e.g. `teetimeprints`. Hyphens are converted to underscores for DB identifiers. |
|
||||||
| 2 | `domain` | *(required)* | Public FQDN, e.g. `teetimeprints.com`. Used for TLS routing and the WP site URL. |
|
| 2 | `domain` | *(required)* | Public FQDN, e.g. `teetimeprints.com`. Used for TLS routing and the WP site URL. |
|
||||||
| 3 | `admin_user` | `admin` | WordPress administrator username. |
|
| 3 | `admin_user` | `admin` | WordPress administrator username. |
|
||||||
|
|
@ -176,13 +177,14 @@ Additional `create` examples:
|
||||||
Installs `apt-transport-https ca-certificates curl gnupg lsb-release ufw fail2ban nftables openssl jq`.
|
Installs `apt-transport-https ca-certificates curl gnupg lsb-release ufw fail2ban nftables openssl jq`.
|
||||||
|
|
||||||
**`[2/6] Setting up Container Engine`**
|
**`[2/6] Setting up Container Engine`**
|
||||||
|
|
||||||
- *Docker:* adds Docker's official GPG key + apt repo, installs `docker-ce`, `docker-ce-cli`, `containerd.io`, `docker-buildx-plugin`, `docker-compose-plugin`, enables the service (skipped if Docker already present).
|
- *Docker:* adds Docker's official GPG key + apt repo, installs `docker-ce`, `docker-ce-cli`, `containerd.io`, `docker-buildx-plugin`, `docker-compose-plugin`, enables the service (skipped if Docker already present).
|
||||||
- *Podman:* `apt-get install podman podman-compose podman-docker`, enables the service.
|
- *Podman:* `apt-get install podman podman-compose podman-docker`, enables the service.
|
||||||
|
|
||||||
**`[3/6] Hardening SSH on Port <port>`**
|
**`[3/6] Hardening SSH on Port <port>`**
|
||||||
Writes `/etc/ssh/sshd_config.d/99-hardened.conf`:
|
Writes `/etc/ssh/sshd_config.d/99-hardened.conf`:
|
||||||
|
|
||||||
```
|
```text
|
||||||
Port <chosen port>
|
Port <chosen port>
|
||||||
PermitRootLogin prohibit-password
|
PermitRootLogin prohibit-password
|
||||||
PasswordAuthentication yes
|
PasswordAuthentication yes
|
||||||
|
|
@ -195,12 +197,14 @@ ClientAliveCountMax 2
|
||||||
Also re-points `ssh.socket`'s `ListenStream` to the new port when socket activation is in use, then restarts SSH.
|
Also re-points `ssh.socket`'s `ListenStream` to the new port when socket activation is in use, then restarts SSH.
|
||||||
|
|
||||||
**`[4/6] Configuring Firewall & Isolation Rules`**
|
**`[4/6] Configuring Firewall & Isolation Rules`**
|
||||||
|
|
||||||
- UFW policy: **deny incoming / allow outgoing**.
|
- UFW policy: **deny incoming / allow outgoing**.
|
||||||
- Allowed inbound: SSH port, `80`, `443`, `3000` (Grafana), plus `81` if NPM or `8080` if Traefik.
|
- Allowed inbound: SSH port, `80`, `443`, `3000` (Grafana), plus `81` if NPM or `8080` if Traefik.
|
||||||
- For Docker, appends a **`DOCKER-USER` chain** to `/etc/ufw/after.rules` so UFW rules actually apply to container traffic (blocks direct SYN scans into `172.16.0.0/12`, rate-limited logging).
|
- For Docker, appends a **`DOCKER-USER` chain** to `/etc/ufw/after.rules` so UFW rules actually apply to container traffic (blocks direct SYN scans into `172.16.0.0/12`, rate-limited logging).
|
||||||
- `ufw --force enable && ufw reload`.
|
- `ufw --force enable && ufw reload`.
|
||||||
|
|
||||||
**`[5/6] Scaffolding Networks & Fail2ban Jails`**
|
**`[5/6] Scaffolding Networks & Fail2ban Jails`**
|
||||||
|
|
||||||
- Creates the directory skeleton (`/server/websites/{proxy,core,template,sites,monitoring}`).
|
- Creates the directory skeleton (`/server/websites/{proxy,core,template,sites,monitoring}`).
|
||||||
- Creates three external container networks: `proxy-net`, `shared-backend`, `monitoring-net`.
|
- Creates three external container networks: `proxy-net`, `shared-backend`, `monitoring-net`.
|
||||||
- Writes Fail2ban jails:
|
- Writes Fail2ban jails:
|
||||||
|
|
@ -215,7 +219,7 @@ Also re-points `ssh.socket`'s `ListenStream` to the new port when socket activat
|
||||||
Deploys `/server/websites/monitoring/docker-compose.yml` on the isolated `monitoring-net`:
|
Deploys `/server/websites/monitoring/docker-compose.yml` on the isolated `monitoring-net`:
|
||||||
|
|
||||||
| Service | Image | Purpose | Exposure |
|
| Service | Image | Purpose | Exposure |
|
||||||
|---|---|---|---|
|
| --- | --- | --- | --- |
|
||||||
| `prometheus` | `prom/prometheus:v2.54.0` | Time-series DB; scrapes node_exporter + cAdvisor every 15 s | internal |
|
| `prometheus` | `prom/prometheus:v2.54.0` | Time-series DB; scrapes node_exporter + cAdvisor every 15 s | internal |
|
||||||
| `node_exporter` | `prom/node-exporter:v1.8.2` | Host CPU/RAM/disk metrics (`/proc`, `/sys`, `/` mounted read-only) | internal |
|
| `node_exporter` | `prom/node-exporter:v1.8.2` | Host CPU/RAM/disk metrics (`/proc`, `/sys`, `/` mounted read-only) | internal |
|
||||||
| `cadvisor` | `gcr.io/cadvisor/cadvisor:v0.49.1` | Per-container cgroup resource usage | internal |
|
| `cadvisor` | `gcr.io/cadvisor/cadvisor:v0.49.1` | Per-container cgroup resource usage | internal |
|
||||||
|
|
@ -264,7 +268,7 @@ A random Grafana admin password is generated (`openssl rand`) and appended to th
|
||||||
### 7.1 Container runtime
|
### 7.1 Container runtime
|
||||||
|
|
||||||
| | **Docker** (default) | **Podman** |
|
| | **Docker** (default) | **Podman** |
|
||||||
|---|---|---|
|
| --- | --- | --- |
|
||||||
| Install source | Docker official apt repo (`docker-ce` + compose plugin) | Distro repos (`podman`, `podman-compose`, `podman-docker`) |
|
| Install source | Docker official apt repo (`docker-ce` + compose plugin) | Distro repos (`podman`, `podman-compose`, `podman-docker`) |
|
||||||
| Compose command | `docker compose` | `podman-compose` |
|
| Compose command | `docker compose` | `podman-compose` |
|
||||||
| UFW integration | Gets the `DOCKER-USER` after.rules patch (required, since Docker bypasses UFW by default) | Not applied (Podman networking works differently with nftables/UFW) |
|
| UFW integration | Gets the `DOCKER-USER` after.rules patch (required, since Docker bypasses UFW by default) | Not applied (Podman networking works differently with nftables/UFW) |
|
||||||
|
|
@ -273,7 +277,7 @@ A random Grafana admin password is generated (`openssl rand`) and appended to th
|
||||||
### 7.2 Ingress proxy
|
### 7.2 Ingress proxy
|
||||||
|
|
||||||
| | **NPM** (default) | **Traefik v3** | **Caddy** |
|
| | **NPM** (default) | **Traefik v3** | **Caddy** |
|
||||||
|---|---|---|---|
|
| --- | --- | --- | --- |
|
||||||
| Image | `jc21/nginx-proxy-manager` | `traefik:v3.1` | `caddy:2-alpine` |
|
| Image | `jc21/nginx-proxy-manager` | `traefik:v3.1` | `caddy:2-alpine` |
|
||||||
| Management | Web UI on **`:81`** (opened in UFW) | Docker labels + insecure API dashboard on **`:8080`** (opened in UFW) | Text `Caddyfile` |
|
| Management | Web UI on **`:81`** (opened in UFW) | Docker labels + insecure API dashboard on **`:8080`** (opened in UFW) | Text `Caddyfile` |
|
||||||
| TLS certificates | Requested per host in the UI (Let's Encrypt) | ACME **TLS-ALPN challenge** via `myresolver` labels | **Fully automatic** Let's Encrypt |
|
| TLS certificates | Requested per host in the UI (Let's Encrypt) | ACME **TLS-ALPN challenge** via `myresolver` labels | **Fully automatic** Let's Encrypt |
|
||||||
|
|
@ -329,7 +333,7 @@ High-level traffic flow (see `docs/` for the full Mermaid diagrams):
|
||||||
### Networks
|
### Networks
|
||||||
|
|
||||||
| Network | Scope | Members |
|
| Network | Scope | Members |
|
||||||
|---|---|---|
|
| --- | --- | --- |
|
||||||
| `proxy-net` | external | ingress proxy + all WordPress containers (public-facing side) |
|
| `proxy-net` | external | ingress proxy + all WordPress containers (public-facing side) |
|
||||||
| `shared-backend` | external, isolated | all WordPress containers + `core_mariadb` + `core_redis` (no host ports published) |
|
| `shared-backend` | external, isolated | all WordPress containers + `core_mariadb` + `core_redis` (no host ports published) |
|
||||||
| `monitoring-net` | external, isolated | Prometheus, node_exporter, cAdvisor, Grafana |
|
| `monitoring-net` | external, isolated | Prometheus, node_exporter, cAdvisor, Grafana |
|
||||||
|
|
@ -337,7 +341,7 @@ High-level traffic flow (see `docs/` for the full Mermaid diagrams):
|
||||||
### Ports
|
### Ports
|
||||||
|
|
||||||
| Port | Service | Firewall |
|
| Port | Service | Firewall |
|
||||||
|---|---|---|
|
| --- | --- | --- |
|
||||||
| 22 → **48222** (default) | SSH | allowed (custom port) |
|
| 22 → **48222** (default) | SSH | allowed (custom port) |
|
||||||
| 80 / 443 | Ingress proxy (HTTP/HTTPS + ACME) | allowed |
|
| 80 / 443 | Ingress proxy (HTTP/HTTPS + ACME) | allowed |
|
||||||
| 81 | Nginx Proxy Manager admin UI | allowed **only if** `--proxy npm` |
|
| 81 | Nginx Proxy Manager admin UI | allowed **only if** `--proxy npm` |
|
||||||
|
|
@ -347,7 +351,7 @@ High-level traffic flow (see `docs/` for the full Mermaid diagrams):
|
||||||
|
|
||||||
### Filesystem layout (`/server/websites/`)
|
### Filesystem layout (`/server/websites/`)
|
||||||
|
|
||||||
```
|
```text
|
||||||
/server/websites/
|
/server/websites/
|
||||||
├── .engine-settings # Persisted choices: ENGINE, PROXY_TYPE, SSH_PORT, GRAFANA_ADMIN_PASS
|
├── .engine-settings # Persisted choices: ENGINE, PROXY_TYPE, SSH_PORT, GRAFANA_ADMIN_PASS
|
||||||
├── core/ # Shared data tier
|
├── core/ # Shared data tier
|
||||||
|
|
@ -384,7 +388,7 @@ Host-level configs written by the script:
|
||||||
## 9. Credentials & State Files
|
## 9. Credentials & State Files
|
||||||
|
|
||||||
| Secret | Where it lives | Notes |
|
| Secret | Where it lives | Notes |
|
||||||
|---|---|---|
|
| --- | --- | --- |
|
||||||
| Engine / proxy / SSH port | `/server/websites/.engine-settings` | plain, non-secret |
|
| Engine / proxy / SSH port | `/server/websites/.engine-settings` | plain, non-secret |
|
||||||
| Grafana admin password | `/server/websites/.engine-settings` → `GRAFANA_ADMIN_PASS` | login: `admin` @ `http://<host>:3000` |
|
| Grafana admin password | `/server/websites/.engine-settings` → `GRAFANA_ADMIN_PASS` | login: `admin` @ `http://<host>:3000` |
|
||||||
| MariaDB **root** password | `/server/websites/core/.env` → `DB_ROOT_PASSWORD` | `chmod 600`; used for creating per-site DBs |
|
| MariaDB **root** password | `/server/websites/core/.env` → `DB_ROOT_PASSWORD` | `chmod 600`; used for creating per-site DBs |
|
||||||
|
|
@ -403,13 +407,15 @@ After bootstrap:
|
||||||
|
|
||||||
1. Open `http://<HOST_IP>:3000` (Grafana).
|
1. Open `http://<HOST_IP>:3000` (Grafana).
|
||||||
2. Log in with `admin` / the password generated during bootstrap and saved in the state file:
|
2. Log in with `admin` / the password generated during bootstrap and saved in the state file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grep GRAFANA_ADMIN_PASS /server/websites/.engine-settings
|
grep GRAFANA_ADMIN_PASS /server/websites/.engine-settings
|
||||||
```
|
```
|
||||||
|
|
||||||
3. The **Prometheus** datasource is pre-provisioned and set as default. Import dashboards via **Dashboards → Import** — recommended IDs:
|
3. The **Prometheus** datasource is pre-provisioned and set as default. Import dashboards via **Dashboards → Import** — recommended IDs:
|
||||||
|
|
||||||
| ID | Dashboard | Provides |
|
| ID | Dashboard | Provides |
|
||||||
|---|---|---|
|
| --- | --- | --- |
|
||||||
| `1860` | Node Exporter Full | Real-time CPU, RAM, disk I/O, network throughput, load averages |
|
| `1860` | Node Exporter Full | Real-time CPU, RAM, disk I/O, network throughput, load averages |
|
||||||
| `14282` | cAdvisor Docker Monitoring | Per-container resource usage; spot CPU/RAM throttling across tenant sites |
|
| `14282` | cAdvisor Docker Monitoring | Per-container resource usage; spot CPU/RAM throttling across tenant sites |
|
||||||
|
|
||||||
|
|
@ -467,7 +473,7 @@ fail2ban-client get ingress-wordpress banned
|
||||||
## 12. Security Hardening Summary
|
## 12. Security Hardening Summary
|
||||||
|
|
||||||
| Layer | Control |
|
| Layer | Control |
|
||||||
|---|---|
|
| --- | --- |
|
||||||
| **Access** | SSH moved off port 22; root login limited to key auth (`PermitRootLogin prohibit-password`); `MaxAuthTries 4`; X11 forwarding off; idle timeout via `ClientAliveInterval`/`ClientAliveCountMax` |
|
| **Access** | SSH moved off port 22; root login limited to key auth (`PermitRootLogin prohibit-password`); `MaxAuthTries 4`; X11 forwarding off; idle timeout via `ClientAliveInterval`/`ClientAliveCountMax` |
|
||||||
| **Perimeter** | UFW default-deny inbound; explicit allow-list (SSH, 80, 443, 3000, +81/8080 per proxy) |
|
| **Perimeter** | UFW default-deny inbound; explicit allow-list (SSH, 80, 443, 3000, +81/8080 per proxy) |
|
||||||
| **Container escape path** | `DOCKER-USER` nftables chain in `/etc/ufw/after.rules` so UFW governs Docker-bridged traffic; direct scans into RFC1918 container ranges are logged + dropped |
|
| **Container escape path** | `DOCKER-USER` nftables chain in `/etc/ufw/after.rules` so UFW governs Docker-bridged traffic; direct scans into RFC1918 container ranges are logged + dropped |
|
||||||
|
|
@ -503,7 +509,7 @@ The script expects **root + systemd + apt + a privileged container runtime**, so
|
||||||
### 14.1 Test stages — `tests/smoke.sh`
|
### 14.1 Test stages — `tests/smoke.sh`
|
||||||
|
|
||||||
| `STAGE=` | Needs | What it verifies |
|
| `STAGE=` | Needs | What it verifies |
|
||||||
|---|---|---|
|
| --- | --- | --- |
|
||||||
| `static` *(default)* | Linux (WSL is fine), **no root** | `bash -n` syntax on both scripts, `shellcheck -S error`, usage/argument handling, non-root rejection via `setpriv` |
|
| `static` *(default)* | Linux (WSL is fine), **no root** | `bash -n` syntax on both scripts, `shellcheck -S error`, usage/argument handling, non-root rejection via `setpriv` |
|
||||||
| `bootstrap` | root + systemd + privileged container | Full unattended `--bootstrap` (Docker + Caddy), then asserts: state file, UFW active, both Fail2ban jails, all 5 containers running, Grafana health, proxy on :80, SSH on the hardened port |
|
| `bootstrap` | root + systemd + privileged container | Full unattended `--bootstrap` (Docker + Caddy), then asserts: state file, UFW active, both Fail2ban jails, all 5 containers running, Grafana health, proxy on :80, SSH on the hardened port |
|
||||||
| `site` | same as `bootstrap` | Auto-bootstraps if needed, runs `create smoketest smoketest.test`, then asserts: site dir, WP container, `wp-config.php`, scoped DB `wp_smoketest`, Caddyfile route, HTTP response through the proxy, `wp core is-installed` |
|
| `site` | same as `bootstrap` | Auto-bootstraps if needed, runs `create smoketest smoketest.test`, then asserts: site dir, WP container, `wp-config.php`, scoped DB `wp_smoketest`, Caddyfile route, HTTP response through the proxy, `wp core is-installed` |
|
||||||
|
|
@ -608,10 +614,7 @@ Harness fixes (in `tests/smoke.sh`): Grafana/proxy assertions got 60 s retry win
|
||||||
|
|
||||||
## Repository Contents
|
## Repository Contents
|
||||||
|
|
||||||
|
```text
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
wp-engine.sh # The installer/provisioner script (executable)
|
wp-engine.sh # The installer/provisioner script (executable)
|
||||||
README.md # This file
|
README.md # This file
|
||||||
.gitignore / .gitattributes # Secrets excluded; *.sh forced to LF
|
.gitignore / .gitattributes # Secrets excluded; *.sh forced to LF
|
||||||
|
|
@ -624,11 +627,3 @@ docs/
|
||||||
│ Runtime_Architecture_Network_Topology.md # Architecture & network Mermaid diagram
|
│ Runtime_Architecture_Network_Topology.md # Architecture & network Mermaid diagram
|
||||||
│ Filesystem_and_Directory_Structure.md # Filesystem layout Mermaid diagram
|
│ Filesystem_and_Directory_Structure.md # Filesystem layout Mermaid diagram
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue