Installation
Upload, open a URL, answer five screens. You do not need SSH, Composer, npm or a build step at any point — the archive ships ready to run.
What your hosting needs
Any shared host sold in the last few years meets this. The installer checks all of it for you and tells you exactly where to change anything that is missing, so you do not need to read this table before you start — it is here for when you are choosing a host.
| Requirement | Needed | Notes |
|---|---|---|
| PHP | 8.2 or newer | Set per domain in cPanel → MultiPHP Manager, or Plesk → PHP Settings. |
| MySQL / MariaDB | MySQL 8.0+ or MariaDB 10.6+ | Older versions usually work but are not supported. |
| PHP extensions | openssl, pdo, pdo_mysql, mbstring, tokenizer, ctype, json, xml, dom, filter, hash, curl | All standard. Enable in cPanel → Select PHP Version → Extensions. |
| Write access | storage/, bootstrap/cache/, and the application folder itself once | 755 is enough on most hosts, 775 where PHP runs as a different user. |
| Cron | Recommended, not required | One entry, once a minute. Everything scheduled depends on it. |
| ffmpeg | Not required | Video testimonials work without it. See below. |
Video testimonials are compressed in your customer’s browser while they record, which is why Proofloop runs on shared hosting at all. Recording, upload, playback, moderation and publishing all work with no ffmpeg anywhere on the server. If your host happens to have it, Proofloop uses it for an extra normalisation pass and to pull poster frames server-side. If it never does, you lose nothing you can see.
Install it
-
Create a database. In cPanel, open MySQL Databases. Create a
database, create a user, then — and this is the step people miss — scroll down to
Add User To Database and grant that user ALL PRIVILEGES. Note that cPanel prefixes
both names with your account, so a database you called
proofloopis reallyyouracct_proofloop. -
Upload the files. Extract the archive and upload its contents to the folder
your domain serves from. If your host lets you point the domain at a subfolder, point it at
public/— it is tidier and keeps configuration files out of reach. If it does not, the included.htaccesshandles it. -
Open the installer. Visit
https://yourdomain.com/install. The first screen checks the server. Anything red says where to fix it; fix it, reload the page, and watch it turn green. -
Enter your database details. The host is almost always
localhostor127.0.0.1, not your domain name. Proofloop tests the connection before it writes anything, so a typo costs you a second. - Create the tables, then your account. Both are single button presses. The schema step is safe to repeat if the page times out.
- Add the cron job using the command the installer generates for your panel, then press Finish installation. The installer locks itself permanently at that point.
.env file
It contains APP_KEY, which encrypts every credential you will later store —
your email provider password, your Twilio token, your Google connection. If that key is
replaced, none of them can be decrypted again and every integration has to be reconnected by
hand. Copy the file somewhere safe before you do anything else.
The one cron job
Proofloop needs a scheduled task running once a minute. That single entry drives everything timed: campaign sends and follow-ups, the quiet-hours window, Google sync, monthly reports and media cleanup. There is never a second one to add, whatever features you switch on later.
Replace /home/acct/public_html with your own path — the installer prints it for you.
* * * * * cd /home/acct/public_html && php artisan schedule:run >> /dev/null 2>&1
cPanel
- Advanced → Cron Jobs.
- Common Settings: Once Per Minute (* * * * *).
- Paste the command above into the Command box and click Add New Cron Job.
Keep the >> /dev/null 2>&1 at the end. Without it cPanel emails you the
output of every run — 1,440 emails a day.
Plesk
- Websites & Domains → Scheduled Tasks → Add Task.
- Task type: Run a command. Paste the command.
- Run: Cron style, and enter
* * * * *.
DirectAdmin and CyberPanel
DirectAdmin: Advanced Features → Cronjobs, set every field to *, paste the
command. CyberPanel: Websites → Manage → Cron Jobs → Add Cron, choose
Every Minute.
Plain SSH
crontab -e
# add the line, save, then confirm with:
crontab -l
Run crontab -e as the same user your web server runs as, or the scheduler will
create files the web server cannot read.
Optional: drain the queue faster
The scheduler already sends everything. Add this second entry only if you send large campaigns and want them to go out in bursts. It exits when the queue is empty, so cron can supervise it like any other job.
* * * * * cd /home/acct/public_html && php artisan queue:work --stop-when-empty --tries=3 --max-time=55 >> /dev/null 2>&1
How to tell it is working
Open Settings → System status. It shows when the scheduler last checked in. If it
still says “never” ten minutes after you added the entry, the command is not running
— nearly always because php on the command line is a different PHP from the
one your site uses. Your host can give you the correct full path in one reply; it usually looks
like /usr/local/bin/ea-php83.
Troubleshooting
| What you see | What it means | What to do |
|---|---|---|
| A blank white page | PHP stopped before it could render anything, usually a missing extension or an unwritable folder. | Open storage/logs/laravel.log in File Manager — the last entry names the cause. If the file does not exist, storage/ is not writable: set it to 755 with “recurse into subdirectories” ticked. |
| “Access denied for user” | Wrong user, wrong password, or the user was never added to the database. | Check the account prefix on both names, then re-run Add User To Database in cPanel and grant ALL PRIVILEGES. |
| “Unknown database” | The name does not exist on that server. | Copy it from MySQL Databases exactly, including the youracct_ prefix. |
| 404 on every page except the home page | Apache is ignoring .htaccess, or the domain is not pointed at public/. |
Ask your host to enable AllowOverride All, or point the domain document root at the public folder. |
| “Specified key was too long” during the schema step | MySQL older than 5.7.7 indexing utf8mb4 columns. | Upgrade to MySQL 8.0 or MariaDB 10.6 in your panel. Both have been standard since 2021. |
| The schema step times out | max_execution_time is very low. |
Press the button again — it resumes where it stopped. If it keeps stopping, ask your host to raise the limit to 300 seconds. |
| “Proofloop is already installed” | The installer has locked itself, which is deliberate. | Only if you really need to re-run it: delete storage/app/proofloop/installed.json over SFTP. |
Updating
- Back up your database and your
.envfile. - Upload the new files over the old ones. Do not delete
.envorstorage/. - Open
/install. Because the lock file is still there, Proofloop knows this is an update and runs any new migrations for you the next time the scheduler ticks. If you would rather not wait, the update screen has a button.
Your uploaded media, testimonials and settings are untouched by an update.
Moving to another host
- Copy every file, including
.envand the wholestorage/folder. - Export and import the database.
- Edit
DB_*andAPP_URLin.envto match the new server. - Recreate the cron entry with the new path.
Keep the same APP_KEY. Change it and every stored credential becomes unreadable.