diff --git a/.woodpecker/ci.yml b/.woodpecker/ci.yml index de76665..6d8bebe 100644 --- a/.woodpecker/ci.yml +++ b/.woodpecker/ci.yml @@ -7,44 +7,44 @@ when: - event: manual steps: - install: - image: node:22-bookworm-slim - commands: - - corepack enable - - corepack prepare pnpm@latest --activate - - pnpm install --frozen-lockfile + - name: Install + image: node:22-bookworm-slim + commands: + - corepack enable + - corepack prepare pnpm@latest --activate + - pnpm install --frozen-lockfile - prettier: - image: node:22-bookworm-slim - commands: - - corepack enable && corepack prepare pnpm@latest --activate - - pnpm run format:check - depends_on: - - install + - name: Prettier + image: node:22-bookworm-slim + commands: + - corepack enable && corepack prepare pnpm@latest --activate + - pnpm run format:check + depends_on: + - Install - lint: - image: node:22-bookworm-slim - commands: - - corepack enable && corepack prepare pnpm@latest --activate - - pnpm run lint - depends_on: - - prettier + - name: Lint + image: node:22-bookworm-slim + commands: + - corepack enable && corepack prepare pnpm@latest --activate + - pnpm run lint + depends_on: + - Prettier - test: - image: node:22-bookworm-slim - commands: - - corepack enable && corepack prepare pnpm@latest --activate - - pnpm run test - depends_on: - - lint + - name: Tests & Coverage + image: node:22-bookworm-slim + commands: + - corepack enable && corepack prepare pnpm@latest --activate + - pnpm run test:coverage + depends_on: + - Lint - build: - image: node:22-bookworm-slim - commands: - - corepack enable && corepack prepare pnpm@latest --activate - - pnpm run build - depends_on: - - test + - name: Build + image: node:22-bookworm-slim + commands: + - corepack enable && corepack prepare pnpm@latest --activate + - pnpm run build + depends_on: + - Tests & Coverage # build-full: # image: node:22-bookworm-slim diff --git a/docker-compose.portainer.yml b/docker-compose.portainer.yml index 8fdb275..460b688 100644 --- a/docker-compose.portainer.yml +++ b/docker-compose.portainer.yml @@ -137,9 +137,10 @@ services: networks: - marina-net - backend + # Use service_started so the stack can deploy even if qr_api is still broken; switch to service_healthy once qr_api image is fixed. depends_on: qr_api: - condition: service_healthy + condition: service_started environment: QR_API_URL: http://qr_api:8080 healthcheck: diff --git a/docs/reset-db-password.md b/docs/reset-db-password.md new file mode 100644 index 0000000..59d4631 --- /dev/null +++ b/docs/reset-db-password.md @@ -0,0 +1,57 @@ +# Resetting the Kutt PostgreSQL password + +If you lost the stack env vars (e.g. after deleting the Portainer stack) and need to use the existing database with a new password, you have two options. + +**Default DB user/db name from compose:** `kutt` / `kutt` (or whatever you set in `DB_USER` / `DB_NAME`). +**Data path on host:** `/mnt/config/docker/kutt/postgres` (from `docker-compose.portainer.yml`). + +--- + +## Option A: Fresh start (delete all Kutt data) + +Use this if you **don’t need** existing links/users. + +1. On the host, remove the Postgres data directory: + ```bash + sudo rm -rf /mnt/config/docker/kutt/postgres + ``` +2. In Portainer, (re-)create the stack and set env vars, including a new `DB_PASSWORD`. +3. Deploy. Postgres will initialise a new database with the new password. + +--- + +## Option B: Keep data, force-set a new password + +Use this if you **want to keep** existing Kutt data but don’t know the current password. +**Stop the stack first** (so nothing is using the Postgres data volume). + +1. On the host, temporarily allow local connections without a password: + ```bash + cd /mnt/config/docker/kutt/postgres + cp pg_hba.conf pg_hba.conf.bak + echo 'local all all trust' > pg_hba.conf + echo 'host all all 127.0.0.1/32 trust' >> pg_hba.conf + echo 'host all all ::1/128 trust' >> pg_hba.conf + ``` + +2. Start a temporary Postgres container (it will use the modified `pg_hba.conf`): + ```bash + docker run -d --name pg-reset \ + -v /mnt/config/docker/kutt/postgres:/var/lib/postgresql/data \ + postgres:16-alpine + sleep 5 + ``` + +3. Set the new password (replace `kutt` if you use a different `DB_USER`, and set `YOUR_NEW_PASSWORD`): + ```bash + docker exec pg-reset psql -U postgres -c "ALTER USER kutt PASSWORD 'YOUR_NEW_PASSWORD';" + ``` + +4. Stop the temporary container and restore `pg_hba.conf`: + ```bash + docker stop pg-reset && docker rm pg-reset + cd /mnt/config/docker/kutt/postgres + mv pg_hba.conf.bak pg_hba.conf + ``` + +5. In Portainer, create/redeploy the stack and set `DB_PASSWORD` (and other env vars) to the same `YOUR_NEW_PASSWORD`. diff --git a/qr-api/Dockerfile b/qr-api/Dockerfile index c9f6e40..ce30ea8 100644 --- a/qr-api/Dockerfile +++ b/qr-api/Dockerfile @@ -1,4 +1,4 @@ -# Build stage: compile app and native deps (better-sqlite3) for target platform. +# Build stage: TypeScript only (no native deps in this stage). FROM node:20-bookworm-slim AS builder RUN corepack enable && corepack prepare pnpm@latest --activate WORKDIR /app @@ -6,14 +6,20 @@ COPY package.json pnpm-lock.yaml* ./ RUN pnpm install COPY . . RUN pnpm run build -RUN pnpm prune --prod -# Runtime: copy built artifacts and node_modules (with compiled better_sqlite3.node). +# Runtime: install deps here so better-sqlite3 is compiled for this exact image/platform. FROM node:20-bookworm-slim WORKDIR /app ENV NODE_ENV=production -COPY package.json ./ -COPY --from=builder /app/node_modules ./node_modules +# Install build deps needed to compile better-sqlite3; remove after install to keep image small. +RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ \ + && rm -rf /var/lib/apt/lists/* +RUN corepack enable && corepack prepare pnpm@latest --activate +COPY package.json pnpm-lock.yaml* ./ +RUN pnpm install --prod \ + && apt-get purge -y python3 make g++ \ + && apt-get autoremove -y --purge \ + && rm -rf /var/lib/apt/lists/* COPY --from=builder /app/dist ./dist EXPOSE 8080 CMD ["node", "dist/index.js"] diff --git a/qr-web/vitest.config.ts b/qr-web/vitest.config.mts similarity index 87% rename from qr-web/vitest.config.ts rename to qr-web/vitest.config.mts index b3dade2..478f4d9 100644 --- a/qr-web/vitest.config.ts +++ b/qr-web/vitest.config.mts @@ -1,6 +1,9 @@ import { defineConfig } from 'vitest/config'; import react from '@vitejs/plugin-react'; import path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default defineConfig({ plugins: [react()],