Open Source Point of Sale 3.4.1
Overview
Open Source Point of Sale (OSPOS) is a browser-based point of sale and inventory management system for shops, cafes and small chains. It runs the till with barcode scanning, taxes, discounts, cash rounding, several payment types, receipts and invoices. It also keeps items, item kits, stock locations, receivings, customers, suppliers, gift cards, expenses and cash-ups in one place, with sales, inventory, tax and payment reports.
This guide covers the Open Source Point of Sale 3.4.1 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud e-commerce platforms listing on AWS Marketplace. You select it as the software version when you subscribe and launch.
What you get:
- Ready to sign in. The database schema is loaded and fully migrated to 3.4.1 at build time, so the first page you open is the login page, not an installer or a migration prompt.
- No default login. Upstream OSPOS seeds the well-known
admin/pointofsalelogin. On this image, that password is replaced before the application ever runs. The image ships with the admin account disabled, and first boot gives it a password unique to your instance. - Secrets unique to your instance. The OSPOS
adminpassword, the MariaDB password OSPOS uses and the application encryption key are generated on first boot. They are written to/root/opensourcepos-credentials.txt(root only). The image ships with the database account locked and no password or key in the configuration. nginx and PHP-FPM refuse to start until first boot has finished. - HTTPS from the first boot. nginx serves OSPOS on port 443 with a certificate generated on your instance, and port 80 redirects to HTTPS. Requests for a host name the instance does not serve are dropped, and the session cookie is
SecureandHttpOnly. - Only the application on the web. nginx serves the
public/directory only and runs exactly one PHP file, the application's front controller. Any other.phpfile, including anything uploaded, answers 404, and uploads are served as images only. OSPOS 3.4.1 ships with its own cross-site request forgery filter switched off, so nginx refuses form posts that come from another web site. - Hardened defaults. MariaDB listens on
127.0.0.1only. nginx, PHP-FPM, MariaDB and the first-boot service are blocked from the instance metadata service, and the AMI requires IMDSv2. PHP is handed the configured host name and the real client address from the connection, never values a client sends. - Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: Open Source Point of Sale 3.4.1 (the official release opensourcepos.3.4.1.5f395d.zip, checksum verified), nginx, PHP 8.3 FPM with OPcache, MariaDB, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu. Architecture: x86_64. Recommended instance type: m5.large.
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH) from your admin network. It should also allow TCP 443 (OSPOS) and TCP 80 (redirects to HTTPS) from the networks your tills and staff work from. Never open 3306.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Select Open Source Point of Sale 3.4.1 on Ubuntu 24.04 as the software version, choose your Region, then choose Launch through EC2.
Choose m5.large, your key pair and a security group as described in the prerequisites. The database lives on the root volume, so for production give the root volume room to grow (20 GiB or more).
To launch with the AWS CLI instead, replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=20,VolumeType=gp3}' \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=ospos}]'First boot completes in well under a minute after the instance is running.
Connect to your instance
Connect over SSH as the ubuntu user. The table below lists the SSH user for this version.
Version SSH user
Open Source Point of Sale 3.4.1 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services
First boot sets the passwords, the encryption key and the certificate, and then nginx and PHP-FPM start. Run these commands to confirm:
systemctl is-active nginx php8.3-fpm mariadb opensourcepos-firstboot
sudo test -f /var/lib/sac/data/opensourcepos-firstboot.done && echo FIRSTBOOT_DONEAll four units report active, and the first-boot marker is present:
active active active active FIRSTBOOT_DONEOnly SSH and nginx listen on network ports. MariaDB listens on the loopback address, and PHP-FPM uses a local socket:
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0.5' | sort0.0.0.0:22 users:(("sshd",...)) 0.0.0.0:443 users:(("nginx",...)) 0.0.0.0:80 users:(("nginx",...)) 127.0.0.1:3306 users:(("mariadbd",...)) [::]:22 users:(("sshd",...)) [::]:443 users:(("nginx",...)) [::]:80 users:(("nginx",...))Get your URL and passwords
Read the credentials file with sudo. Only root can read it:
sudo cat /root/opensourcepos-credentials.txtThe file looks like this:
# Open Source Point of Sale 3.4.1 - generated on first boot by opensourcepos-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret. OSPOS_URL=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/ OSPOS_ADMIN_USER=admin OSPOS_ADMIN_PASSWORD=<OSPOS_ADMIN_PASSWORD> MARIADB_DATABASE=ospos MARIADB_USER=ospos MARIADB_PASSWORD=<MARIADB_PASSWORD>
# The application encryption key (also in /var/www/opensourcepos/.env); OSPOS encrypts stored integration secrets with it. OSPOS_ENCRYPTION_KEY=<OSPOS_ENCRYPTION_KEY>
# The certificate is self signed (minted on this instance); port 80 redirects to https.
# Change the name OSPOS is served as:
sudo opensourcepos-set-hostname <your-dns-name>
# MariaDB listens on 127.0.0.1 only; on-box maintenance:
sudo mariadb
# User guide: https://secureanycloud.com/stacks/open-source-point-of-sale-3-4-1/The URL uses the instance's public DNS name from the EC2 instance metadata. The certificate also names the public and private IP addresses, so https://<public-ip>/ works too. After you sign in, OSPOS sends you to the configured name.
If you stop and start the instance without an Elastic IP, the boot service picks up the new address and issues a new certificate for it. To serve OSPOS under your own DNS name, see Step 8.
You need the MariaDB password only for your own tools. OSPOS already has it in /var/www/opensourcepos/.env. Keep the encryption key with your backups, because OSPOS uses it for the integration secrets you save (for example the SMTP password and the Mailchimp API key).
Sign in
Open the OSPOS_URL in your browser. The certificate is self-signed, so your browser asks you to confirm it the first time. You can install your own certificate instead (see Step 8). Sign in as admin with the password from Step 4.
The home page has a tile for each module. The footer shows the version and the link to the project, which the OSPOS licence requires on every page.
You can also check the sign-in from the instance. This script signs in through the real login form over HTTPS with the instance's password. It then shows that a blank password, the upstream default pointofsale and common weak passwords are refused with OSPOS's "Invalid username and/or password" error:
sudo opensourcepos-cred-roundtrip.shOK per-instance admin signs in over HTTPS; blank, admin/pointofsale and weak guesses refusedSet up your store
The image ships the upstream starting data: one employee, admin, whose person record is the sample name John Doe, and the store details Open Source Point of Sale, 123 Nowhere street. There are no items, customers, suppliers or sales. Work through these first:
- Open Office, then Configuration, then the Information tab. Enter your company name, address, phone, e-mail and logo.
- Open the General, Tax and Localization tabs. Set the default tax rates, currency symbol, number and date formats and the time zone. Then use Receipt, Invoice and Barcode to set up printed output.
- Open Office, then Employees. Edit the
adminemployee's name and e-mail, and add an employee for each person with only the modules they need. - Open Items. Add items one at a time with New Item, or load them from a spreadsheet with CSV Import. Item Kits bundle several items under one price.
- Use Sales as the register. Scan or search for items, choose a customer if needed, take payment and print the receipt.
Reports covers sales, items, customers, employees, payments, taxes, discounts and inventory, as graphs, summaries or detail.
E-mail (optional)
OSPOS can e-mail receipts and invoices. Set your SMTP relay under Office, Configuration, Setup & Conf, Email.
Amazon SES works as the relay (port 587 with STARTTLS). If you restrict egress, allow outbound 587 in your security group or network ACLs.
Your own DNS name and certificate
Point a DNS record at the instance (an Elastic IP keeps the address stable), then set the name OSPOS is served as. The command below mints a new self-signed certificate for the name. It updates nginx, the host name OSPOS accepts (app.allowedHostnames in /var/www/opensourcepos/.env) and the URL in /root/opensourcepos-credentials.txt. The name persists across reboots.
sudo opensourcepos-set-hostname <your-domain>To use a certificate from a public or internal certificate authority instead (for example one issued by Let's Encrypt for <your-domain>), copy it over the generated pair and reload nginx. Running opensourcepos-set-hostname again replaces it with a self-signed certificate.
sudo install -m 0644 <your-domain>.crt /etc/ssl/opensourcepos/opensourcepos.crt
sudo install -m 0600 <your-domain>.key /etc/ssl/opensourcepos/opensourcepos.key
sudo nginx -t && sudo systemctl reload nginxSecurity checks
nginx serves the application and its static files only. The configuration file, the application and vendor code, and any PHP file other than the front controller, answer 404. The licence stays readable, and plain HTTP redirects to HTTPS:
H=$(sudo grep '^OSPOS_URL=' /root/opensourcepos-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#') for p in /login /.env /app/Config/App.php /vendor/autoload.php /uploads/item_pics/test.php /license/LICENSE; do curl -sk -o /dev/null -w "%{http_code} $p\n" --resolve "$H:443:127.0.0.1" "https://$H$p" done curl -s -o /dev/null -w 'http:// -> %{http_code} %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/" [ "$(curl -sk -o /dev/null -w '%{http_code}' --resolve "$H:443:127.0.0.1" "https://$H/.env")" = "404" ]200 /login 404 /.env 404 /app/Config/App.php 404 /vendor/autoload.php 404 /uploads/item_pics/test.php 200 /license/LICENSE http:// -> 301 https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/A form post from another web site is refused. A request for a host name the instance does not serve gets no answer, and curl reports 000:
H=$(sudo grep '^OSPOS_URL=' /root/opensourcepos-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
curl -sk -o /dev/null -w 'cross-site post -> %{http_code}\n' --resolve "$H:443:127.0.0.1" -H 'Origin: https://evil.example' --data 'username=admin&password=x' "https://$H/login"
curl -sk -o /dev/null -w 'unknown host -> %{http_code}\n' --resolve "evil.example:443:127.0.0.1" https://evil.example/ || truecross-site post -> 403 unknown host -> 000OSPOS reports version 3.4.1, and every database migration has run:
grep "application_version =" /var/www/opensourcepos/app/Config/App.php
sudo mariadb -N -B ospos -e "SELECT COUNT(*) FROM ospos_migrations;"public string $application_version = '3.4.1'; 40The certificate was generated on this instance and names its own addresses:
H=$(sudo grep '^OSPOS_URL=' /root/opensourcepos-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltNamesubject=CN = ec2-<public-ip-dashed>.compute-1.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-<public-ip-dashed>.compute-1.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhostNone of the services can reach the instance metadata service:
systemctl show nginx php8.3-fpm mariadb opensourcepos-firstboot -p Id -p IPAddressDenyIPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 Id=nginx.service IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 Id=php8.3-fpm.service IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 Id=mariadb.service IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 Id=opensourcepos-firstboot.servicenginx hands PHP the configured host name and the client address from the connection, never values a client sends. OSPOS accepts only the configured host name:
grep -E 'fastcgi_param (HTTP_HOST|HTTPS|HTTP_X_FORWARDED_FOR|HTTP_X_REAL_IP|HTTP_CLIENT_IP) ' /etc/nginx/sites-available/sac-opensourcepos
sudo grep -E '^(CI_ENVIRONMENT|app\.allowedHostnames|app\.forceGlobalSecureRequests|cookie\.secure) ' /var/www/opensourcepos/.envfastcgi_param HTTP_HOST $ospos_host; fastcgi_param HTTPS on; fastcgi_param HTTP_X_FORWARDED_FOR $remote_addr; fastcgi_param HTTP_X_REAL_IP $remote_addr; fastcgi_param HTTP_CLIENT_IP $remote_addr; CI_ENVIRONMENT = production app.forceGlobalSecureRequests = true app.allowedHostnames = 'ec2-<public-ip-dashed>.compute-1.amazonaws.com' cookie.secure = trueChange passwords
- OSPOS admin password: sign in as
adminand open Office, then Employees. Edit the admin employee, open the Login tab, enter a new password twice and submit. Then update or deleteOSPOS_ADMIN_PASSWORDin/root/opensourcepos-credentials.txtso the file does not keep the old password. - Give each person their own employee login with only the modules they need, rather than sharing
admin. - MariaDB password: change it only together with
database.default.passwordin/var/www/opensourcepos/.env. - Encryption key: do not change
encryption.keyin.envafter you have saved integration secrets. OSPOS could no longer read them.
Backup and maintenance
The store database lives in MariaDB (/var/lib/mysql). Item pictures and the company logo live under /var/www/opensourcepos/public/uploads. The configuration, including the encryption key, is /var/www/opensourcepos/.env.
The simplest backup is an EBS snapshot of the root volume. For a consistent file-level copy while OSPOS is running, use:
sudo mariadb-dump --single-transaction --routines --triggers ospos | gzip > <backup-dir>/ospos-$(date +%F).sql.gz
sudo tar -czf <backup-dir>/ospos-files-$(date +%F).tar.gz -C /var/www/opensourcepos .env public/uploadsOperating system security updates install automatically. Run sudo apt-get update && sudo apt-get upgrade to apply everything else. nginx, PHP-FPM and MariaDB restart cleanly, and OSPOS keeps all of its data.
Key paths on the instance:
Component Path
OSPOS /var/www/opensourcepos (web root public/)
Configuration /var/www/opensourcepos/.env (mode 0640)
Item pictures and logo /var/www/opensourcepos/public/uploads
Sessions, logs and cache /var/www/opensourcepos/writable
Database MariaDB database ospos (/var/lib/mysql)
nginx site /etc/nginx/sites-available/sac-opensourcepos
Certificate and key /etc/ssl/opensourcepos/
Boot service /usr/local/sbin/opensourcepos-firstboot.sh
Host name helper /usr/local/sbin/opensourcepos-set-hostname
Credentials /root/opensourcepos-credentials.txt (mode 0600)
Security recommendations
- Allow port 22 from your admin network only, and ports 80 and 443 only from the networks your tills and staff work from. Never open 3306.
- Use your own DNS name and a certificate your browsers trust (Step 8).
- Give each person their own employee login, and change the admin password if it may have been shared (Step 10).
- Keep the operating system patched, and snapshot the root volume regularly.
Support and licensing
Open Source Point of Sale is open source under the MIT licence. The project adds one condition: the footer signature (version, commit and the opensourcepos.org link) must stay visible and unmodified on every page. This image ships it unchanged.
There is no per-user or per-till licence fee. The AMI price covers SecureAnyCloud's hardening, first-boot setup and support.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24 hour response SLA
Deploy on AWS
Launch Open Source Point of Sale 3.4.1 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com