POSMaster Help v1.2.0
Installation

Install with Docker

Docker runs POSMaster and its database in ready-made containers, so you do not install PHP, Apache or MySQL yourself. It is a good choice for a VPS, a test server, or a computer that already has Docker.

You need Docker with Docker Compose v2 (the docker compose command). On Windows and Mac, install Docker Desktop. On Linux, install Docker Engine and the Compose plugin.

Quick start

Open a terminal in the folder that contains docker-compose.yml, then run these two commands.

  1. Build and start everything:
docker compose up -d --build

The first build takes a few minutes, because Docker downloads PHP, Apache and MariaDB and installs the PHP extensions.

  1. Install POSMaster. Pick one:
# Demo shop with sample products and sales
docker compose exec -u www-data app php artisan pos:install --demo

# Or a clean shop (asks for your Super Admin name, email and password)
docker compose exec -u www-data app php artisan pos:install
  1. Open http://localhost:8080 and sign in.

With --demo the Super Admin is superadmin@posmaster.test with the password password.

Warning: pos:install --demo wipes the database before loading the demo shop. Never run it on a shop with real data.

Note: If the second command says it cannot connect to the database, wait 20 seconds and try again. The database needs a moment to start on the first run. The app waits for it automatically.

Warning: Always run php artisan in the container with -u www-data, as shown. Without it, files are created as root, the web server can no longer write its cache, and pages show an error.

What Docker starts

docker-compose.yml defines three services:

Service What it does
app PHP 8.2 with Apache. Serves POSMaster on port 8080. On start it creates the app key, waits for the database, and creates the storage link.
scheduler Runs php artisan schedule:work. It handles the nightly demo reset when you turn it on.
db MariaDB 10.11 with the utf8mb4 character set and utf8mb4_unicode_ci collation.

The app is configured through environment variables set in the compose file, so you do not need a .env file inside the container. APP_ENV is production and APP_DEBUG is false. Logs go to the container output.

You do not need to create the app key. The first start creates a random key and keeps it in the storage volume, so it stays the same as long as that volume exists.

Change the settings (.env.docker)

The defaults work for a first try. For anything real, change at least the passwords. Create your own settings file:

cp .env.docker.example .env.docker

Edit .env.docker:

POS_PORT=8080
POS_APP_URL=http://localhost:8080
POS_DB_DATABASE=posmaster
POS_DB_USERNAME=posmaster
POS_DB_PASSWORD=change-me
POS_DB_ROOT_PASSWORD=change-me-too
POS_DEMO_LOCK=false
POS_DEMO_RESET_NIGHTLY=false

Then start with the file:

docker compose --env-file .env.docker up -d --build
Setting Meaning
POS_PORT The port on your computer. Use 80 to open the app without a port number.
POS_APP_URL The address people type. Set it to your real domain, for example https://shop.example.com.
POS_DB_DATABASE, POS_DB_USERNAME, POS_DB_PASSWORD The database name, user and password
POS_DB_ROOT_PASSWORD The password of the database root user
POS_DEMO_LOCK true forces demo mode on and hides the switch. See below.
POS_DEMO_RESET_NIGHTLY true resets the demo data every night at 00:00

Warning: The database password is saved in the database volume the first time it is created. If you change POS_DB_PASSWORD later, the existing database does not follow. Set the passwords before the first start. To change them afterwards you must either change them inside the database or remove the database volume, which deletes all data.

Tip: Use the same --env-file .env.docker option every time you run docker compose up, down or build. Otherwise Compose falls back to the defaults.

Public demo server

To run a public demo that visitors cannot damage:

  1. Put these in .env.docker:
POS_DEMO_LOCK=true
POS_DEMO_RESET_NIGHTLY=true
  1. Start the containers and install the demo:
docker compose --env-file .env.docker up -d --build
docker compose exec -u www-data app php artisan pos:install --demo

With POS_DEMO_LOCK=true, demo mode is always on. Nobody, not even the Super Admin, can switch it off or change protected settings. With POS_DEMO_RESET_NIGHTLY=true, the scheduler service wipes and reloads the demo data at 00:00 every night.

Data and volumes

Docker keeps your data in two named volumes. They survive restarts and rebuilds.

Volume Holds
db The MariaDB database files
storage Uploaded pictures, logs, the app key and the cache

Compose adds your folder name in front, so the real names look like pointofsales_db. List them with docker volume ls.

Warning: docker compose down -v deletes the volumes and all your data. Plain docker compose down is safe.

Look at the logs

# Follow the app log (press Ctrl+C to stop following)
docker compose logs -f app

# Database and scheduler
docker compose logs -f db
docker compose logs -f scheduler

Application errors are written to the app container's output, because the log channel is stderr.

Stop, start and restart

docker compose stop        # stop, keep everything
docker compose start       # start again
docker compose restart app # restart one service
docker compose down        # remove the containers, keep the data
docker compose ps          # see what is running

The containers are set to restart: unless-stopped, so they come back after a server reboot.

Back up the database

Create a SQL dump of the database on your computer:

docker compose exec db sh -c 'mariadb-dump -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"' > posmaster-backup.sql

This uses the user, password and database name that are already set inside the db container, so you do not have to type them. Put the date in the file name to keep several copies.

Also copy the uploaded pictures:

docker compose cp app:/var/www/html/storage/app/public ./backup-public

Restore a backup

  1. Make sure the containers are running.
  2. Load the dump:
docker compose exec -T db sh -c 'mariadb -u"$MARIADB_USER" -p"$MARIADB_PASSWORD" "$MARIADB_DATABASE"' < posmaster-backup.sql
  1. Copy the pictures back if you need them:
docker compose cp ./backup-public/. app:/var/www/html/storage/app/public

See Update, backup and restore for a full backup plan.

Update to a new version

  1. Make a backup first (see above).
  2. Replace the project files with the new version. Keep your .env.docker.
  3. Rebuild and restart:
docker compose --env-file .env.docker up -d --build
  1. Run the database migrations and clear the cache:
docker compose exec -u www-data app php artisan migrate --force
docker compose exec -u www-data app php artisan optimize:clear

Your data is safe, because it lives in the volumes and not in the image.

Useful commands

# Open a shell inside the app container
docker compose exec app sh

# Run any artisan command
docker compose exec -u www-data app php artisan about

# Reset the demo data now (only while demo mode is on)
docker compose exec -u www-data app php artisan pos:demo-reset

Troubleshooting Docker

  • "Database not reachable." in the app log. The app waited two minutes and the database never answered. Check docker compose logs db. A wrong password in .env.docker after the first start is the usual cause. See Troubleshooting.
  • Port 8080 is already in use. Set a different POS_PORT, for example 8081, and update POS_APP_URL to match.
  • Pictures do not show. Check that POS_APP_URL is exactly the address in your browser.
  • Slow on Windows. Use Docker Desktop with the WSL 2 backend.
POSMaster 1.2.0 · Help for shop owners, managers and cashiers