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):
| File | Contents | For |
|---|---|---|
pos-<version>-regular.zip | pos/ 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 notices | The regular item, no source code |
pos-<version>-source.zip | The same, plus source/ with spring-admin, infotech-admin-web and release | The 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:
.envfiles, 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:
| Container | Image | Does |
|---|---|---|
postgres | postgres:16-alpine | The database, in the postgres volume |
api | built from Dockerfile.api with app/pos-api.jar | The Spring Boot API |
web | built 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
- Set the version in
release/VERSION(or pass it to the script). - Run the checks:
mvn verifyinspring-admin(with aDB_TEST_URLtest database, so the integration tests run) andnpm run buildandnpm run lintininfotech-admin-web. See Run it on your computer. - Build:
release/build-release.sh. - 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. - Upload
pos-<version>-regular.zip(andpos-<version>-source.zipfor 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:
- Deploy the separate
license-serverproject, generate its key pair (--keygen), put the public key inspring-admin/src/main/resources/license/public-key.txtand commit it. - 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.
- Once the marketplace item ID is known, set
ENVATO_ITEM_IDSon 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.
Related pages
Last updated 17 Oct 2026