Add testing environment deployment and DNS helpers

This commit is contained in:
Tero Halla-aho 2025-12-06 17:33:17 +02:00
parent b1cee2c0d7
commit 4201884609
9 changed files with 91 additions and 7 deletions

View file

@ -27,6 +27,7 @@
# Lomavuokraus app progress (Nov 24)
- New testing DB (`lomavuokraus_testing`) holds the previous staging/prod data; the main `lomavuokraus` DB was recreated clean with only the seeded admin user. Migration history was copied, and a schema snapshot lives at `docs/db-schema.sql`.
- Testing environment wiring added: dedicated namespace (`lomavuokraus-test`), deploy wrapper (`deploy/deploy-test.sh`), API host support, and a DNS updater for `test.lomavuokraus.fi` / `apitest.lomavuokraus.fi`.
- Backend/data: Added Prisma models (User/Listing/ListingTranslation/ListingImage), seed script creates sample listing; DB on Hetzner VM `46.62.203.202`, staging secrets set in `lomavuokraus-web-secrets`.
- Auth: Register/login/verify flows; session cookie (`session_token`), NavBar shows email+role badge. Roles: USER, ADMIN, USER_MODERATOR (approve users), LISTING_MODERATOR (approve listings). Admin can change roles at `/admin/users`.
- Listing flow: create listing (session required), pending/published with admin/moderator approvals; pages for “My listings,” “New listing,” “Profile.” Quick actions tile removed; all actions in navbar.

18
deploy/deploy-test.sh Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
source deploy/env.sh
export K8S_NAMESPACE="${TEST_NAMESPACE}"
export APP_HOST="${TEST_HOST}"
export API_HOST="${TEST_API_HOST:-$TEST_HOST}"
export NEXT_PUBLIC_SITE_URL="https://${APP_HOST}"
export NEXT_PUBLIC_API_BASE="https://${API_HOST}/api"
export APP_ENV="testing"
export CLUSTER_ISSUER="${TEST_CLUSTER_ISSUER}"
export INGRESS_CLASS
export APP_REPLICAS="${APP_REPLICAS:-1}"
# optionally set APP_SECRET and DATABASE_URL (pointing to lomavuokraus_testing) in the environment before running
bash deploy/deploy.sh

View file

@ -16,16 +16,27 @@ if [[ -z "${K8S_NAMESPACE:-}" || -z "${APP_HOST:-}" || -z "${NEXT_PUBLIC_SITE_UR
prod|production)
K8S_NAMESPACE="${K8S_NAMESPACE:-$PROD_NAMESPACE}"
APP_HOST="${APP_HOST:-$PROD_HOST}"
NEXT_PUBLIC_SITE_URL="${NEXT_PUBLIC_SITE_URL:-https://$PROD_HOST}"
NEXT_PUBLIC_API_BASE="${NEXT_PUBLIC_API_BASE:-https://$PROD_HOST/api}"
API_HOST="${API_HOST:-$PROD_HOST}"
NEXT_PUBLIC_SITE_URL="${NEXT_PUBLIC_SITE_URL:-https://$APP_HOST}"
NEXT_PUBLIC_API_BASE="${NEXT_PUBLIC_API_BASE:-https://$API_HOST/api}"
APP_ENV="${APP_ENV:-production}"
CLUSTER_ISSUER="${CLUSTER_ISSUER:-$PROD_CLUSTER_ISSUER}"
;;
test|testing)
K8S_NAMESPACE="${K8S_NAMESPACE:-$TEST_NAMESPACE}"
APP_HOST="${APP_HOST:-$TEST_HOST}"
API_HOST="${API_HOST:-$TEST_API_HOST:-$TEST_HOST}"
NEXT_PUBLIC_SITE_URL="${NEXT_PUBLIC_SITE_URL:-https://$APP_HOST}"
NEXT_PUBLIC_API_BASE="${NEXT_PUBLIC_API_BASE:-https://$API_HOST/api}"
APP_ENV="${APP_ENV:-testing}"
CLUSTER_ISSUER="${CLUSTER_ISSUER:-$TEST_CLUSTER_ISSUER:-$STAGING_CLUSTER_ISSUER}"
;;
staging|stage|stg|*)
K8S_NAMESPACE="${K8S_NAMESPACE:-$STAGING_NAMESPACE}"
APP_HOST="${APP_HOST:-$STAGING_HOST}"
NEXT_PUBLIC_SITE_URL="${NEXT_PUBLIC_SITE_URL:-https://$STAGING_HOST}"
NEXT_PUBLIC_API_BASE="${NEXT_PUBLIC_API_BASE:-https://$STAGING_HOST/api}"
API_HOST="${API_HOST:-$STAGING_HOST}"
NEXT_PUBLIC_SITE_URL="${NEXT_PUBLIC_SITE_URL:-https://$APP_HOST}"
NEXT_PUBLIC_API_BASE="${NEXT_PUBLIC_API_BASE:-https://$API_HOST/api}"
APP_ENV="${APP_ENV:-staging}"
CLUSTER_ISSUER="${CLUSTER_ISSUER:-$STAGING_CLUSTER_ISSUER}"
;;
@ -36,17 +47,19 @@ fi
: "${K8S_NAMESPACE:?K8S_NAMESPACE pitää asettaa}"
: "${APP_HOST:?APP_HOST pitää asettaa}"
: "${API_HOST:=${APP_HOST}}"
: "${NEXT_PUBLIC_SITE_URL:?NEXT_PUBLIC_SITE_URL pitää asettaa}"
: "${NEXT_PUBLIC_API_BASE:?NEXT_PUBLIC_API_BASE pitää asettaa}"
: "${APP_ENV:?APP_ENV pitää asettaa}"
: "${CLUSTER_ISSUER:?CLUSTER_ISSUER pitää asettaa}"
: "${INGRESS_CLASS:?INGRESS_CLASS pitää asettaa}"
: "${APP_REPLICAS:=${APP_REPLICAS:-2}}"
IMAGE=$(cat deploy/.last-image)
K8S_IMAGE="$IMAGE"
APP_VERSION="${APP_VERSION:-$(echo \"$IMAGE\" | awk -F: '{print $NF}')}"
export K8S_NAMESPACE APP_HOST NEXT_PUBLIC_SITE_URL NEXT_PUBLIC_API_BASE APP_ENV CLUSTER_ISSUER INGRESS_CLASS K8S_IMAGE APP_VERSION
export K8S_NAMESPACE APP_HOST API_HOST NEXT_PUBLIC_SITE_URL NEXT_PUBLIC_API_BASE APP_ENV CLUSTER_ISSUER INGRESS_CLASS APP_REPLICAS K8S_IMAGE APP_VERSION
TMP_MANIFEST=$(mktemp)
envsubst < k8s/app.yaml > "$TMP_MANIFEST"

