{"id":45,"date":"2026-03-27T16:42:54","date_gmt":"2026-03-27T16:42:54","guid":{"rendered":"https:\/\/kr0311.com\/projects\/?p=45"},"modified":"2026-04-02T12:32:41","modified_gmt":"2026-04-02T12:32:41","slug":"custom-hosting-control-panel-build-phase-2","status":"publish","type":"post","link":"https:\/\/kr0311.com\/projects\/custom-hosting-control-panel-build-phase-2\/","title":{"rendered":"Phase 2: Laravel Installation &amp; Initial Configuration"},"content":{"rendered":"<p>With <a href=\"\/projects\/custom-hosting-control-panel-build-phase-1\/\">Phase 1 complete<\/a>, the groundwork is solid.<\/p>\n<p>The server is secured, the stack is installed, and everything is running cleanly.<\/p>\n<p>Which is great\u2026 because this is usually the point where things <em>stop<\/em> being predictable.<\/p>\n<p>Now we shift focus.<\/p>\n<p>This is where the custom hosting control panel build starts to take shape \u2014 moving from infrastructure into application.<\/p>\n<hr \/>\n<h2>\ud83e\udde9 What This Phase Does in the Custom Hosting Control Panel Build<\/h2>\n<p>Phase 2 is about bringing the platform to life.<\/p>\n<ul>\n<li>Installing Laravel as the application framework<\/li>\n<li>Establishing the project structure<\/li>\n<li>Configuring the environment<\/li>\n<li>Connecting to the database<\/li>\n<li>Serving the application through Nginx<\/li>\n<\/ul>\n<p>Nothing flashy yet \u2014 no dashboards, no buttons, nothing that looks impressive in a screenshot.<\/p>\n<p>But this is the phase where everything either clicks together\u2026 or quietly falls apart.<\/p>\n<p>This turns a prepared server into a working application foundation.<\/p>\n<hr \/>\n<h2>\ud83d\udce6 Installing Laravel<\/h2>\n<p>Laravel was installed using Composer \u2014 clean, standard, and no unnecessary complications.<\/p>\n<p>Laravel installation follows the official documentation available here: <a href=\"https:\/\/laravel.com\/docs\" target=\"_blank\" rel=\"noopener\">Laravel documentation<\/a>.<\/p>\n<p>The project was created inside:<\/p>\n<p><strong>\/srv\/kr0311-panel<\/strong><\/p>\n<p>This keeps the application isolated from system-level directories while still fitting into a structured server layout.<\/p>\n<p>Once installed, the familiar Laravel structure appeared:<\/p>\n<ul>\n<li><strong>app\/<\/strong> \u2013 Core application logic<\/li>\n<li><strong>routes\/<\/strong> \u2013 Route definitions<\/li>\n<li><strong>resources\/<\/strong> \u2013 Views and assets<\/li>\n<li><strong>public\/<\/strong> \u2013 Web root<\/li>\n<li><strong>storage\/<\/strong> \u2013 Logs, cache, runtime data<\/li>\n<\/ul>\n<p>Permissions were set carefully \u2014 owned by the application user, with only the required directories writable by the web server.<\/p>\n<p>No \u201cchmod 777 and hope for the best\u201d approach here.<\/p>\n<p>Clean from day one.<\/p>\n<hr \/>\n<h2>\u2699\ufe0f Environment Configuration<\/h2>\n<p>Laravel\u2019s <strong>.env<\/strong> file is where everything connects \u2014 and where things can go very wrong very quickly.<\/p>\n<p>So this was configured early and properly.<\/p>\n<p>Key settings included:<\/p>\n<ul>\n<li><strong>APP_URL<\/strong> set to the panel domain<\/li>\n<li><strong>APP_ENV<\/strong> set to production<\/li>\n<li><strong>APP_DEBUG<\/strong> disabled<\/li>\n<li>Database connection placeholders<\/li>\n<li>Redis configured for cache and queue usage<\/li>\n<\/ul>\n<p>The application key was then generated \u2014 a tiny command that quietly powers encryption, sessions, and basically everything important.<\/p>\n<p>At this point, Laravel was configured\u2026 but not yet fully connected.<\/p>\n<p>Which is always the slightly nervous stage.<\/p>\n<hr \/>\n<h2>\ud83d\uddc4\ufe0f Connecting the Database<\/h2>\n<p>MariaDB was already in place from Phase 1, so this step was all about integration.<\/p>\n<p>A dedicated database and user were created specifically for the panel.<\/p>\n<p>No root usage. No shared credentials. No future regrets.<\/p>\n<p>Once the credentials were added to the <strong>.env<\/strong> file, Laravel connected cleanly.<\/p>\n<p>Initial migrations were then executed, confirming that:<\/p>\n<ul>\n<li>The database connection was working<\/li>\n<li>Laravel could read and write successfully<\/li>\n<li>The application layer was now talking to storage properly<\/li>\n<\/ul>\n<p>This is the moment where it stops being \u201cjust files on a server\u201d\u2026 and starts becoming an actual system.<\/p>\n<hr \/>\n<h2>\ud83c\udf10 Nginx Configuration for Laravel<\/h2>\n<p>With the application in place, the next step was making it accessible.<\/p>\n<p>Nginx was configured with a dedicated server block.<\/p>\n<p>Key points:<\/p>\n<ul>\n<li>Document root pointed to <strong>\/public<\/strong><\/li>\n<li>Requests routed through <strong>index.php<\/strong><\/li>\n<li>PHP handled via PHP-FPM<\/li>\n<\/ul>\n<p>This ensures Laravel controls routing \u2014 not the web server \u2014 exactly how it should be.<\/p>\n<p>The default Nginx site was removed to keep things clean and intentional.<\/p>\n<p>No leftovers. No confusion later.<\/p>\n<hr \/>\n<h2>\u2705 First Successful Run<\/h2>\n<p>This is always one of those small wins that feels bigger than it should.<\/p>\n<p>Nginx reloaded. PHP-FPM running. Domain opened in the browser\u2026<\/p>\n<p>And there it was.<\/p>\n<p><strong>The Laravel welcome page.<\/strong><\/p>\n<p>No errors. No warnings. No blank screens staring back at you.<\/p>\n<p>At this stage, success means:<\/p>\n<ul>\n<li>The web server is correctly serving the application<\/li>\n<li>PHP is executing without issues<\/li>\n<li>Laravel routing is functioning<\/li>\n<li>The environment configuration is valid<\/li>\n<\/ul>\n<p>It looks simple.<\/p>\n<p>But behind that one page is an entire stack working together perfectly.<\/p>\n<p><!-- \u2705 IMAGE INSERT --><br \/>\n<!-- \u2705 IMAGE INSERT --><\/p>\n<figure style=\"max-width: 700px;margin: 30px auto;text-align: center\">\n  <img decoding=\"async\" src=\"https:\/\/kr0311.com\/projects\/wp-content\/uploads\/2026\/04\/Laravel-installed-page.png\" alt=\"Laravel welcome page running on panel.kr0311.com during Phase 2 build\" style=\"width: 100%;height: auto;border-radius: 12px\" \/><figcaption style=\"font-size: 0.9em;opacity: 0.75;margin-top: 10px\">\n    First successful Laravel application load on panel.kr0311.com \u2014 confirming the full stack was operational<br \/>\n  <\/figcaption><\/figure>\n<hr \/>\n<h2>\u26a0\ufe0f Notes &amp; Observations<\/h2>\n<p>A few small but important things came up during this phase:<\/p>\n<ul>\n<li>File permissions matter \u2014 fixing them later is far more painful<\/li>\n<li>Nginx must point to <strong>\/public<\/strong>, not the project root (seriously\u2026 don\u2019t do it)<\/li>\n<li>Clearing Laravel config cache avoids confusing behaviour during setup<\/li>\n<li>Using a dedicated database user keeps things clean and secure<\/li>\n<\/ul>\n<p>Nothing dramatic \u2014 but these are the details that quietly save hours later.<\/p>\n<hr \/>\n<h2>\ud83e\udde0 Why This Phase Matters<\/h2>\n<p>Phase 1 built the foundation.<\/p>\n<p>Phase 2 makes it usable.<\/p>\n<p>This is the turning point where the project stops being \u201ca server\u201d and starts becoming \u201ca platform\u201d.<\/p>\n<p>Laravel is now installed, configured, and running \u2014 ready to be shaped into a control panel.<\/p>\n<p>Everything from here builds on this layer.<\/p>\n<p>No pressure.<\/p>\n<hr \/>\n<h2>\ud83d\udd1c What\u2019s Next \u2013 Phase 3<\/h2>\n<p>With the application running, the next step is structure.<\/p>\n<p><strong>Phase 3 will focus on:<\/strong><\/p>\n<ul>\n<li>Authentication system (secure login)<\/li>\n<li>Panel layout and UI foundation<\/li>\n<li>Core application structure (users, dashboard)<\/li>\n<\/ul>\n<p>This is where the KR0311 Control Panel starts to actually <em>look<\/em> like something.<\/p>\n<hr \/>\n<h2>\ud83c\udfc1 Final Thoughts<\/h2>\n<p>This phase isn\u2019t about features.<\/p>\n<p>It\u2019s about getting the application layer right \u2014 clean, secure, and ready to scale.<\/p>\n<p>No hacks. No shortcuts. No \u201cwe\u2019ll fix that later\u201d.<\/p>\n<p>Just a solid base\u2026 that everything else is about to depend on.<\/p>\n<p>And now\u2026 the real work begins.<\/p>\n<p>This stage completes the application setup phase of the custom hosting control panel build.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Phase 2 of the KR0311 Control Panel build focuses on installing Laravel, configuring the environment, and preparing the platform for development.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[19,20,29,30,13,26,24,25,27,28,21,23,22],"class_list":["post-45","post","type-post","status-publish","format-standard","hentry","category-control-panel","tag-control-panel","tag-custom-hosting-control-panel","tag-hosting-infrastructure","tag-laravel","tag-linux","tag-mariadb","tag-nginx","tag-php","tag-redis","tag-security-hardening","tag-self-hosted","tag-server-setup","tag-ubuntu"],"_links":{"self":[{"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/posts\/45","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/comments?post=45"}],"version-history":[{"count":4,"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/posts\/45\/revisions"}],"predecessor-version":[{"id":92,"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/posts\/45\/revisions\/92"}],"wp:attachment":[{"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/media?parent=45"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/categories?post=45"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kr0311.com\/projects\/wp-json\/wp\/v2\/tags?post=45"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}