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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/compose-secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ jobs:

- name: Check profile templates and required Compose secrets
run: bash tools/scripts/check-compose-secrets.sh

- name: Check setup appends secrets on an existing .env
run: bash tools/tests/test_setup_compose_secrets.sh
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

#### Stack-level

- **Setup**: `setup.sh` and `setup.ps1` append `SITMUN_USER_SECRET`, `MIDDLEWARE_SECRET`, and `SITMUN_MBTILES_JOB_HANDLE_SECRET` when `.env` already exists and a key is absent. An existing value is kept. Windows setup uses `RandomNumberGenerator` and does not call `openssl` ([#138](https://github.com/sitmun/sitmun-application-stack/issues/138)).
- **Docker**: Each `profiles/*.env` template names `SITMUN_USER_SECRET`, `MIDDLEWARE_SECRET`, and `SITMUN_MBTILES_JOB_HANDLE_SECRET` and leaves them unset. Copying a profile to `.env` still requires generated values before Compose will start ([#134](https://github.com/sitmun/sitmun-application-stack/issues/134)).
- **Liquibase**: `service.type` is limited to `WMS`, `WFS`, and `WMTS` on the development, postgres, and oracle profiles. A stored service of another type is not deleted ([#101](https://github.com/sitmun/sitmun-application-stack/issues/101)).
- **Docker**: `docker compose build front` uses the Angular 22 viewer webpack config. `envsubst` replaces only `PUBLIC_BASE_PATH`, so the viewer image build keeps the `jszip`, `util`, and `@spz-loader` exclusions.
Expand Down
85 changes: 31 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,9 @@ The stack has four main components:
cd sitmun-application-stack
```

2. **Setup the environment**
2. **Select a profile (`.env`)**

For Unix-based systems (Linux/macOS):

```bash
./setup.sh
```

For Windows systems:

```powershell
./setup.ps1
```

3. **Select a profile (`.env`)**

The stack is configured via `.env`. Recommended profiles are under `profiles/`:
The stack is configured via `.env`. Copy a profile before setup. If `.env` is still missing, setup uses `profiles/development-postgres.env`.

```bash
# Development (PostgreSQL)
Expand All @@ -107,17 +93,23 @@ The stack has four main components:
# cp profiles/development-oracle.env .env
```

Notes:
- The setup scripts create `.env` from `profiles/development-postgres.env` **only if** `.env` is missing. They then append `SITMUN_USER_SECRET`, `MIDDLEWARE_SECRET`, and `SITMUN_MBTILES_JOB_HANDLE_SECRET` when those keys are absent.
- A manual copy must append the same three values before Compose will start:
3. **Setup the environment**

For Unix-based systems (Linux/macOS):

```bash
echo "SITMUN_USER_SECRET=$(openssl rand -hex 32)" >> .env
echo "MIDDLEWARE_SECRET=$(openssl rand -hex 32)" >> .env
echo "SITMUN_MBTILES_JOB_HANDLE_SECRET=$(openssl rand -hex 32)" >> .env
./setup.sh
```

- You can keep local overrides in `.env.local` (not committed); Docker Compose loads `.env → .env.local → environment variables`.
For Windows systems:

```powershell
./setup.ps1
```

The scripts append `SITMUN_USER_SECRET`, `MIDDLEWARE_SECRET`, and `SITMUN_MBTILES_JOB_HANDLE_SECRET` when those keys are absent, including when `.env` was copied from a profile first. An existing value is left as it is. Windows does not need `openssl`. Run the script again after replacing `.env` with another profile.

You can keep local overrides in `.env.local` (not committed); Docker Compose loads `.env → .env.local → environment variables`.

4. **Start the SITMUN Application Stack**

Expand Down Expand Up @@ -147,7 +139,14 @@ The stack has four main components:
cd sitmun-application-stack
```

2. **Setup Environment**
2. **Select a development profile (`.env`)**

```bash
cp profiles/development-postgres.env .env
# Or: cp profiles/development-oracle.env .env
```

3. **Setup Environment**

```bash
# Unix-based systems
Expand All @@ -157,17 +156,7 @@ The stack has four main components:
./setup.ps1
```

3. **Select a development profile (`.env`)**

```bash
cp profiles/development-postgres.env .env
# Or: cp profiles/development-oracle.env .env
echo "SITMUN_USER_SECRET=$(openssl rand -hex 32)" >> .env
echo "MIDDLEWARE_SECRET=$(openssl rand -hex 32)" >> .env
echo "SITMUN_MBTILES_JOB_HANDLE_SECRET=$(openssl rand -hex 32)" >> .env
```

`./setup.sh` and `./setup.ps1` append those three keys when they create `.env` and the keys are absent. Do not commit the values.
`./setup.sh` and `./setup.ps1` append `SITMUN_USER_SECRET`, `MIDDLEWARE_SECRET`, and `SITMUN_MBTILES_JOB_HANDLE_SECRET` when those keys are absent. An existing value is kept. Do not commit the values.

4. **Start Services**

Expand Down Expand Up @@ -227,14 +216,7 @@ The stack has four main components:

2. **Secrets (mandatory)**

Production profiles (`profiles/postgres`, `profiles/oracle`) do **not** ship secret defaults. You must set these three variables in `.env`, each at least 32 characters:

```bash
# Backend JWT signing secret, backend-proxy shared secret, and MBTiles job handle
echo "SITMUN_USER_SECRET=$(openssl rand -hex 32)" >> .env
echo "MIDDLEWARE_SECRET=$(openssl rand -hex 32)" >> .env
echo "SITMUN_MBTILES_JOB_HANDLE_SECRET=$(openssl rand -hex 32)" >> .env
```
Production profiles (`profiles/postgres`, `profiles/oracle`) do **not** ship secret defaults. After the copy, run `./setup.sh` on Unix or `./setup.ps1` on Windows. The script appends `SITMUN_USER_SECRET`, `MIDDLEWARE_SECRET`, and `SITMUN_MBTILES_JOB_HANDLE_SECRET` when a key is absent. Each value is at least 32 characters. An existing value is kept. Windows does not need `openssl`.

Enforcement is fail-fast, so misconfiguration is caught before the platform serves traffic:

Expand Down Expand Up @@ -607,22 +589,20 @@ profiles/
postgres/ # PostgreSQL Liquibase and backend config, mounted by the root Compose file
```

PostgreSQL and Oracle start from the repository root. Copy the profile, append the three secrets when they are absent, then start the root Compose file. `SITMUN_CONFIG_DIR` mounts `profiles/postgres` or `profiles/oracle`.
PostgreSQL and Oracle start from the repository root. Copy the profile, run `./setup.sh` or `./setup.ps1` so the three secrets are appended when absent, then start the root Compose file. `SITMUN_CONFIG_DIR` mounts `profiles/postgres` or `profiles/oracle`.

```bash
cp profiles/postgres.env .env
echo "SITMUN_USER_SECRET=$(openssl rand -hex 32)" >> .env
echo "MIDDLEWARE_SECRET=$(openssl rand -hex 32)" >> .env
echo "SITMUN_MBTILES_JOB_HANDLE_SECRET=$(openssl rand -hex 32)" >> .env
./setup.sh
docker compose up -d

cp profiles/oracle.env .env
echo "SITMUN_USER_SECRET=$(openssl rand -hex 32)" >> .env
echo "MIDDLEWARE_SECRET=$(openssl rand -hex 32)" >> .env
echo "SITMUN_MBTILES_JOB_HANDLE_SECRET=$(openssl rand -hex 32)" >> .env
./setup.sh
docker compose up -d
```

On Windows, run `./setup.ps1` instead of `./setup.sh`.

### Development Workflow

1. **Update Repository and Submodules**
Expand Down Expand Up @@ -899,10 +879,7 @@ MIDDLEWARE_SECRET=<32+ char random value> # shared backend <-> proxy secret
SITMUN_MBTILES_JOB_HANDLE_SECRET=<32+ char random value> # proxy MBTiles job handle
```

```bash
# Generate secure random values
openssl rand -hex 32
```
`./setup.sh` and `./setup.ps1` append a value for each missing key. Windows does not need `openssl`.

**IMPORTANT for production**:

Expand Down
2 changes: 1 addition & 1 deletion profiles/development-lvh.env
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ ENVIRONMENT=development

# --- Security ---
# Required. Compose refuses to start until each value is set.
# Generate with: openssl rand -hex 32
# setup.sh and setup.ps1 append a value when this key is absent.
# SITMUN_USER_SECRET=
# MIDDLEWARE_SECRET=
# SITMUN_MBTILES_JOB_HANDLE_SECRET=
Expand Down
2 changes: 1 addition & 1 deletion profiles/development-oracle.env
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ DATABASE_URL=jdbc:oracle:thin:@//oracle:1521/

# --- Security ---
# Required. Compose refuses to start until each value is set.
# Generate with: openssl rand -hex 32
# setup.sh and setup.ps1 append a value when this key is absent.
# SITMUN_USER_SECRET=
# MIDDLEWARE_SECRET=
# SITMUN_MBTILES_JOB_HANDLE_SECRET=
Expand Down
2 changes: 1 addition & 1 deletion profiles/development-postgres.env
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ ENVIRONMENT=development

# --- Security ---
# Required. Compose refuses to start until each value is set.
# Generate with: openssl rand -hex 32
# setup.sh and setup.ps1 append a value when this key is absent.
# SITMUN_USER_SECRET=
# MIDDLEWARE_SECRET=
# SITMUN_MBTILES_JOB_HANDLE_SECRET=
Expand Down
2 changes: 1 addition & 1 deletion profiles/development.env
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ ENVIRONMENT=development

# --- Security ---
# Required. Compose refuses to start until each value is set.
# Generate with: openssl rand -hex 32
# setup.sh and setup.ps1 append a value when this key is absent.
# SITMUN_USER_SECRET=
# MIDDLEWARE_SECRET=
# SITMUN_MBTILES_JOB_HANDLE_SECRET=
Expand Down
2 changes: 1 addition & 1 deletion profiles/oracle.env
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ SPRING_LIQUIBASE_CONTEXTS=

# --- Security ---
# Required. Compose refuses to start until each value is set.
# Generate with: openssl rand -hex 32
# setup.sh and setup.ps1 append a value when this key is absent.
# SITMUN_USER_SECRET=
# MIDDLEWARE_SECRET=
# SITMUN_MBTILES_JOB_HANDLE_SECRET=
Expand Down
2 changes: 1 addition & 1 deletion profiles/postgres.env
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ SPRING_LIQUIBASE_CONTEXTS=

# --- Security ---
# Required. Compose refuses to start until each value is set.
# Generate with: openssl rand -hex 32
# setup.sh and setup.ps1 append a value when this key is absent.
# SITMUN_USER_SECRET=
# MIDDLEWARE_SECRET=
# SITMUN_MBTILES_JOB_HANDLE_SECRET=
Expand Down
10 changes: 5 additions & 5 deletions setup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,17 @@ function Add-ComposeSecretIfMissing {
}
}

# Copy default development profile to .env if .env does not exist.
# Profile files do not store secrets. Generate any of the three that are absent.
# Create .env from the development PostgreSQL profile when it is absent.
# Profile files do not store secrets. Append any of the three keys that are missing.
function Copy-EnvFileIfMissing {
if (-Not (Test-Path ".env")) {
Write-Host "${Yellow}.env file is missing. Copying profiles/development-postgres.env to .env...${Reset}"
Copy-Item -Path "profiles/development-postgres.env" -Destination ".env"
Add-ComposeSecretIfMissing -Key "SITMUN_USER_SECRET"
Add-ComposeSecretIfMissing -Key "MIDDLEWARE_SECRET"
Add-ComposeSecretIfMissing -Key "SITMUN_MBTILES_JOB_HANDLE_SECRET"
Write-Host "${Green}.env file created from profiles/development-postgres.env.${Reset}"
}
Add-ComposeSecretIfMissing -Key "SITMUN_USER_SECRET"
Add-ComposeSecretIfMissing -Key "MIDDLEWARE_SECRET"
Add-ComposeSecretIfMissing -Key "SITMUN_MBTILES_JOB_HANDLE_SECRET"
}

# Main logic
Expand Down
23 changes: 12 additions & 11 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,23 @@ append_compose_secret_if_missing() {
fi
}

# Copy default development profile to .env if .env does not exist.
# Profile files do not store secrets. Generate any of the three that are absent.
# Create .env from the development PostgreSQL profile when it is absent.
# Profile files do not store secrets. Append any of the three keys that are missing.
copy_env_file_if_missing() {
if [ ! -f ".env" ]; then
echo -e "${YELLOW}.env file is missing. Copying profiles/development-postgres.env to .env...${NC}"
cp profiles/development-postgres.env .env
append_compose_secret_if_missing SITMUN_USER_SECRET
append_compose_secret_if_missing MIDDLEWARE_SECRET
append_compose_secret_if_missing SITMUN_MBTILES_JOB_HANDLE_SECRET
echo -e "${GREEN}.env file created from profiles/development-postgres.env.${NC}"
fi
append_compose_secret_if_missing SITMUN_USER_SECRET
append_compose_secret_if_missing MIDDLEWARE_SECRET
append_compose_secret_if_missing SITMUN_MBTILES_JOB_HANDLE_SECRET
}

# Main logic
display_banner
check_git_repository
check_repository_url
update_from_remote
copy_env_file_if_missing
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
display_banner
check_git_repository
check_repository_url
update_from_remote
copy_env_file_if_missing
fi
76 changes: 76 additions & 0 deletions tools/tests/test_setup_compose_secrets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
# A copied profile .env has the three secret names only as comments.
# setup must append values without replacing one that is already set.
#
# bash tools/tests/test_setup_compose_secrets.sh
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT

assert_generated() {
local file="$1" key="$2"
if ! grep -qE "^${key}=[0-9a-f]{64}$" "$file"; then
echo "missing generated ${key} in ${file}" >&2
exit 1
fi
}

run_copy() {
local dir="$1"
(
cd "$dir"
# shellcheck disable=SC1091
source "$ROOT/setup.sh"
copy_env_file_if_missing
)
}

copied="$work/copied"
mkdir -p "$copied"
cp "$ROOT/profiles/postgres.env" "$copied/.env"
run_copy "$copied"
for key in SITMUN_USER_SECRET MIDDLEWARE_SECRET SITMUN_MBTILES_JOB_HANDLE_SECRET; do
assert_generated "$copied/.env" "$key"
done

kept="$work/kept"
mkdir -p "$kept"
cp "$ROOT/profiles/postgres.env" "$kept/.env"
printf '\nSITMUN_USER_SECRET=kept-value-0123456789abcdef0123456789abcd\n' >> "$kept/.env"
run_copy "$kept"
if ! grep -qx 'SITMUN_USER_SECRET=kept-value-0123456789abcdef0123456789abcd' "$kept/.env"; then
echo "existing SITMUN_USER_SECRET was replaced" >&2
exit 1
fi
if [[ "$(grep -c '^SITMUN_USER_SECRET=' "$kept/.env")" -ne 1 ]]; then
echo "SITMUN_USER_SECRET was duplicated" >&2
exit 1
fi
assert_generated "$kept/.env" MIDDLEWARE_SECRET
assert_generated "$kept/.env" SITMUN_MBTILES_JOB_HANDLE_SECRET

created="$work/created"
mkdir -p "$created/profiles"
cp "$ROOT/profiles/development-postgres.env" "$created/profiles/development-postgres.env"
run_copy "$created"
if ! grep -qx 'COMPOSE_PROFILES=postgres' "$created/.env"; then
echo "missing .env was not created from profiles/development-postgres.env" >&2
exit 1
fi
for key in SITMUN_USER_SECRET MIDDLEWARE_SECRET SITMUN_MBTILES_JOB_HANDLE_SECRET; do
assert_generated "$created/.env" "$key"
done

if grep -q 'openssl rand' "$ROOT/README.md"; then
echo "README still tells operators to run openssl" >&2
exit 1
fi

if grep -q 'openssl rand' "$ROOT"/profiles/*.env; then
echo "a profile env template still tells operators to run openssl" >&2
exit 1
fi

echo "setup appends the three compose secrets when .env already exists"
Loading