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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ This project serves as a starting point for a PWA (Progressive Web Application).

* [Expressjs](https://expressjs.com)
* [Workboxjs](https://developer.chrome.com/docs/workbox/)
* [Authorizer](https://authorizer.dev)
* [Authorizer](https://github.com/localnerve/authorizer)
* [Mariadb](https://mariadb.com)

### Development Dependencies
Expand Down
4 changes: 3 additions & 1 deletion docker/.env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ AUTHZ_SMTP_USER=smtpuser
AUTHZ_SMTP_PASSWORD=deadbeefcafebabe06
AUTHZ_SENDER_EMAIL=company@email.domain.local
AUTHZ_ORGANIZATION_NAME="Business Name"
AUTHZ_ORGANIZATION_LOGO=http://localhost:5000/images/logo-7322e21572.svg
AUTHZ_ORGANIZATION_LOGO=http://localhost:5000/images/logo-7322e21572.svg
JB_IMAGE=jam-build:latest
JB_CONTAINER_NAME=jam-build-service
21 changes: 21 additions & 0 deletions docker/.env.proxy
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
UID=501
GID=20
DB_HOST=mariadb
DB_DATABASE=jam_build
DB_USER=jbuser
DB_PASSWORD=deadbeefcafebabe01
DB_APP_USER=jbadmin
DB_APP_PASSWORD=deadbeefcafebabe02
DB_ROOT_PASSWORD=deadbeefcafebabe03
AUTHZ_ADMIN_SECRET=deadbeefcafebabe05
AUTHZ_CLIENT_ID=deadbeef-cafe-babe-feed-baadc0deface
AUTHZ_URL=https://rp-localnerve.duckdns.org
AUTHZ_SMTP_HOST=email.domain.local
AUTHZ_SMTP_PORT=587
AUTHZ_SMTP_USER=smtpuser
AUTHZ_SMTP_PASSWORD=deadbeefcafebabe06
AUTHZ_SENDER_EMAIL=company@email.domain.local
AUTHZ_ORGANIZATION_NAME="Business Name"
AUTHZ_ORGANIZATION_LOGO=https://ln.rp-localnerve.duckdns.org/images/logo-7322e21572.svg
JB_IMAGE=jam-build-proxy:latest
JB_CONTAINER_NAME=jam-build-proxy
1 change: 1 addition & 0 deletions docker/authorizer-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ services:
ENV: development
ADMIN_SECRET: deadbeefcafebabe
DATABASE_TYPE: mariadb
APP_COOKIE_SECURE: true # false for safari w/o TLS, stops everything else from working, persisted in features in mariadb
DATABASE_URL: admin:deadbeefcafebabe@tcp(host.docker.internal:3306)/authorizer
DATABASE_NAME: authorizer
CLIENT_ID: 'deadbeef-cafe-babe-feed-baadc0deface'
Expand Down
24 changes: 20 additions & 4 deletions docker/build-image.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
#!/bin/sh

# Get the value for $VAR_NAME from $ENV_FILE
find_envvar () {
VAR_NAME="$1"
while IFS= read -r line; do
# Skip comments and empty lines
[[ "$line" =~ ^[[:space:]]*# ]] && continue
[[ -z "$line" ]] && continue
# Echo the variable value if it contains an equals sign
[[ "$line" == $VAR_NAME=* ]] && echo "${line#*=}"
done < $ENV_FILE
}

SCRIPT_DIR=$(cd -- "$(dirname -- "$0")" &> /dev/null && pwd)
PROJECT_DIR=$(readlink -f $SCRIPT_DIR/..)
DOCKER_FILE=$PROJECT_DIR/Dockerfile

# If not exist, falls back to environment
HOSTENV_FILE=$PROJECT_DIR/private/host-env.json

# Change these if building a non-demo image
export AUTHZ_URL=http://localhost:9010
export AUTHZ_CLIENT_ID=deadbeef-cafe-babe-feed-baadc0deface
# Assign AUTHZ_URL and AUTHZ_CLIENT_ID from env file identified by .env.$1 (default .env.dev)
BUILD_TYPE="$1" # $1 'proxy' or empty
IMAGE_TAG=jam-build${BUILD_TYPE:+-$BUILD_TYPE}
ENV_FILE=$SCRIPT_DIR/.env.${BUILD_TYPE:-dev}
export AUTHZ_URL=$(find_envvar AUTHZ_URL)
export AUTHZ_CLIENT_ID=$(find_envvar AUTHZ_CLIENT_ID)

docker buildx build --tag "jam-build" --secret id=jam-build,src=$HOSTENV_FILE --file $DOCKER_FILE $PROJECT_DIR --build-arg UID=`id -u` --build-arg GID=`id -g` --build-arg AUTHZ_URL --build-arg AUTHZ_CLIENT_ID
echo Building "$IMAGE_TAG" image with AUTHZ_URL=$AUTHZ_URL and AUTHZ_CLIENT_ID=$AUTHZ_CLIENT_ID
docker buildx build --tag "$IMAGE_TAG" --secret id=jam-build,src=$HOSTENV_FILE --file $DOCKER_FILE $PROJECT_DIR --build-arg UID=`id -u` --build-arg GID=`id -g` --build-arg AUTHZ_URL --build-arg AUTHZ_CLIENT_ID
2 changes: 1 addition & 1 deletion docker/compose-container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
SCRIPT_DIR=$(cd -- "$(dirname -- "$0")" &> /dev/null && pwd)
PROJECT_DIR=$(readlink -f $SCRIPT_DIR/..)
COMPOSE_FILE=$PROJECT_DIR/docker/docker-compose.yml
ENV_FILE=$PROJECT_DIR/docker/.env.dev
ENV_FILE=$PROJECT_DIR/docker/.env.${1:-dev} # $1 'proxy' or empty

docker compose --file $COMPOSE_FILE --env-file $ENV_FILE up -d
3 changes: 2 additions & 1 deletion docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ services:
GID: ${GID}
AUTHZ_URL: ${AUTHZ_URL}
AUTHZ_CLIENT_ID: ${AUTHZ_CLIENT_ID}
image: jam-build:latest
image: ${JB_IMAGE}
container_name: ${JB_CONTAINER_NAME}
environment:
DB_HOST: mariadb
DB_DATABASE: jam_build
Expand Down
30 changes: 17 additions & 13 deletions docs/localsetup.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
---
Author: Alex Grant <alex@localnerve.com> (https://www.localnerve.com)
Date: December 23, 2025
Date: December 30, 2025
Title: Getting Started
---

# How to Run Locally

> **Note:** Safari will not work as-is, interactively, locally without using named SSL proxy hosts in the procedure described [below](#ngnix-for-local-ssl-proxy-hosts).
> **Note:** Safari will not work as-is, interactively, locally without using named TLS proxy hosts in the procedure described [below](#setup-for-local-tls-proxy-hosts).

## Docker Setup

### Installation Steps
1. **Install Docker Desktop**: Download and install Docker Desktop from the official website.
2. **Run Docker Compose**:
- Execute `docker compose --file docker/docker-compose.yml --env-file docker/.env.dev up` to build and start the services.
- Or just execute `docker/compose-container.sh` to build and compose the demo.
- Optionally, create your own `.env` file.
- Local ports 3306, 5000, 6379, and 9010 must be free prior to service start.
- Execute `docker/compose-container.sh` to build and start the services.
- Optionally, create your own `docker/.env` file.
- Local ports 3306, 5000, 6379, and 9010 must be free prior to service start.

### Configuration Steps
1. **Remove Leftover Files**:
Expand All @@ -37,7 +36,7 @@ Title: Getting Started
### Prerequisites
- **NodeJS**: Version 22.15.0 or higher.
- **MariaDB**: Version 11.7.2 or higher.
- **Authorizer.dev**.
- **Localnerve/Authorizer** Version 1.5.3 or higher. [Standalone download](https://hub.docker.com/r/localnerve/authorizer).

### Services Setup

Expand All @@ -59,13 +58,18 @@ Title: Getting Started
- Generate `ADMIN_SECRET` and `CLIENT_ID` using local CLI tools like `uuidgen` and `openssl`.
- Choose any port, but the default settings in `package.json` scripts are easiest to use.

##### Ngnix for Local SSL Proxy Hosts
- To set up a named proxy for local SSL using [DuckDNS](https://notthebe.ee/blog/easy-ssl-in-homelab-dns01/) and the Docker Nginx Proxy Manager:
> Presuming you setup localhost:9010 to point to `yourproxyhost.duckdns.org` and localhost:5000 to point to `app.yourproxyhost.duckdns.org`
##### Setup for Local TLS Proxy Hosts
For testing with TLS locally, I recommend using [Duckdns](https://duckdns.org) to setup domain names that refer to addresses (192.168) on your local lab network. These work because duckdns supports [DNS-01 challenge protocol](https://notthebe.ee/blog/easy-ssl-in-homelab-dns01/#how-does-it-work), so Let's Encrypt can issue certificates for your local hosts. From there, you can use a reverse proxy service locally to manage Let's Encrypt keys and map subdomains to services on local ports.

- Run builds with `AUTHZ_URL=https://yourproxyhost.duckdns.org npm run build`.
- Access the jam-build app in the browser as `https://app.yourproxyhost.duckdns.org`.
- This setup is necessary to test Safari on localhost and for secure development with SSL.
After some experimentation, I've found that [caddy](https://caddyserver.com/docs/) works best in the role of local reverse proxy service. It is performant, stable, and easy to configure and manage. Here's my [configuration repo](https://github.com/localnerve/caddy-local) for caddy if you want a working reference.

Notes:
- Configure the reverse proxy service to use authorizer service on localhost:9010 as `yourname.duckdns.org` and the app service on localhost:5000 as `app.yourname.duckdns.org`
- Run builds with `AUTHZ_URL=https://yourname.duckdns.org npm run build`.
* There are many test scripts in `package.json` that model this for various tasks with `proxy` in the name.
- Access the jam-build app in the browser as `https://app.yourname.duckdns.org`.
- This setup is necessary to manually test with Safari on native localhost with TLS.
* `npm run test:webkit` tests the services with safari in a local container without TLS (special config).

#### Data Service Setup
- The data service runs in NodeJS on port 5000 by default. The main entry point is `src/application/server/index.js`.
Expand Down
36 changes: 18 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jam-build",
"version": "2.8.4",
"version": "2.8.5",
"description": "An adventurous, scalable, fullstack web application reference project",
"main": "index.js",
"type": "module",
Expand Down Expand Up @@ -109,7 +109,7 @@
"@jsquash/oxipng": "^2.3.0",
"@jsquash/png": "^3.1.1",
"@jsquash/webp": "^1.5.0",
"@localnerve/csp-hashes": "^5.1.6",
"@localnerve/csp-hashes": "^5.1.7",
"@localnerve/editable-object": "^0.3.15",
"@localnerve/fast-is-equal": "^2.0.3",
"@localnerve/gulp-responsive": "^7.6.2",
Expand All @@ -121,7 +121,7 @@
"@rollup/plugin-node-resolve": "^16.0.3",
"@rollup/plugin-replace": "^6.0.3",
"@rollup/plugin-terser": "^0.4.4",
"@testcontainers/mariadb": "^11.10.0",
"@testcontainers/mariadb": "^11.11.0",
"autoprefixer": "^10.4.23",
"c8": "^10.1.3",
"cross-env": "^10.1.0",
Expand Down Expand Up @@ -162,7 +162,7 @@
"stylelint-no-unsupported-browser-features": "^8.0.5",
"svgo": "^4.0.0",
"tar": "^7.5.2",
"testcontainers": "^11.10.0",
"testcontainers": "^11.11.0",
"v8-to-istanbul": "^9.3.0",
"wasm-feature-detect": "^1.8.0",
"workbox-build": "^7.4.0",
Expand Down