Self-host QR Track
in 5 minutes.
QR Track is a single-directory PHP application. There’s no Docker stack to wrangle, no Node build step, no proprietary database. If you can run a WordPress site, you can run QR Track.
What you need
- ✅ Linux server — any distro. Debian, Ubuntu, Rocky, CentOS, Alma, Arch — doesn’t matter.
- ✅ PHP 8.0+ with
pdo,mbstring,gd, andcurlextensions. - ✅ Apache with
mod_rewrite— or nginx with try_files. - ✅ MariaDB / MySQL or SQLite — SQLite is the simplest if you have <100k scans/month.
- ✅ A subdomain — e.g.
qr.yoursite.com.
Total disk: under 10 MB plus your codes’ database. Memory: 64–128 MB per PHP-FPM worker is plenty.
Install in 5 steps
-
1. Clone the repository
cd /var/www git clone https://github.com/tuxxin/qr-track.git cd qr-trackNo Composer install needed — QR Track has no PHP dependencies.
-
2. Configure the environment
cp TiCore/.env.example TiCore/.env nano TiCore/.envFor SQLite (simplest), leave
DB_HOST=sqlite— the database file lives atTiCore/db/qr-track.sqlite. For MariaDB, setDB_HOST,DB_NAME,DB_USER,DB_PASS. -
3. Fix permissions
chown -R www-data:www-data /var/www/qr-track chmod -R 750 /var/www/qr-track chmod -R 770 /var/www/qr-track/TiCore/{db,logs,tmp}The
db/,logs/, andtmp/directories must be writable by the web user. -
4. Point a subdomain at
www/Apache vhost example:
<VirtualHost *:443> ServerName qr.yoursite.com DocumentRoot /var/www/qr-track/www SSLEngine on SSLCertificateFile /etc/letsencrypt/live/qr.yoursite.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/qr.yoursite.com/privkey.pem <Directory /var/www/qr-track/www> AllowOverride All Require all granted </Directory> </VirtualHost>On nginx,
try_files $uri $uri/ /index.php?$query_string;is the equivalent. -
5. Visit the dashboard
Browse to
https://qr.yoursite.com/. The first request bootstraps the database, seeds an admin account, and shows you the auto-generated credentials. Change the password immediately, then start creating QR codes.
Running behind Cloudflare?
Set USE_CLOUDFLARE_TUNNEL=true in TiCore/.env and QR Track will read the
real visitor IP from CF-Connecting-IP instead of the Cloudflare proxy IP. Apple
iCloud Private Relay and other anonymizing proxies are also handled.
Common gotchas
- 500 error on first visit — usually a permissions issue. Double-check that
TiCore/dbandTiCore/logsare writable by the web user. - QR codes scan but redirect goes to a 404 —
mod_rewriteisn’t enabled.a2enmod rewriteon Apache, or check your nginxtry_files. - Geo-location shows “unknown” —
ip-api.comrate-limits free callers to 45/min. The cache layer prevents most repeat hits, but if you’re bulk-importing scans, expect some lookups to defer.