{"id":13040,"date":"2026-10-12T10:21:41","date_gmt":"2026-10-12T10:21:41","guid":{"rendered":"https:\/\/ui-lib.com\/blog\/?p=13040"},"modified":"2026-10-13T17:26:57","modified_gmt":"2026-10-13T17:26:57","slug":"deploy-laravel-pos-shared-hosting-cpanel","status":"publish","type":"post","link":"https:\/\/ui-lib.com\/blog\/deploy-laravel-pos-shared-hosting-cpanel\/","title":{"rendered":"Deploy a Laravel + Vue POS on Shared Hosting (cPanel, Step by Step)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Many Laravel apps ask for a VPS because they need Node, Redis, a queue worker or a build step on the server. Stocky POS asks for none of those. It is a Laravel app with a Vue front end, and the front-end assets ship already built. So an ordinary cPanel shared hosting account is enough to run it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this post we will install it from zero, step by step. We use Stocky POS as the example because it is the app we know best. The first five steps are the same for most Laravel apps on shared hosting: the right PHP version, an empty database, the files, a document root that points to <code>public\/<\/code>, and the permissions. The installer part is specific to Stocky.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What You Need<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s take a look at what the server must have before we start:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PHP 8.2 or newer.<\/strong> Versions 8.2, 8.3 and 8.4 are supported.<\/li>\n\n\n\n<li><strong>MySQL 8.0 or newer, or MariaDB 10.6 or newer.<\/strong><\/li>\n\n\n\n<li><strong>Apache with mod_rewrite, or Nginx.<\/strong><\/li>\n\n\n\n<li><strong>PHP extensions:<\/strong> bcmath, ctype, curl, fileinfo, gd, json, mbstring, openssl, pdo, pdo_mysql, tokenizer, xml and zip.<\/li>\n\n\n\n<li><strong>Memory:<\/strong> set the PHP <code>memory_limit<\/code> to 256 MB. Big imports and PDF exports are what use it.<\/li>\n\n\n\n<li><strong>HTTPS<\/strong>, if you plan to scan barcodes with a phone camera or install the PWA. Browsers only offer those two on secure pages. The rest works without it.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You do not need SSH, Composer, npm or phpMyAdmin. The installer checks every extension and names the missing ones, so you can also just start and see.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Set the PHP Version<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In cPanel open <strong>MultiPHP Manager<\/strong> (some hosts call it <strong>Select PHP Version<\/strong>), choose your domain and set PHP to 8.2 or newer. While you are there, look at the extensions list. Control panels differ from host to host, so if you cannot find the option, ask your host\u2019s support to switch the version for you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Create an Empty Database<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Open <strong>MySQL Database Wizard<\/strong>. Create a database, create a user, and give that user all privileges on the database. Write down the database name, the username and the password. We need them in the installer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One thing about cPanel: it puts your account name in front of the database name, for example <code>cpuser_stocky<\/code>, and it does the same for the database user. In the installer type the full name, prefix included.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not import anything. Stocky creates every table by itself, so the database must be empty.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Upload the Files<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Open <strong>File Manager<\/strong>, upload the application ZIP to the folder where the app will live and press <strong>Extract<\/strong>. Everything is included, so you do not run <code>composer install<\/code> or npm.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Point the Domain at public\/<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now the tricky part, and the one people skip. Stocky is a Laravel app, and only the <code>public<\/code> folder should be reachable from the web. Look at the folders we have after extracting:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nstocky\/\n  .env\n  storage\/\n  bootstrap\/cache\/\n  public\/      &amp;lt;- the domain must point here\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">If your domain points at the <code>stocky<\/code> folder itself, anyone can download <code>.env<\/code>. That file holds your database password and the application key.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"538\" src=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-document-root-diagram-1024x538.png\" alt=\"Diagram: with the domain pointed at the project folder, .env can be downloaded; pointed at the public folder, only public is the web root\" class=\"wp-image-13041\" style=\"aspect-ratio:1.9047619047619047;width:1200px;height:auto\" srcset=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-document-root-diagram-1024x538.png 1024w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-document-root-diagram-300x158.png 300w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-document-root-diagram-768x403.png 768w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-document-root-diagram.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Which folder the domain points at decides what visitors can reach.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In cPanel go to <strong>Domains<\/strong> and change the <strong>Document Root<\/strong> of your domain or subdomain to the <code>public<\/code> folder. For example <code>public_html\/public<\/code> if you extracted the app into <code>public_html<\/code>, or <code>stocky\/public<\/code> if it lives in its own folder.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Some hosts do not let you change the document root. For that case Stocky ships an <code>.htaccess<\/code> and a <code>server.php<\/code> in the project root, and they send every request into <code>public\/<\/code>. It works, but changing the document root is the cleaner fix.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Check the Permissions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The installer writes <code>.env<\/code>, and the app writes uploads, so these must be writable:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>.env<\/code><\/li>\n\n\n\n<li><code>storage\/<\/code><\/li>\n\n\n\n<li><code>bootstrap\/cache\/<\/code><\/li>\n\n\n\n<li><code>public\/images\/<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Folders at 755 and files at 644 is the normal setting. File Manager shows the permission of each item, and you can change it there.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Run the Installer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s run the installer. Open <code>https:\/\/your-domain\/setup<\/code> in the browser. Stocky installs itself in four screens.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Screen 1: Requirements<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The first screen lists the PHP version, every extension and the ZipArchive class, and each one gets a green tick when it passes. You cannot continue until all of them pass. If something is missing, switch it on in your hosting panel and press <strong>Re-check requirements<\/strong>. The installer has not written anything at this point.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"783\" src=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-server-requirements-1024x783.jpg\" alt=\"Stocky installer step 1: every server requirement is checked and shown green\" class=\"wp-image-13042\" style=\"aspect-ratio:1.3086150490730644;width:1200px;height:auto\" srcset=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-server-requirements-1024x783.jpg 1024w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-server-requirements-300x229.jpg 300w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-server-requirements-768x587.jpg 768w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-server-requirements.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The requirements screen. A failing item is named, so you know exactly what to switch on.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Screen 2: Application Settings<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here you set five things: the application name, the environment, debug mode, the application key and the application URL. For a live shop choose <strong>Production<\/strong> and turn debug <strong>Off<\/strong>. Press <strong>Generate<\/strong> to create the key. Type the URL the way visitors will, with <code>https:\/\/<\/code>. Everything on this screen is saved to <code>.env<\/code>, so you can change it there later.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"711\" src=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-application-settings-1024x711.jpg\" alt=\"Stocky installer step 2: application name, environment, debug mode, key and URL\" class=\"wp-image-13043\" style=\"aspect-ratio:1.440576230492197;width:1200px;height:auto\" srcset=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-application-settings-1024x711.jpg 1024w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-application-settings-300x208.jpg 300w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-application-settings-768x533.jpg 768w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-application-settings.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The defaults on a test install. On a live server set Environment to Production and Debug mode to Off.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Screen 3: Database<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Enter the host, port, database name, username and password from Step 2. Press <strong>Test connection<\/strong>. The Continue button only appears after the test passes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"711\" src=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-database-1024x711.jpg\" alt=\"\" class=\"wp-image-13044\" style=\"aspect-ratio:1.440576230492197;width:758px;height:auto\" srcset=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-database-1024x711.jpg 1024w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-database-300x208.jpg 300w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-database-768x533.jpg 768w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-installer-database.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Use the database user from Step 2 here, with its full prefixed name.<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Screen 4: Review and Install<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Read the summary and press <strong>Install Stocky<\/strong>. Now the installer does the real work. It writes <code>.env<\/code>, builds the tables and fills in the starting data: the Owner role with its permissions, a default warehouse, currencies, payment methods, settings and the translations. On a slow host this can take a few minutes, so leave the tab open until it finishes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The last page gives you the administrator account that the install created. Sign in with it and change the password and the email at once.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Make Sure \/setup Is Closed<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When the install finishes, the installer seals itself. After that, every <code>\/setup<\/code> address answers 403. The seal is just a file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nstorage\/app\/public\/installed\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">If <code>\/setup<\/code> is ever reachable on a live site, check that file first. If it is missing, create it with any content and check the folder\u2019s permissions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 8: Set the Basics Before You Sell<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Do these three things before the first sale, because they affect every document and report after it. Open <strong>Settings \u2192 System Settings<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Company details.<\/strong> Whatever you enter here appears on your receipts and invoices: the company name, logo, phone, email and address.<\/li>\n\n\n\n<li><strong>Timezone.<\/strong> It decides which date a late-evening sale lands on, and what time the scheduled jobs run.<\/li>\n\n\n\n<li><strong>Default currency.<\/strong> Reports and stock values are all calculated in this currency. If you switch on multi-currency later, the other currencies are converted into it.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Then open <strong>Settings \u2192 Mail Settings<\/strong>, fill in your SMTP details and press <strong>Send test<\/strong>. Invoices, password resets and order confirmations all go through it. Many hosts only send mail from an address on your own domain, using port 587 with TLS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 9: Add the Cron Entry (Optional)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Stocky works without cron. Sales, stock, receipts, the online store and the reports do not need anything in the background. One cron entry unlocks the scheduled work, such as the daily database backup and the WooCommerce sync.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In cPanel open <strong>Cron Jobs<\/strong> and add the line below to run every minute. If the default <code>php<\/code> on your host is older than 8.2, write the full path to a newer PHP instead.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n* * * * * cd \/path\/to\/stocky &amp;amp;&amp;amp; php artisan schedule:run &gt;&gt; \/dev\/null 2&gt;&amp;amp;1\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The queue driver is the database, so there is no Redis to install and no separate <code>queue:work<\/code> process. The scheduler drains the queue every minute. Without cron the queued jobs run while somebody uses the admin. That is enough for a small shop, but webhooks and syncs wait until the next visit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To check that it works, open <strong>Settings \u2192 System Health<\/strong> and look at the queue. A growing number of pending jobs means the scheduler is not running.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"783\" src=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-system-health-1024x783.jpg\" alt=\"\" class=\"wp-image-13045\" style=\"aspect-ratio:1.3086150490730644;width:1200px;height:auto\" srcset=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-system-health-1024x783.jpg 1024w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-system-health-300x229.jpg 300w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-system-health-768x587.jpg 768w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-system-health.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">System Health shows what the server is running and whether jobs are waiting in the queue.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">If the Install Fails<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most failures are one of these. The installer message tells you which:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>The message mentions<\/th><th>What to do<\/th><\/tr><\/thead><tbody><tr><td>Access denied for user<\/td><td>The database username or password is wrong. On cPanel check that you typed the prefixed username. Go back one screen and test again.<\/td><\/tr><tr><td>Unknown database<\/td><td>There is no database with that name. Create the empty database in cPanel first, then type its full name with the prefix.<\/td><\/tr><tr><td>Permission denied \/ failed to open stream<\/td><td>The installer cannot write to <code>.env<\/code>, <code>storage\/<\/code> or <code>bootstrap\/cache\/<\/code>. Fix the permissions as in Step 5, and make sure the web server\u2019s user owns them.<\/td><\/tr><tr><td>Maximum execution time<\/td><td>The install ran longer than PHP allows. Raise <code>max_execution_time<\/code> to 300 and try again, or run the command-line install below.<\/td><\/tr><tr><td>Base table already exists<\/td><td>An earlier attempt stopped halfway. Empty the database, or drop its tables, and start the installer again.<\/td><\/tr><tr><td>A blank page or a 500 after Install Stocky<\/td><td>Set <code>APP_DEBUG=true<\/code> in <code>.env<\/code> to show the error, or open <code>storage\/logs\/laravel.log<\/code>. Set debug back to false when you are done.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Problems After the Install<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>What you see<\/th><th>Why, and what to do<\/th><\/tr><\/thead><tbody><tr><td>A 500 error or a blank page<\/td><td>Open <code>storage\/logs\/laravel.log<\/code>, or <strong>Reports \u2192 Error Logs<\/strong> in the admin. The usual causes are a permission on <code>storage\/<\/code> or <code>bootstrap\/cache\/<\/code>, or a PHP extension that disappeared when the host changed something.<\/td><\/tr><tr><td>Pictures will not upload<\/td><td>Check that <code>public\/images\/<\/code> is writable. Then check <code>upload_max_filesize<\/code> and <code>post_max_size<\/code> in PHP, because both must be larger than the file.<\/td><\/tr><tr><td>Emails do not arrive<\/td><td>Mail Settings has a test button. Use it, then check the sender address and the port, as in Step 8.<\/td><\/tr><tr><td>The camera scanner or the install button is missing<\/td><td>Both need HTTPS, and your site is on plain HTTP. Put an SSL certificate on the domain.<\/td><\/tr><tr><td>Pending jobs keep growing in System Health<\/td><td>The cron entry is missing, or it uses the wrong PHP. See Step 9.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Prefer the Command Line?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If your host gives you SSH, you can skip the wizard. Write <code>.env<\/code> with <code>APP_URL<\/code>, <code>APP_KEY<\/code> and the <code>DB_*<\/code> values, then run:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nphp artisan key:generate\nphp artisan migrate --force\nphp artisan passport:install\nphp artisan db:seed --force\n\n# tell the installer it has nothing left to do\necho 1 &gt; storage\/app\/public\/installed\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">These commands create the Owner role and the default administrator account. You can run the seeders twice and nothing is duplicated.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Backups and Updates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Two things to set up on day one. First, backups. Open <strong>Settings \u2192 Backup<\/strong> and generate a dump. The dump is the database only, so include <code>public\/images\/<\/code> and <code>storage\/app\/<\/code> in your file backup too. Cloud backup to Amazon S3 or Google Drive is built in, and a copy that stays on the same server is not a safe copy.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"640\" src=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-backup-1024x640.jpg\" alt=\"Stocky Settings Backup page with a generate backup button and a list of dumps\" class=\"wp-image-13046\" style=\"aspect-ratio:1.6;width:1200px;height:auto\" srcset=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-backup-1024x640.jpg 1024w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-backup-300x188.jpg 300w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-backup-768x480.jpg 768w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-backup.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The backup page, with the list of dumps and the cloud backup option.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Second, updates. <strong>Settings \u2192 Update<\/strong> takes the new ZIP, runs checks on the archive, the PHP version, permissions, disk space and the database, then installs it. It backs up the files and the database first, and rolls back by itself if something fails. Make your own database backup before each update as well, even though the updater makes one. If your host does not let the updater write files, use the Manual Update tab.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"783\" src=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-update-1024x783.jpg\" alt=\"Stocky Settings Update page with the upload area for the new version ZIP and the pre-update checks\" class=\"wp-image-13047\" style=\"aspect-ratio:1.3086150490730644;width:1200px;height:auto\" srcset=\"https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-update-1024x783.jpg 1024w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-update-300x229.jpg 300w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-update-768x587.jpg 768w, https:\/\/ui-lib.com\/blog\/wp-content\/uploads\/2026\/10\/stocky-settings-update.jpg 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The update page: drop in the new ZIP, let the checks run, then install.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Is Shared Hosting Enough?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For one shop, or a few, yes. A $10 a month hosting plan does the job for most installs. If you outgrow it, your data is in your own database, so you can move it to a VPS later. The multi-tenant edition, Stocky SaaS, is different: on shared hosting an admin creates each tenant by hand, so a VPS is recommended there.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Not sure about your host? Compare it with the <a href=\"https:\/\/ui-lib.com\/shared-hosting\/\">shared hosting checklist<\/a> and the <a href=\"https:\/\/ui-lib.com\/requirements\/\">server requirements<\/a>, or send us its PHP version and extension list before you buy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Stocky POS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Stocky POS is the app we installed here. It is a self-hosted point-of-sale and inventory system that you buy once and run on your own hosting. Open the <a href=\"https:\/\/ui-lib.com\/downloads\/stocky-pos-erp\/\">Stocky POS page<\/a> for the live demo and the licence options, or read the full installation handbook in the <a href=\"https:\/\/getstocky.com\/docs\">Stocky documentation<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many Laravel apps ask for a VPS because they need Node, Redis, a queue worker or a build step on the server. Stocky POS asks&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/ui-lib.com\/blog\/deploy-laravel-pos-shared-hosting-cpanel\/\">Continue reading<span class=\"screen-reader-text\">Deploy a Laravel + Vue POS on Shared Hosting (cPanel, Step by Step)<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1251,1252,1],"tags":[],"class_list":["post-13040","post","type-post","status-publish","format-standard","hentry","category-business-software","category-pos-inventory","category-uncategorized","entry"],"_links":{"self":[{"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/posts\/13040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/comments?post=13040"}],"version-history":[{"count":1,"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/posts\/13040\/revisions"}],"predecessor-version":[{"id":13048,"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/posts\/13040\/revisions\/13048"}],"wp:attachment":[{"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/media?parent=13040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/categories?post=13040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ui-lib.com\/blog\/wp-json\/wp\/v2\/tags?post=13040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}