Compare commits
2 Commits
d07b5cc575
...
ec8ce94082
| Author | SHA1 | Date | |
|---|---|---|---|
| ec8ce94082 | |||
| 4dafddf8e5 |
@ -41,6 +41,10 @@ Additional service directories may be added when those services are implemented.
|
||||
|
||||
`config/sql-server/` contains the version-controlled Docker Compose definition and safe example environment file for the SQL Server container. The live environment file is stored outside the repository at `/etc/atlas/sql-server.env`.
|
||||
|
||||
`config/nginx/` contains the temporary Atlas default HTTP site configuration and the PlotDirector development reverse-proxy configuration. Live nginx configuration is deployed under `/etc/nginx/`.
|
||||
|
||||
`config/systemd/` contains source-controlled systemd unit templates. `plotdirector-dev.service` is deployed to `/etc/systemd/system/plotdirector-dev.service`.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
Configuration templates must not contain live secrets. Secret-bearing live files should be stored outside the repository and referenced by documented paths or environment variable names.
|
||||
|
||||
21
config/nginx/README.md
Normal file
21
config/nginx/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# nginx Configuration
|
||||
|
||||
This directory contains version-controlled nginx configuration for Atlas.
|
||||
|
||||
`atlas-default.conf` is the temporary default HTTP site. It serves a small static status page from `/var/www/atlas` and exposes `/health` for local validation.
|
||||
|
||||
`plotdirector-dev.conf` proxies `dev.plotdirector.com` to PlotDirector on `http://127.0.0.1:5050` and provides a lightweight `/health` endpoint. It is intentionally HTTP-only until the TLS phase.
|
||||
|
||||
Deployment locations:
|
||||
|
||||
- Source configuration: `config/nginx/atlas-default.conf`
|
||||
- Live configuration: `/etc/nginx/sites-available/atlas-default.conf`
|
||||
- Enabled site: `/etc/nginx/sites-enabled/atlas-default.conf`
|
||||
- Static content: `/var/www/atlas`
|
||||
- Health check: `/health`
|
||||
- PlotDirector source configuration: `config/nginx/plotdirector-dev.conf`
|
||||
- PlotDirector live configuration: `/etc/nginx/sites-available/plotdirector-dev.conf`
|
||||
- PlotDirector enabled site: `/etc/nginx/sites-enabled/plotdirector-dev.conf`
|
||||
- PlotDirector hostname: `dev.plotdirector.com`
|
||||
|
||||
Do not store TLS private keys, live certificates, secrets, or PlotDirector-specific proxy credentials here.
|
||||
20
config/nginx/atlas-default.conf
Normal file
20
config/nginx/atlas-default.conf
Normal file
@ -0,0 +1,20 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
server_name _;
|
||||
root /var/www/atlas;
|
||||
index index.html;
|
||||
|
||||
access_log /var/log/nginx/atlas-access.log;
|
||||
error_log /var/log/nginx/atlas-error.log;
|
||||
|
||||
location = /health {
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "ok\n";
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
30
config/nginx/plotdirector-dev.conf
Normal file
30
config/nginx/plotdirector-dev.conf
Normal file
@ -0,0 +1,30 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name dev.plotdirector.com;
|
||||
|
||||
access_log /var/log/nginx/plotdirector-dev-access.log;
|
||||
error_log /var/log/nginx/plotdirector-dev-error.log;
|
||||
|
||||
client_max_body_size 100m;
|
||||
|
||||
location = /health {
|
||||
add_header Content-Type text/plain;
|
||||
return 200 "ok\n";
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5050;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 120s;
|
||||
proxy_send_timeout 120s;
|
||||
proxy_connect_timeout 30s;
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@ services:
|
||||
env_file:
|
||||
- /etc/atlas/sql-server.env
|
||||
ports:
|
||||
- "1433:1433"
|
||||
- "192.168.10.10:1433:1433"
|
||||
volumes:
|
||||
- /sql/mssql:/var/opt/mssql
|
||||
healthcheck:
|
||||
@ -26,4 +26,3 @@ services:
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "5"
|
||||
|
||||
|
||||
@ -8,4 +8,3 @@ ACCEPT_EULA=Y
|
||||
MSSQL_PID=Developer
|
||||
MSSQL_TCP_PORT=1433
|
||||
MSSQL_SA_PASSWORD=CHANGE_ME_DO_NOT_COMMIT
|
||||
|
||||
|
||||
21
config/systemd/plotdirector-dev.service
Normal file
21
config/systemd/plotdirector-dev.service
Normal file
@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=PlotDirector development web application
|
||||
After=network-online.target docker.service
|
||||
Wants=network-online.target
|
||||
Requires=docker.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=plotdirector
|
||||
Group=plotdirector
|
||||
WorkingDirectory=/srv/apps/plotdirector-dev/current
|
||||
EnvironmentFile=/etc/plotdirector/plotdirector.env
|
||||
ExecStart=/usr/bin/dotnet /srv/apps/plotdirector-dev/current/PlotLine.dll
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
SyslogIdentifier=plotdirector-dev
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@ -23,6 +23,8 @@ Atlas is a single physical development server.
|
||||
- Development volume: SSD mounted at `/srv`
|
||||
- Repository root: `/srv/repos`
|
||||
- Infrastructure repository: `/srv/repos/AI-Development-Server`
|
||||
- PlotDirector source repository: `/srv/repos/PlotDirector`
|
||||
- PlotDirector development deployment: `/srv/apps/plotdirector-dev/current`
|
||||
|
||||
The intended model separates operating system state, SQL data, and development data. This supports rebuild and recovery by reducing reliance on the OS volume for mutable project data.
|
||||
|
||||
@ -34,7 +36,9 @@ The intended model separates operating system state, SQL data, and development d
|
||||
- Primary network interface: `enp3s0`
|
||||
- Gitea SSH remote for this repository: `git@git.catherinelynwood.com:atlas-bot/AI-Development-Server.git`
|
||||
|
||||
DNS, firewall, public exposure, and TLS policy are `TODO: Confirm during the relevant implementation phase.`
|
||||
UFW is active with default deny incoming and default allow outgoing. Inbound SSH `22`, HTTP `80`, and HTTPS `443` are allowed. SQL Server `1433` is allowed only from `192.168.10.0/24` and is bound to `192.168.10.10`.
|
||||
|
||||
Public DNS, TLS, and router exposure policy are `TODO: Confirm during the relevant implementation phase.`
|
||||
|
||||
### Repository and Source-Control Flow
|
||||
|
||||
@ -78,31 +82,47 @@ Atlas is intended to support:
|
||||
|
||||
Only components verified during implementation should be recorded as installed.
|
||||
|
||||
### Intended PlotDirector Deployment Topology
|
||||
### PlotDirector Development Deployment Topology
|
||||
|
||||
PlotDirector deployment topology is not yet established.
|
||||
PlotDirector is deployed for development from the `onboarding` branch.
|
||||
|
||||
Current assumptions:
|
||||
- Repository: `git@git.catherinelynwood.com:nick/PlotDirector.git`
|
||||
- Source path: `/srv/repos/PlotDirector`
|
||||
- Entry project: `PlotLine/PlotLine.csproj`
|
||||
- Target framework: `net10.0`
|
||||
- Output assembly: `PlotLine.dll`
|
||||
- Published path: `/srv/apps/plotdirector-dev/current`
|
||||
- Uploads path: `/srv/apps/plotdirector-dev/uploads`
|
||||
- Runtime environment file: `/etc/plotdirector/plotdirector.env`
|
||||
- Service account: `plotdirector`
|
||||
- systemd service: `plotdirector-dev`
|
||||
- Kestrel endpoint: `http://127.0.0.1:5050`
|
||||
- nginx hostname: `dev.plotdirector.com`
|
||||
- Development database: `PlotDirector_Development`
|
||||
- SQL login: `plotdirector_dev`
|
||||
|
||||
- Source repositories should live under `/srv/repos`.
|
||||
- Build artefacts should be generated outside this infrastructure repository.
|
||||
- Deployed applications should be separated from source repositories.
|
||||
- SQL data should use `/sql` once SQL Server paths are confirmed.
|
||||
- nginx may act as the reverse proxy if the application is exposed over HTTP or HTTPS.
|
||||
- Docker may host one or more services if containerisation is adopted.
|
||||
Windows LAN clients can test the development site with this hosts-file entry:
|
||||
|
||||
Specific PlotDirector service names, ports, deployment paths, database names, and rollback procedures are `TODO: Confirm during the relevant implementation phase.`
|
||||
```text
|
||||
192.168.10.10 dev.plotdirector.com
|
||||
```
|
||||
|
||||
SMTP, Stripe, and OpenAI are intentionally unconfigured in the Atlas development runtime unless explicitly provided through protected runtime configuration.
|
||||
|
||||
### Role of nginx
|
||||
|
||||
nginx is planned as the likely local reverse proxy for HTTP and HTTPS applications. Its future responsibilities may include:
|
||||
nginx is installed from the standard Ubuntu 26.04 repositories and currently serves a temporary Atlas HTTP status site.
|
||||
|
||||
- Routing requests to application services.
|
||||
- TLS termination.
|
||||
- Static file serving where appropriate.
|
||||
- Request size, timeout, and header policy.
|
||||
- Package version: nginx `1.28.3`
|
||||
- Service: `nginx`
|
||||
- Site configuration: `/etc/nginx/sites-available/atlas-default.conf`
|
||||
- Version-controlled source: `config/nginx/atlas-default.conf`
|
||||
- Static site root: `/var/www/atlas`
|
||||
- Health endpoint: `http://192.168.10.10/health`
|
||||
- PlotDirector development proxy source: `config/nginx/plotdirector-dev.conf`
|
||||
- PlotDirector development hostname: `dev.plotdirector.com`
|
||||
|
||||
nginx installation, site layout, TLS certificate handling, and exposure rules are `TODO: Confirm during the relevant implementation phase.`
|
||||
HTTPS and TLS certificates are not configured yet.
|
||||
|
||||
### Role of SQL Server
|
||||
|
||||
@ -137,6 +157,10 @@ The intended storage and responsibility model is:
|
||||
|
||||
- Source repositories: `/srv/repos`
|
||||
- Infrastructure repository: `/srv/repos/AI-Development-Server`
|
||||
- PlotDirector source repository: `/srv/repos/PlotDirector`
|
||||
- PlotDirector published application: `/srv/apps/plotdirector-dev/current`
|
||||
- PlotDirector runtime configuration: `/etc/plotdirector/plotdirector.env`
|
||||
- PlotDirector uploads: `/srv/apps/plotdirector-dev/uploads`
|
||||
- Installer logs: `/var/log/atlas/install/`
|
||||
- Discovery and validation reports: `/var/log/atlas/reports/`
|
||||
- Future installer state and markers: `/var/lib/atlas/`
|
||||
@ -159,6 +183,7 @@ Known trust boundaries:
|
||||
- Repository content versus live secret-bearing configuration.
|
||||
- SQL data on `/sql` versus source and scripts on `/srv`.
|
||||
- Future public-facing application traffic through nginx, if enabled.
|
||||
- PlotDirector Kestrel listens only on loopback and is reached through nginx.
|
||||
|
||||
Unresolved trust-boundary details:
|
||||
|
||||
@ -184,9 +209,10 @@ flowchart TB
|
||||
Scripts[Future operational scripts<br>scripts/]
|
||||
Tests[Future smoke tests<br>tests/]
|
||||
SQL[(SQL data volume<br>/sql)]
|
||||
Deploy[Future deployed applications]
|
||||
Nginx[Future nginx reverse proxy]
|
||||
Docker[Future Docker runtime]
|
||||
Deploy[PlotDirector dev deployment<br>/srv/apps/plotdirector-dev/current]
|
||||
Nginx[nginx reverse proxy<br>dev.plotdirector.com]
|
||||
Docker[Docker runtime]
|
||||
SqlContainer[SQL Server container<br>atlas-sql-server]
|
||||
end
|
||||
|
||||
Repo --> Install
|
||||
@ -194,7 +220,8 @@ flowchart TB
|
||||
Repo --> Scripts
|
||||
Repo --> Tests
|
||||
Source --> Deploy
|
||||
Deploy --> SQL
|
||||
Deploy --> SqlContainer
|
||||
SqlContainer --> SQL
|
||||
Nginx --> Deploy
|
||||
Docker --> Deploy
|
||||
```
|
||||
|
||||
@ -10,6 +10,116 @@ This file records chronological Atlas build and infrastructure milestones. Do no
|
||||
|
||||
### Phase
|
||||
|
||||
Phase 2 PlotDirector development deployment.
|
||||
|
||||
### Objective
|
||||
|
||||
Build and run the PlotDirector `onboarding` branch on Atlas behind nginx using the local SQL Server container.
|
||||
|
||||
### Changes
|
||||
|
||||
- Cloned PlotDirector at `/srv/repos/PlotDirector` from `git@git.catherinelynwood.com:nick/PlotDirector.git`.
|
||||
- Confirmed branch `onboarding` tracks `origin/onboarding`.
|
||||
- Built `PlotLine/PlotLine.csproj` targeting `net10.0`.
|
||||
- Created runtime configuration at `/etc/plotdirector/plotdirector.env`.
|
||||
- Created SQL database `PlotDirector_Development`.
|
||||
- Created SQL login `plotdirector_dev`.
|
||||
- Applied numbered SQL scripts `001` through `131`; `Stripe_Price_IDs_Prod.sql` was not run.
|
||||
- Published the application to `/srv/apps/plotdirector-dev/current`.
|
||||
- Added systemd unit template `config/systemd/plotdirector-dev.service`.
|
||||
- Added nginx proxy configuration `config/nginx/plotdirector-dev.conf`.
|
||||
- Added deployment phase `install/phases/50-plotdirector-dev.sh`.
|
||||
|
||||
### Validation
|
||||
|
||||
- `dotnet restore` passed.
|
||||
- `dotnet build --configuration Release` passed with zero warnings.
|
||||
- `dotnet publish --configuration Release` passed.
|
||||
- `plotdirector-dev` systemd service started and listened on `127.0.0.1:5050`.
|
||||
- nginx proxied `dev.plotdirector.com` to Kestrel.
|
||||
- `/health` returned HTTP 200 from nginx.
|
||||
- The development database contained the expected schema after script application.
|
||||
|
||||
### Problems
|
||||
|
||||
- SQL script execution required `sqlcmd -I` from script `076` onward so `QUOTED_IDENTIFIER` was enabled.
|
||||
- `/srv` was `0700`, which prevented the non-root service account from traversing to `/srv/apps`. Atlas now grants execute-only traversal on `/srv`.
|
||||
- The repository contains legacy hard-coded connection strings. They were not copied into Atlas runtime configuration.
|
||||
|
||||
### Decisions
|
||||
|
||||
- Run the application as the non-root `plotdirector` service account.
|
||||
- Keep Kestrel bound to `127.0.0.1:5050`.
|
||||
- Use nginx hostname `dev.plotdirector.com` for LAN development.
|
||||
- Leave SMTP, Stripe, and OpenAI unconfigured for smoke testing.
|
||||
|
||||
### Git Commit
|
||||
|
||||
Not yet committed.
|
||||
|
||||
### Operator
|
||||
|
||||
Codex.
|
||||
|
||||
### Date
|
||||
|
||||
2026-07-10
|
||||
|
||||
### Phase
|
||||
|
||||
Phase 2 nginx and firewall baseline.
|
||||
|
||||
### Objective
|
||||
|
||||
Install nginx, deploy a minimal Atlas status site, restrict SQL Server binding, and enable a safe UFW baseline.
|
||||
|
||||
### Changes
|
||||
|
||||
- Added `install/phases/40-nginx.sh`.
|
||||
- Installed nginx `1.28.3` from Ubuntu `resolute-updates`.
|
||||
- Added Atlas default nginx site under `config/nginx/`.
|
||||
- Deployed static site content to `/var/www/atlas`.
|
||||
- Enabled `/health` endpoint.
|
||||
- Enabled UFW with default deny incoming and default allow outgoing.
|
||||
- Allowed inbound TCP `22`, `80`, and `443`.
|
||||
- Allowed inbound TCP `1433` only from `192.168.10.0/24`.
|
||||
- Changed SQL Server container binding to `192.168.10.10:1433:1433`.
|
||||
|
||||
### Validation
|
||||
|
||||
- `nginx -t` passed.
|
||||
- HTTP checks passed for `127.0.0.1` and `192.168.10.10`.
|
||||
- `/health` returned HTTP 200.
|
||||
- nginx restart test passed.
|
||||
- SQL Server remained healthy after container recreation.
|
||||
- SQL data persisted after container recreation.
|
||||
- SQL LAN connection test passed.
|
||||
- Atlas discovery and validation passed.
|
||||
|
||||
### Problems
|
||||
|
||||
- Initial nginx deployment encountered a duplicate default-server config while the Ubuntu default site was still enabled. The installer now validates before and after disabling the default site.
|
||||
|
||||
### Decisions
|
||||
|
||||
- Keep nginx HTTP-only until a later TLS phase.
|
||||
- Keep the temporary Atlas status site separate from future PlotDirector proxy configuration.
|
||||
- Do not rely on UFW alone for Docker-published SQL Server; bind SQL Server to the Atlas LAN address.
|
||||
|
||||
### Git Commit
|
||||
|
||||
Not yet committed.
|
||||
|
||||
### Operator
|
||||
|
||||
Codex.
|
||||
|
||||
### Date
|
||||
|
||||
2026-07-10
|
||||
|
||||
### Phase
|
||||
|
||||
Phase 2 Docker and SQL Server container platform.
|
||||
|
||||
### Objective
|
||||
|
||||
@ -11,6 +11,8 @@ This guide describes the planned rebuild path for Atlas. At Phase 1, the reposit
|
||||
- .NET installation script: present.
|
||||
- Docker installation script: present.
|
||||
- SQL Server container installation script: present.
|
||||
- nginx installation script: present.
|
||||
- PlotDirector development deployment script: present.
|
||||
- Other component installation scripts: not yet created.
|
||||
- Configuration templates: not yet created.
|
||||
- Operational scripts: not yet created.
|
||||
@ -118,8 +120,14 @@ Planned bootstrap flow:
|
||||
7. Run `install/phases/10-dotnet.sh` when .NET SDKs are required.
|
||||
8. Run `install/phases/30-docker.sh`.
|
||||
9. Run `install/phases/20-sql-server.sh` after Docker is available.
|
||||
10. Run additional ordered installation scripts from `install/phases/` when they exist.
|
||||
11. Run smoke tests from `tests/` when they exist.
|
||||
10. Run `install/phases/40-nginx.sh`.
|
||||
11. Apply the UFW baseline rules.
|
||||
12. Clone PlotDirector to `/srv/repos/PlotDirector` on branch `onboarding`.
|
||||
13. Create protected PlotDirector runtime configuration at `/etc/plotdirector/plotdirector.env`.
|
||||
14. Initialise the `PlotDirector_Development` database using the numbered SQL scripts.
|
||||
15. Run `install/phases/50-plotdirector-dev.sh`.
|
||||
16. Run additional ordered installation scripts from `install/phases/` when they exist.
|
||||
17. Run smoke tests from `tests/` when they exist.
|
||||
|
||||
Bootstrap command sequence is `TODO: Confirm during the relevant implementation phase.`
|
||||
|
||||
@ -132,6 +140,7 @@ install/phases/10-dotnet.sh
|
||||
install/phases/20-sql-server.sh
|
||||
install/phases/30-docker.sh
|
||||
install/phases/40-nginx.sh
|
||||
install/phases/50-plotdirector-dev.sh
|
||||
```
|
||||
|
||||
Current Docker and SQL Server commands:
|
||||
@ -154,7 +163,57 @@ sudo docker inspect -f '{{.State.Health.Status}}' atlas-sql-server
|
||||
|
||||
SQL Server live secrets are stored at `/etc/atlas/sql-server.env` and must not be committed.
|
||||
|
||||
These scripts do not exist yet. When created, each script must:
|
||||
Current nginx validation commands:
|
||||
|
||||
```bash
|
||||
sudo nginx -t
|
||||
systemctl is-active nginx
|
||||
curl -fsS http://127.0.0.1/health
|
||||
curl -fsS http://192.168.10.10/health
|
||||
```
|
||||
|
||||
Current firewall inspection command:
|
||||
|
||||
```bash
|
||||
sudo ufw status numbered
|
||||
```
|
||||
|
||||
Current PlotDirector development deployment command:
|
||||
|
||||
```bash
|
||||
install/phases/50-plotdirector-dev.sh
|
||||
```
|
||||
|
||||
PlotDirector runtime details:
|
||||
|
||||
- Source repository: `/srv/repos/PlotDirector`
|
||||
- Required branch: `onboarding`
|
||||
- Entry project: `PlotLine/PlotLine.csproj`
|
||||
- Published path: `/srv/apps/plotdirector-dev/current`
|
||||
- Runtime environment file: `/etc/plotdirector/plotdirector.env`
|
||||
- Service: `plotdirector-dev`
|
||||
- Kestrel endpoint: `http://127.0.0.1:5050`
|
||||
- nginx hostname: `dev.plotdirector.com`
|
||||
- Database: `PlotDirector_Development`
|
||||
- SQL login: `plotdirector_dev`
|
||||
|
||||
Use this Windows hosts-file entry for LAN testing:
|
||||
|
||||
```text
|
||||
192.168.10.10 dev.plotdirector.com
|
||||
```
|
||||
|
||||
PlotDirector validation commands:
|
||||
|
||||
```bash
|
||||
systemctl is-active plotdirector-dev
|
||||
journalctl -u plotdirector-dev --no-pager -n 100
|
||||
curl --noproxy '*' -fsS http://127.0.0.1:5050/ >/dev/null
|
||||
curl --noproxy '*' -fsS -H 'Host: dev.plotdirector.com' http://127.0.0.1/ >/dev/null
|
||||
sudo nginx -t
|
||||
```
|
||||
|
||||
Installation scripts must:
|
||||
|
||||
- Be idempotent.
|
||||
- Validate prerequisites.
|
||||
|
||||
@ -54,6 +54,8 @@ Current Phase 2 installer:
|
||||
install/phases/10-dotnet.sh
|
||||
install/phases/20-sql-server.sh
|
||||
install/phases/30-docker.sh
|
||||
install/phases/40-nginx.sh
|
||||
install/phases/50-plotdirector-dev.sh
|
||||
```
|
||||
|
||||
The .NET installer installs only the required .NET SDK packages and verifies them with `dotnet --list-sdks`.
|
||||
@ -67,11 +69,19 @@ Current installed SDKs:
|
||||
|
||||
Docker is installed from Docker's official signed Ubuntu APT repository. SQL Server uses Microsoft's official SQL Server 2025 container image because native SQL Server packages are not supported on Ubuntu 26.04.
|
||||
|
||||
nginx is installed from Ubuntu repositories and serves the temporary Atlas status site until PlotDirector routing is configured.
|
||||
|
||||
PlotDirector development deployment uses `/srv/repos/PlotDirector` on branch `onboarding`, publishes `PlotLine.dll` to `/srv/apps/plotdirector-dev/current`, runs as the `plotdirector` service account, and is proxied by nginx as `dev.plotdirector.com`.
|
||||
|
||||
The PlotDirector runtime environment file is `/etc/plotdirector/plotdirector.env`. It contains secrets and must never be committed.
|
||||
|
||||
Runtime output belongs outside the repository:
|
||||
|
||||
- `/var/log/atlas/install/`
|
||||
- `/var/log/atlas/reports/`
|
||||
- `/var/lib/atlas/`
|
||||
- `/srv/apps/plotdirector-dev/current`
|
||||
- `/srv/apps/plotdirector-dev/uploads`
|
||||
|
||||
## Security Considerations
|
||||
|
||||
|
||||
167
install/phases/40-nginx.sh
Executable file
167
install/phases/40-nginx.sh
Executable file
@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTALL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
REPO_ROOT="$(cd "${INSTALL_DIR}/.." && pwd)"
|
||||
|
||||
# shellcheck source=install/lib/common.sh
|
||||
source "${INSTALL_DIR}/lib/common.sh"
|
||||
# shellcheck source=install/lib/logging.sh
|
||||
source "${INSTALL_DIR}/lib/logging.sh"
|
||||
# shellcheck source=install/lib/packages.sh
|
||||
source "${INSTALL_DIR}/lib/packages.sh"
|
||||
|
||||
atlas_set_script_name "40-nginx.sh"
|
||||
atlas_install_error_trap
|
||||
|
||||
ATLAS_SITE_ROOT="/var/www/atlas"
|
||||
ATLAS_SITE_CONF_SOURCE="${REPO_ROOT}/config/nginx/atlas-default.conf"
|
||||
ATLAS_SITE_CONF_DEST="/etc/nginx/sites-available/atlas-default.conf"
|
||||
ATLAS_SITE_LINK="/etc/nginx/sites-enabled/atlas-default.conf"
|
||||
NGINX_DEFAULT_LINK="/etc/nginx/sites-enabled/default"
|
||||
NGINX_BACKUP_DIR="/etc/nginx/atlas-backups"
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: install/phases/40-nginx.sh [options]
|
||||
|
||||
Install nginx from Ubuntu repositories and deploy the temporary Atlas default
|
||||
HTTP status site. This does not configure HTTPS or PlotDirector proxying.
|
||||
|
||||
Options:
|
||||
--help Show this help text.
|
||||
--version Show script/framework version.
|
||||
--dry-run Show intended actions without making changes.
|
||||
--verbose Print additional diagnostic output.
|
||||
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--help)
|
||||
usage
|
||||
exit "${ATLAS_EXIT_OK}"
|
||||
;;
|
||||
--version)
|
||||
atlas_print_version
|
||||
exit "${ATLAS_EXIT_OK}"
|
||||
;;
|
||||
--dry-run)
|
||||
atlas_enable_dry_run
|
||||
;;
|
||||
--verbose)
|
||||
atlas_enable_verbose
|
||||
;;
|
||||
*)
|
||||
atlas_usage_error "Unknown option: $1"
|
||||
exit "${ATLAS_EXIT_USAGE}"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
install_nginx() {
|
||||
if atlas_package_installed nginx; then
|
||||
atlas_log_ok "nginx is already installed"
|
||||
else
|
||||
atlas_install_packages nginx
|
||||
fi
|
||||
}
|
||||
|
||||
write_site_content() {
|
||||
local tmp_file
|
||||
tmp_file="$(mktemp)"
|
||||
cat >"$tmp_file" <<'HTML'
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Atlas</title>
|
||||
<style>
|
||||
body { margin: 0; font-family: system-ui, sans-serif; background: #f6f7f9; color: #1f2933; }
|
||||
main { max-width: 42rem; margin: 12vh auto; padding: 2rem; }
|
||||
h1 { font-size: 2rem; margin: 0 0 1rem; }
|
||||
p { line-height: 1.5; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Atlas is operational</h1>
|
||||
<p>This is the temporary Atlas status site. Application routing has not been configured yet.</p>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
||||
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
|
||||
atlas_log_info "Dry-run mode: would deploy static site content to ${ATLAS_SITE_ROOT}"
|
||||
rm -f "$tmp_file"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sudo -n install -d -m 0755 -o www-data -g www-data "$ATLAS_SITE_ROOT"
|
||||
sudo -n install -m 0644 -o www-data -g www-data "$tmp_file" "${ATLAS_SITE_ROOT}/index.html"
|
||||
rm -f "$tmp_file"
|
||||
}
|
||||
|
||||
deploy_nginx_config() {
|
||||
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
|
||||
atlas_log_info "Dry-run mode: would deploy ${ATLAS_SITE_CONF_DEST}"
|
||||
atlas_log_info "Dry-run mode: would enable Atlas nginx site and disable Ubuntu default site"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sudo -n install -d -m 0755 /etc/nginx/sites-available /etc/nginx/sites-enabled
|
||||
sudo -n install -d -m 0750 "$NGINX_BACKUP_DIR"
|
||||
|
||||
sudo -n nginx -t
|
||||
|
||||
if [[ -e "$ATLAS_SITE_CONF_DEST" ]] && ! cmp -s "$ATLAS_SITE_CONF_SOURCE" "$ATLAS_SITE_CONF_DEST"; then
|
||||
sudo -n cp -a "$ATLAS_SITE_CONF_DEST" "${NGINX_BACKUP_DIR}/atlas-default.conf.$(date -u '+%Y%m%dT%H%M%SZ').bak"
|
||||
fi
|
||||
sudo -n install -m 0644 "$ATLAS_SITE_CONF_SOURCE" "$ATLAS_SITE_CONF_DEST"
|
||||
|
||||
if [[ -e "$NGINX_DEFAULT_LINK" ]]; then
|
||||
sudo -n cp -a "$NGINX_DEFAULT_LINK" "${NGINX_BACKUP_DIR}/default-link.$(date -u '+%Y%m%dT%H%M%SZ').bak"
|
||||
sudo -n rm -f "$NGINX_DEFAULT_LINK"
|
||||
fi
|
||||
|
||||
sudo -n ln -sfn "$ATLAS_SITE_CONF_DEST" "$ATLAS_SITE_LINK"
|
||||
|
||||
sudo -n nginx -t
|
||||
}
|
||||
|
||||
enable_nginx() {
|
||||
atlas_sudo_run systemctl enable nginx
|
||||
atlas_sudo_run systemctl restart nginx
|
||||
}
|
||||
|
||||
verify_nginx() {
|
||||
if [[ "${ATLAS_DRY_RUN}" == "1" ]]; then
|
||||
atlas_log_info "Dry-run mode: would verify nginx service and health endpoint"
|
||||
return 0
|
||||
fi
|
||||
sudo -n nginx -t
|
||||
systemctl is-enabled nginx >/dev/null
|
||||
systemctl is-active nginx >/dev/null
|
||||
curl -fsS http://127.0.0.1/health >/dev/null
|
||||
curl -fsS http://192.168.10.10/health >/dev/null
|
||||
atlas_log_ok "nginx verification passed"
|
||||
}
|
||||
|
||||
main() {
|
||||
atlas_require_sudo_noninteractive || {
|
||||
atlas_log_error "Passwordless non-interactive sudo is required"
|
||||
exit "${ATLAS_EXIT_PREREQ}"
|
||||
}
|
||||
install_nginx
|
||||
write_site_content
|
||||
deploy_nginx_config
|
||||
enable_nginx
|
||||
verify_nginx
|
||||
}
|
||||
|
||||
main
|
||||
218
install/phases/50-plotdirector-dev.sh
Executable file
218
install/phases/50-plotdirector-dev.sh
Executable file
@ -0,0 +1,218 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTALL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
REPO_ROOT="$(cd "${INSTALL_DIR}/.." && pwd)"
|
||||
|
||||
# shellcheck source=install/lib/common.sh
|
||||
source "${INSTALL_DIR}/lib/common.sh"
|
||||
# shellcheck source=install/lib/logging.sh
|
||||
source "${INSTALL_DIR}/lib/logging.sh"
|
||||
# shellcheck source=install/lib/files.sh
|
||||
source "${INSTALL_DIR}/lib/files.sh"
|
||||
|
||||
atlas_set_script_name "50-plotdirector-dev.sh"
|
||||
atlas_install_error_trap
|
||||
|
||||
APP_REPO="/srv/repos/PlotDirector"
|
||||
APP_BRANCH="onboarding"
|
||||
APP_PROJECT="${APP_REPO}/PlotLine/PlotLine.csproj"
|
||||
PUBLISH_DIR="/srv/apps/plotdirector-dev/current"
|
||||
UPLOADS_DIR="/srv/apps/plotdirector-dev/uploads"
|
||||
ENV_FILE="/etc/plotdirector/plotdirector.env"
|
||||
SERVICE_USER="plotdirector"
|
||||
SERVICE_NAME="plotdirector-dev"
|
||||
SYSTEMD_SOURCE="${REPO_ROOT}/config/systemd/plotdirector-dev.service"
|
||||
SYSTEMD_DEST="/etc/systemd/system/plotdirector-dev.service"
|
||||
NGINX_SOURCE="${REPO_ROOT}/config/nginx/plotdirector-dev.conf"
|
||||
NGINX_DEST="/etc/nginx/sites-available/plotdirector-dev.conf"
|
||||
NGINX_LINK="/etc/nginx/sites-enabled/plotdirector-dev.conf"
|
||||
NGINX_BACKUP_DIR="/etc/nginx/atlas-backups"
|
||||
ALLOW_DIRTY=0
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage: install/phases/50-plotdirector-dev.sh [options]
|
||||
|
||||
Publish and run the PlotDirector onboarding branch as the Atlas development
|
||||
instance behind nginx. This script does not modify PlotDirector source,
|
||||
create Git commits, or store secrets.
|
||||
|
||||
Prerequisites:
|
||||
- /srv/repos/PlotDirector exists on branch onboarding.
|
||||
- /etc/plotdirector/plotdirector.env exists and contains runtime settings.
|
||||
- The PlotDirector development database has already been initialised.
|
||||
|
||||
Options:
|
||||
--help Show this help text.
|
||||
--version Show script/framework version.
|
||||
--dry-run Show intended actions without making changes.
|
||||
--verbose Print additional diagnostic output.
|
||||
--allow-dirty Permit deployment from a dirty PlotDirector working tree.
|
||||
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--help)
|
||||
usage
|
||||
exit "${ATLAS_EXIT_OK}"
|
||||
;;
|
||||
--version)
|
||||
atlas_print_version
|
||||
exit "${ATLAS_EXIT_OK}"
|
||||
;;
|
||||
--dry-run)
|
||||
atlas_enable_dry_run
|
||||
;;
|
||||
--verbose)
|
||||
atlas_enable_verbose
|
||||
;;
|
||||
--allow-dirty)
|
||||
ALLOW_DIRTY=1
|
||||
;;
|
||||
*)
|
||||
atlas_usage_error "Unknown option: $1"
|
||||
exit "${ATLAS_EXIT_USAGE}"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
require_prerequisites() {
|
||||
atlas_require_command git
|
||||
atlas_require_command dotnet
|
||||
atlas_require_command curl
|
||||
atlas_require_sudo_noninteractive || {
|
||||
atlas_log_error "Passwordless non-interactive sudo is required"
|
||||
exit "${ATLAS_EXIT_PREREQ}"
|
||||
}
|
||||
|
||||
if [[ ! -d "${APP_REPO}/.git" ]]; then
|
||||
atlas_log_error "PlotDirector repository not found at ${APP_REPO}"
|
||||
exit "${ATLAS_EXIT_PREREQ}"
|
||||
fi
|
||||
|
||||
local current_branch
|
||||
current_branch="$(git -C "$APP_REPO" branch --show-current)"
|
||||
if [[ "$current_branch" != "$APP_BRANCH" ]]; then
|
||||
atlas_log_error "Expected ${APP_REPO} to be on ${APP_BRANCH}; found ${current_branch}"
|
||||
exit "${ATLAS_EXIT_UNSAFE}"
|
||||
fi
|
||||
|
||||
if [[ "$ALLOW_DIRTY" != "1" ]] && [[ -n "$(git -C "$APP_REPO" status --porcelain)" ]]; then
|
||||
atlas_log_error "PlotDirector working tree is dirty. Use --allow-dirty only for deliberate local deployments."
|
||||
exit "${ATLAS_EXIT_UNSAFE}"
|
||||
fi
|
||||
|
||||
if ! sudo -n test -f "$ENV_FILE"; then
|
||||
atlas_log_error "Runtime environment file is missing: ${ENV_FILE}"
|
||||
exit "${ATLAS_EXIT_PREREQ}"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_runtime_user_and_dirs() {
|
||||
if atlas_is_dry_run; then
|
||||
atlas_log_info "Dry-run mode: would ensure ${SERVICE_USER} user and deployment directories"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! id "$SERVICE_USER" >/dev/null 2>&1; then
|
||||
sudo -n useradd --system --home-dir /srv/apps/plotdirector-dev --shell /usr/sbin/nologin --create-home "$SERVICE_USER"
|
||||
fi
|
||||
|
||||
sudo -n install -d -m 0750 -o "$SERVICE_USER" -g "$SERVICE_USER" /srv/apps/plotdirector-dev "$PUBLISH_DIR" "$UPLOADS_DIR"
|
||||
local srv_mode
|
||||
srv_mode="$(stat -c '%a' /srv)"
|
||||
if (( (8#$srv_mode & 0001) == 0 )); then
|
||||
sudo -n chmod o+x /srv
|
||||
fi
|
||||
sudo -n chown root:"$SERVICE_USER" /etc/plotdirector
|
||||
sudo -n chmod 0750 /etc/plotdirector
|
||||
sudo -n chown root:"$SERVICE_USER" "$ENV_FILE"
|
||||
sudo -n chmod 0640 "$ENV_FILE"
|
||||
}
|
||||
|
||||
publish_application() {
|
||||
if atlas_is_dry_run; then
|
||||
atlas_log_info "Dry-run mode: would restore and publish ${APP_PROJECT} to ${PUBLISH_DIR}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local publish_tmp
|
||||
publish_tmp="$(mktemp -d)"
|
||||
dotnet restore "$APP_PROJECT"
|
||||
dotnet publish "$APP_PROJECT" --configuration Release --output "$publish_tmp"
|
||||
sudo -n rsync -a --delete "${publish_tmp}/" "${PUBLISH_DIR}/"
|
||||
sudo -n chown -R "${SERVICE_USER}:${SERVICE_USER}" "$PUBLISH_DIR" "$UPLOADS_DIR"
|
||||
sudo -n find "$PUBLISH_DIR" -type d -exec chmod 0750 {} +
|
||||
sudo -n find "$PUBLISH_DIR" -type f -exec chmod 0640 {} +
|
||||
rm -rf "$publish_tmp"
|
||||
}
|
||||
|
||||
deploy_systemd_unit() {
|
||||
if atlas_is_dry_run; then
|
||||
atlas_log_info "Dry-run mode: would deploy ${SYSTEMD_DEST}"
|
||||
atlas_log_info "Dry-run mode: would enable ${SERVICE_NAME}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ -f "$SYSTEMD_DEST" ]] && cmp -s "$SYSTEMD_SOURCE" "$SYSTEMD_DEST"; then
|
||||
atlas_log_ok "No change required for ${SYSTEMD_DEST}"
|
||||
else
|
||||
sudo -n install -m 0644 -o root -g root "$SYSTEMD_SOURCE" "$SYSTEMD_DEST"
|
||||
atlas_log_ok "Updated ${SYSTEMD_DEST}"
|
||||
fi
|
||||
sudo -n systemctl daemon-reload
|
||||
sudo -n systemctl enable "$SERVICE_NAME"
|
||||
}
|
||||
|
||||
deploy_nginx_site() {
|
||||
if atlas_is_dry_run; then
|
||||
atlas_log_info "Dry-run mode: would deploy nginx site ${NGINX_DEST}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sudo -n install -d -m 0755 /etc/nginx/sites-available /etc/nginx/sites-enabled
|
||||
sudo -n install -d -m 0750 "$NGINX_BACKUP_DIR"
|
||||
sudo -n nginx -t
|
||||
sudo -n install -m 0644 "$NGINX_SOURCE" "$NGINX_DEST"
|
||||
sudo -n ln -sfn "$NGINX_DEST" "$NGINX_LINK"
|
||||
sudo -n nginx -t
|
||||
}
|
||||
|
||||
restart_and_verify() {
|
||||
if atlas_is_dry_run; then
|
||||
atlas_log_info "Dry-run mode: would restart ${SERVICE_NAME}, reload nginx, and verify HTTP responses"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sudo -n systemctl restart "$SERVICE_NAME"
|
||||
|
||||
local attempt
|
||||
for attempt in {1..30}; do
|
||||
if curl -fsS http://127.0.0.1:5050/ >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
curl -fsS http://127.0.0.1:5050/ >/dev/null
|
||||
sudo -n nginx -t
|
||||
sudo -n systemctl reload nginx
|
||||
curl -fsS -H "Host: dev.plotdirector.com" http://127.0.0.1/health >/dev/null
|
||||
atlas_log_ok "PlotDirector development deployment verified"
|
||||
}
|
||||
|
||||
main() {
|
||||
require_prerequisites
|
||||
ensure_runtime_user_and_dirs
|
||||
publish_application
|
||||
deploy_systemd_unit
|
||||
deploy_nginx_site
|
||||
restart_and_verify
|
||||
}
|
||||
|
||||
main
|
||||
@ -23,6 +23,8 @@ Each phase must source the shared framework under `install/lib/`, support dry-ru
|
||||
- `10-dotnet.sh`: installs the required .NET 8 and .NET 10 SDKs from official Ubuntu package sources.
|
||||
- `20-sql-server.sh`: deploys SQL Server 2025 Developer using Microsoft's official container image.
|
||||
- `30-docker.sh`: installs Docker Engine from Docker's official Ubuntu APT repository.
|
||||
- `40-nginx.sh`: installs nginx and deploys the temporary Atlas status site.
|
||||
- `50-plotdirector-dev.sh`: publishes and restarts the PlotDirector development instance from `/srv/repos/PlotDirector`.
|
||||
|
||||
Installed SDKs after the current Phase 2 run:
|
||||
|
||||
@ -35,3 +37,15 @@ Current SQL Server deployment:
|
||||
- Digest: `sha256:698682bab57c02c42bc0aa274b158aeb242d8e9104149a7489628d5535805816`
|
||||
- Container: `atlas-sql-server`
|
||||
- Compose project: `atlas-sql`
|
||||
|
||||
Current PlotDirector development deployment:
|
||||
|
||||
- Repository: `/srv/repos/PlotDirector`
|
||||
- Branch: `onboarding`
|
||||
- Entry project: `PlotLine/PlotLine.csproj`
|
||||
- Target framework: `net10.0`
|
||||
- Assembly: `PlotLine.dll`
|
||||
- Published path: `/srv/apps/plotdirector-dev/current`
|
||||
- Service: `plotdirector-dev`
|
||||
- nginx hostname: `dev.plotdirector.com`
|
||||
- Database: `PlotDirector_Development`
|
||||
|
||||
@ -53,3 +53,4 @@ Additional areas may be added when a repeated operational need exists.
|
||||
- Include validation and rollback guidance for service-affecting scripts.
|
||||
- Discovery and validation scripts must not dump environment variables, private keys, tokens, or complete sensitive configuration files.
|
||||
- SQL helper scripts must not embed or print SQL administrator passwords.
|
||||
- Firewall inspection should use `sudo ufw status numbered`.
|
||||
|
||||
@ -31,4 +31,3 @@ fi
|
||||
exec sudo -n docker exec -i "$CONTAINER_NAME" /bin/bash -lc \
|
||||
'SQLCMDPASSWORD="$MSSQL_SA_PASSWORD" exec /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -C "$@"' \
|
||||
sqlcmd "$@"
|
||||
|
||||
|
||||
@ -131,6 +131,16 @@ sql_container_health() {
|
||||
fi
|
||||
}
|
||||
|
||||
nginx_status() {
|
||||
if ! have nginx; then
|
||||
printf 'not installed\n'
|
||||
elif systemctl is-active --quiet nginx 2>/dev/null && sudo -n nginx -t >/dev/null 2>&1; then
|
||||
printf 'active-config-valid\n'
|
||||
else
|
||||
printf 'installed-needs-attention\n'
|
||||
fi
|
||||
}
|
||||
|
||||
mount_status() {
|
||||
local path="$1"
|
||||
if have findmnt && findmnt -rn --target "$path" >/dev/null 2>&1; then
|
||||
@ -243,6 +253,7 @@ human_report() {
|
||||
printf ' Docker Compose: %s\n\n' "$(if have docker; then docker compose version 2>/dev/null | sed -n '1p'; else printf 'not installed'; fi)"
|
||||
printf ' Docker status: %s\n' "$(docker_status)"
|
||||
printf ' SQL Server container health: %s\n\n' "$(sql_container_health)"
|
||||
printf ' nginx status: %s\n\n' "$(nginx_status)"
|
||||
|
||||
printf 'Services\n'
|
||||
printf ' Failed systemd services:\n'
|
||||
@ -305,6 +316,7 @@ json_report() {
|
||||
--arg docker_version "$(component_version docker --version)" \
|
||||
--arg docker_status "$(docker_status)" \
|
||||
--arg sql_container_health "$(sql_container_health)" \
|
||||
--arg nginx_status "$(nginx_status)" \
|
||||
--arg hostname "$(hostname)" \
|
||||
--arg host_overrides "$(local_host_overrides_present)" \
|
||||
--arg firewall "$(firewall_summary)" \
|
||||
@ -333,7 +345,8 @@ json_report() {
|
||||
nginx: $nginx_version,
|
||||
docker: $docker_version,
|
||||
docker_status: $docker_status,
|
||||
sql_server_container_health: $sql_container_health
|
||||
sql_server_container_health: $sql_container_health,
|
||||
nginx_status: $nginx_status
|
||||
},
|
||||
services: {failed_systemd_units: ($failed_services | split("\n") | map(select(length > 0)))},
|
||||
network: {
|
||||
|
||||
@ -246,6 +246,37 @@ check_docker_sql_state() {
|
||||
fi
|
||||
}
|
||||
|
||||
check_nginx_ufw_state() {
|
||||
if command -v nginx >/dev/null 2>&1; then
|
||||
systemctl is-active --quiet nginx && atlas_validation_result PASS "nginx service is active" || atlas_validation_result FAIL "nginx service is not active"
|
||||
sudo -n nginx -t >/dev/null 2>&1 && atlas_validation_result PASS "nginx configuration is valid" || atlas_validation_result FAIL "nginx configuration is invalid"
|
||||
curl -fsS http://127.0.0.1/health >/dev/null 2>&1 && atlas_validation_result PASS "Atlas nginx health endpoint is reachable" || atlas_validation_result FAIL "Atlas nginx health endpoint is not reachable"
|
||||
else
|
||||
atlas_validation_result SKIPPED "nginx is not installed"
|
||||
fi
|
||||
|
||||
if command -v ufw >/dev/null 2>&1 && sudo -n ufw status | grep -q '^Status: active'; then
|
||||
atlas_validation_result PASS "UFW is active"
|
||||
sudo -n ufw status numbered | grep -q '22/tcp' && atlas_validation_result PASS "UFW allows SSH" || atlas_validation_result FAIL "UFW SSH rule missing"
|
||||
sudo -n ufw status numbered | grep -q '80/tcp' && atlas_validation_result PASS "UFW allows HTTP" || atlas_validation_result FAIL "UFW HTTP rule missing"
|
||||
sudo -n ufw status numbered | grep -q '443/tcp' && atlas_validation_result PASS "UFW allows HTTPS" || atlas_validation_result FAIL "UFW HTTPS rule missing"
|
||||
sudo -n ufw status numbered | grep -q '1433/tcp.*192.168.10.0/24' && atlas_validation_result PASS "UFW restricts SQL Server to LAN subnet" || atlas_validation_result FAIL "UFW SQL LAN rule missing"
|
||||
else
|
||||
atlas_validation_result FAIL "UFW is not active"
|
||||
fi
|
||||
|
||||
if ss -ltn | awk '{print $4}' | grep -qx '192.168.10.10:1433'; then
|
||||
atlas_validation_result PASS "SQL Server is bound to Atlas LAN address"
|
||||
else
|
||||
atlas_validation_result FAIL "SQL Server is not bound to Atlas LAN address"
|
||||
fi
|
||||
if ss -ltn | awk '{print $4}' | grep -Eq '(^0\.0\.0\.0:1433$|^\[::\]:1433$)'; then
|
||||
atlas_validation_result FAIL "SQL Server is bound to all interfaces"
|
||||
else
|
||||
atlas_validation_result PASS "SQL Server is not bound to all interfaces"
|
||||
fi
|
||||
}
|
||||
|
||||
atlas_validation_reset
|
||||
|
||||
printf 'Atlas Host Validation\n'
|
||||
@ -290,6 +321,7 @@ check_free_space /sql "$MIN_SQL_FREE_GIB"
|
||||
|
||||
check_failed_services
|
||||
check_docker_sql_state
|
||||
check_nginx_ufw_state
|
||||
|
||||
if [[ -f /var/run/reboot-required ]]; then
|
||||
atlas_validation_result WARNING "Reboot is pending"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user