Introduce CodeIgniter Tasks-based job scheduling to support long-running background work (e.g. large CSV imports) without blocking requests. - composer.json/composer.lock: add codeigniter4/tasks (and its dependencies codeigniter4/queue, codeigniter4/settings) to power the task scheduler and settings-backed configuration. - app/Models/JobThrottle.php: new model for job_throttles table, providing exists/save/getAll/delete helpers to rate-limit or throttle job execution per throttle_id. - INSTALL.md: document the three trigger modes (Web default via request-hook processing, Auto via cron/Task Scheduler, Manual via admin UI button), including step-by-step Linux/Mac cron and Windows Task Scheduler setup, and Docker considerations (worker container, supervisor, or cron sidecar) since cron does not run inside a single-process container by default. Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
9.8 KiB
Server Requirements
- PHP version
8.2to8.4are supported, PHP version≤ 8.1is NOT supported. Please note that PHP needs to have the extensionsphp-json,php-gd,php-bcmath,php-intl,php-openssl,php-mbstring,php-curlandphp-xmlinstalled and enabled. An unstable master build can be downloaded in the releases section. - MySQL
5.7is supported, also MariaDB replacement10.xis supported and might offer better performance. - Apache
2.4is supported. Nginx should work fine too, see wiki page here. - Raspberry PI based installations proved to work, see wiki page here.
- For Windows based installations please read the wiki. There are closed issues about this subject, as this topic has been covered a lot.
Security Configuration
Allowed Hostnames (REQUIRED for Production)
⚠️ CRITICAL: OpenSourcePOS validates the Host header to prevent Host Header Injection attacks. You MUST configure app.allowedHostnames for production deployments. If not configured, the application will fail to start.
Add to your .env file:
# Comma-separated list of allowed hostnames (no protocols or ports)
app.allowedHostnames = 'yourdomain.com,www.yourdomain.com'
For local development:
app.allowedHostnames = 'localhost'
If you see this error at startup:
RuntimeException: Security: allowedHostnames is not configured.
Solution: Add app.allowedHostnames to your .env file with your domain(s).
Why this matters:
- Prevents Host Header Injection attacks
- Ensures URLs are generated with the correct domain
- Fixes issue #4480: .env configuration now works via comma-separated values
HTTPS Behind Proxy
If your installation is behind a proxy with SSL offloading, set:
FORCE_HTTPS = true
Local install
First of all, if you're seeing the message system folder missing after launching your browser, that most likely means you have cloned the repository and have not built the project. To build the project from a source commit point instead of from an official release check out Building OSPOS. Otherwise, continue with the following steps.
- Download the a pre-release for a specific branch or the latest stable from GitHub here. A repository clone will not work unless know how to build the project.
- Create/locate a new MySQL database to install Open Source Point of Sale into.
- Unzip and upload Open Source Point of Sale files to the web-server.
- If
.envdoes not exist, copy.env.exampleto.env. - Open
.envand modify credentials to connect to your database if needed. - The database schema will be automatically created when you first access the application. Migrations run automatically on fresh installs.
- Go to your install
publicdir via the browser. - Log in using
- Username: admin
- Password: pointofsale
- If everything works, then set the
CI_ENVIRONMENTvariable toproductionin the .env file - Enjoy!
- Oops, an issue? Please make sure you read the FAQ, wiki page, and you checked open and closed issues on GitHub. PHP
display_errorsis disabled by default. Create anapp/Config/.envfile from the.env.exampleto enable it in a development environment.
Local install using Docker
OSPOS can be deployed using Docker on Linux, Mac, and Windows. Locally or on a host (server). This setup dramatically reduces the number of possible issues as all setup is now done in a Dockerfile. Docker runs natively on Mac and Linux. Windows requires WSL2 to be installed. Please refer to the Docker documentation for instructions on how to set it up on your platform.
Be aware that this setup is not suited for production usage! Change the default passwords in the compose file before exposing the containers publicly.
Start the containers using the following command
docker-compose up
Background Job Scheduling
OSPOS includes a background job queue (Office → Job Queue) for long-running tasks such as large CSV imports. It supports three trigger modes, configured on the Job Queue → Settings tab:
- Web (default) — no setup required. Jobs are processed via a request hook after page loads, using
fastcgi_finish_request()where available. Works out of the box on shared hosting, VPS, and Docker. - Auto — a cron entry (Linux/Mac) or Task Scheduler task (Windows) triggers processing on a fixed interval. Recommended for VPS/dedicated servers with cron access.
- Manual — an admin clicks a "Process All Jobs" button on the Job Queue → Utilities tab. Always available regardless of mode, useful for debugging.
auto mode: Linux/Mac cron
Add the following entry to your crontab (crontab -e), adjusting the path to your OSPOS install:
* * * * * cd /path/to/ospos && php spark tasks:run >> /dev/null 2>&1
auto mode: Windows Task Scheduler
- Open Task Scheduler and create a new task.
- Trigger:
Daily, checkRepeat task every: 5 minutes(the fastest interval the GUI allows),for a duration of: Indefinitely, no expiration.- Don't use a
One timetrigger with a fixed repeat duration (e.g.1 day) — it stops repeating once that duration elapses instead of running forever.
- Don't use a
- Action: start a program.
- Program/script:
php.exe(full path, e.g.C:\php\php.exe) - Arguments:
spark tasks:run - Start in: must be the OSPOS project root — the directory containing the
sparkfile (e.g.C:\laragon\www\opensourcepos, orC:\wamp64\www\opensourcepos\public\..). This is NOT your PHP installation directory. IfStart inis wrong or blank,sparkfails immediately withCould not open input file: sparkand the window closes before you can read it. - Alternatively, avoid relying on
Start inaltogether by giving the full path tosparkdirectly in Arguments:Arguments: C:\laragon\www\opensourcepos\spark tasks:run.
- Program/script:
- On the General tab, select "Run whether user is logged on or not". Without this, the task runs in your interactive session and briefly flashes a console window every time it fires.
- You'll be prompted for your account password to save the task. If it's rejected (common with Microsoft accounts using Windows Hello — fingerprint/PIN/face login won't work here), check "Do not store password" instead. This limits the task to local computer resources only, which is sufficient for
spark tasks:run.
- You'll be prompted for your account password to save the task. If it's rejected (common with Microsoft accounts using Windows Hello — fingerprint/PIN/face login won't work here), check "Do not store password" instead. This limits the task to local computer resources only, which is sufficient for
- Save the task. It will invoke the scheduler every 5 minutes — less frequent than the once-per-minute cron example above, so jobs are processed in 5-minute batches instead.
- Before trusting the scheduled task, verify it manually: open
cmd.exe,cdto the sameStart indirectory, and run the sameProgram/script+Arguments. You should seeRunning Tasks...thenCompleted Running Tasks, and a new heartbeat line inwritable/logs/.
manual mode
No setup is required. Set Mode to Manual on the Job Queue → Settings tab, then use the "Process All Jobs" button on the Utilities tab whenever you need jobs processed.
Docker considerations
Docker containers are single-process by default, so cron does not run inside the OSPOS container out of the box — this is why Web mode is the default and works with zero extra Docker configuration.
If you want auto mode under Docker, pick one of the following:
Option 1: separate worker container (recommended)
Add a second service to your docker-compose.yml pointing at the same database:
worker:
image: opensourcepos
command: php spark tasks:run
depends_on:
- db
restart: unless-stopped
Option 2: supervisor inside the container
Add supervisor to the image and configure it to run both the web server and the scheduler. Works, but goes against the one-process-per-container convention — acceptable for simple single-container setups.
Option 3: cron sidecar container
Run a minimal sidecar container that fires php spark tasks:run every minute via cron, sharing the same network and database as the main container.
Nginx install using Docker
Since OSPOS version 3.3.0 the Docker installation offers a reverse proxy based on Nginx with a Let's Encrypt TLS certificate termination (aka HTTPS connection).
Let's Encrypt is a free certificate issuer, requiring a special installation that this Docker installation would take care of for you.
Any Let's Encrypt TLS certificate renewal will be managed automatically, therefore there is no need to worry about those details.
Before starting your installation, you should edit the docker/.env file and configure it to contain the correct MySQL/MariaDB and phpMyAdmin passwords (don't use the defaults!).
You will also need to register to Let's Encrypt. Configure your host domain name and Let's Encrypt email address in the docker/.env file.
The variable STAGING needs to be set to 0 when you are confident your configuration is correct so that Let's Encrypt will issue a final proper TLS certificate.
Follow local install steps, but instead use
docker/install-nginx.sh
Do not use below command on live deployments unless you want to tear everything down. All your disk content will be wiped!
docker/uninstall.sh
Cloud install
If you choose DigitalOcean: Through this link, you will get a free $100, 60-day credit. Check the wiki for further instructions on how to install the necessary components.