Skip to content
Infotech

Build a release package

The install packages that buyers download are built from the repository with one script, release/build-release.sh. This page explains what it produces, what it checks and the steps for publishing a new version. Buyers then install the package as described in Install.

What you need

  • JDK 21 and Maven 3.9, to build the API jar.
  • Node.js 20 or later, to build the web app.
  • zip.
  • The license public key in place (see below).

Build

From the repository root:

release/build-release.sh          # version from release/VERSION
release/build-release.sh 1.1.0    # or give the version

The output goes to release/dist/ (ignored by Git):

FileContentsFor
pos-<version>-regular.zippos/ with the Docker files, install.sh, update.sh, backup.sh, the prebuilt app/pos-api.jar and the built web/; plus documentation/ and third-party noticesThe regular item, no source code
pos-<version>-source.zipThe same, plus source/ with spring-admin, infotech-admin-web and releaseThe source code item

Buyers of the source package can build their own packages with source/release/build-release.sh. See Source code.

What goes in, and what never does

Only files Git tracks (or would track) are copied. These are always left out:

  • .env files, database dumps and backups
  • the deploy/ folder (your own server's scripts)
  • the old Laravel application

The script also refuses to build when it finds private keys, live Stripe keys or references to the author's private domain in the files it would package. Remove them and run it again.

The license public key

Each installation's license token is verified with a public key built into the API jar (spring-admin/src/main/resources/license/public-key.txt). It cannot be changed by configuration, so it must be the real key before you build. While the file still holds the placeholder, the script refuses to build.

For a test package only, allow the placeholder:

ALLOW_UNLICENSED_BUILD=1 release/build-release.sh 1.1.0-test

Never publish a package built this way.

What the buyer's package runs

The package's docker-compose.yml starts three containers:

ContainerImageDoes
postgrespostgres:16-alpineThe database, in the postgres volume
apibuilt from Dockerfile.api with app/pos-api.jarThe Spring Boot API
webbuilt from Dockerfile.web (Caddy)Serves the web app, proxies /api/* and WebSockets to the API on the same address, gets HTTPS certificates automatically

Because the web app and API share one address, the package needs no CORS_ORIGINS or VITE_API_URL. install.sh checks Docker and memory, asks for the domain and an email for HTTPS, writes .env with a random DB_PASSWORD, APP_ENCRYPTION_KEY and SETUP_TOKEN, runs docker compose up -d --build and prints the address of the setup wizard.

Publishing a new version

  1. Set the version in release/VERSION (or pass it to the script).
  2. Run the checks: mvn verify in spring-admin (with a DB_TEST_URL test database, so the integration tests run) and npm run build and npm run lint in infotech-admin-web. See Run it on your computer.
  3. Build: release/build-release.sh.
  4. Smoke test on a fresh VPS: extract the regular package, run install.sh, go through the setup wizard with a real purchase code, and try online payments in test mode.
  5. Upload pos-<version>-regular.zip (and pos-<version>-source.zip for the source item) to the marketplace.

Database changes ship as new Flyway migrations inside the jar. They run automatically when the buyer's API starts, so a release needs no separate migration step.

First release only

Before the very first public release:

  1. Deploy the separate license-server project, generate its key pair (--keygen), put the public key in spring-admin/src/main/resources/license/public-key.txt and commit it.
  2. Create a manual Extended license in the license console for your own installation and activate it there. Otherwise your own platform console locks after you deploy this version.
  3. Once the marketplace item ID is known, set ENVATO_ITEM_IDS on the license server.

How buyers update

A buyer copies the new package's app/ and web/ folders (and any new Docker files) over their installation and runs ./update.sh. It backs up the database with backup.sh, sets APP_VERSION in .env from the new VERSION file and runs docker compose up -d --build. Migrations run when the API starts. See Update.

Last updated 17 Oct 2026