View file

@ -8,12 +8,16 @@ export REGISTRY_REPO="thalla/lomavuokraus-web"
export DEPLOYMENT_NAME="lomavuokraus-web"
export PROD_NAMESPACE="lomavuokraus-prod"
export STAGING_NAMESPACE="lomavuokraus-staging"
export TEST_NAMESPACE="lomavuokraus-test"
# ---- Domains and cert-manager issuers ----
export PROD_HOST="lomavuokraus.fi"
export STAGING_HOST="staging.lomavuokraus.fi"
export TEST_HOST="test.lomavuokraus.fi"
export TEST_API_HOST="apitest.lomavuokraus.fi"
export PROD_CLUSTER_ISSUER="letsencrypt-prod"
export STAGING_CLUSTER_ISSUER="letsencrypt-staging"
export TEST_CLUSTER_ISSUER="letsencrypt-staging"
# ---- Ingress class (k3s ships with Traefik by default) ----
export INGRESS_CLASS="traefik"

30
deploy/update-test-dns.sh Executable file
View file

@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
AUTH_FILE="creds/joker_com_dyndns_creds.txt"
if [[ ! -f "$AUTH_FILE" ]]; then
echo "Joker DYNDNS credentials missing at $AUTH_FILE" >&2
exit 1
fi
JOKER_AUTH="$(cat "$AUTH_FILE")"
TARGET_IP="${TARGET_IP:-157.180.66.64}"
TEST_HOST="${TEST_HOST:-test.lomavuokraus.fi}"
TEST_API_HOST="${TEST_API_HOST:-apitest.lomavuokraus.fi}"
update_host() {
local host="$1"
echo "Updating $host -> $TARGET_IP"
local resp
resp="$(curl -sS -u "$JOKER_AUTH" "https://svc.joker.com/nic/update?hostname=${host}&myip=${TARGET_IP}")"
echo "$resp"
if [[ "$resp" != good* && "$resp" != nochg* ]]; then
echo "DNS update failed for $host (response: $resp)" >&2
exit 1
fi
}
update_host "$TEST_HOST"
update_host "$TEST_API_HOST"

View file

@ -73,8 +73,10 @@ flowchart LR
<ul>
<li><code>deploy/deploy-staging.sh</code></li>
<li><code>deploy/deploy-prod.sh</code></li>
<li><code>deploy/deploy-test.sh</code></li>
</ul>
</li>
<li>DNS helpers: <code>deploy/update-test-dns.sh</code> updates test.lomavuokraus.fi + apitest.lomavuokraus.fi via Joker DYNDNS.</li>
</ul>
</section>

View file

@ -69,7 +69,7 @@ flowchart TB
<h2>Cluster &amp; Namespaces</h2>
<ul>
<li>Single-node k3s (Hetzner hel1 cx22) at <code>157.180.66.64</code>.</li>
<li>Namespaces: <code>lomavuokraus-prod</code>, <code>lomavuokraus-staging</code>.</li>
<li>Namespaces: <code>lomavuokraus-prod</code>, <code>lomavuokraus-staging</code>, <code>lomavuokraus-test</code>.</li>
<li>Ingress controller: Traefik (k3s default).</li>
<li>cert-manager v1.15.3 with ClusterIssuers:
<ul>

View file

@ -78,7 +78,7 @@ metadata:
labels:
app: lomavuokraus-web
spec:
replicas: 2
replicas: ${APP_REPLICAS}
selector:
matchLabels:
app: lomavuokraus-web
@ -185,6 +185,7 @@ spec:
tls:
- hosts:
- ${APP_HOST}
- ${API_HOST}
secretName: lomavuokraus-web-tls
rules:
- host: ${APP_HOST}
@ -197,3 +198,13 @@ spec:
name: lomavuokraus-web
port:
number: 80
- host: ${API_HOST}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: lomavuokraus-web
port:
number: 80

View file

@ -7,3 +7,8 @@ apiVersion: v1
kind: Namespace
metadata:
name: lomavuokraus-staging
---
apiVersion: v1
kind: Namespace
metadata:
name: lomavuokraus-test