Back to blog

Deploy a Laravel 7 app to shared hosting (namecheap)

Posted

Namecheap has very good documentation about how to install Laravel and start a new project but it doesn't explain how to deploy your existing project. This is a step-by-step guide of how I did it from installing composer to deploying your code, database configuration and Apache config.

Install Composer and upload your site

The first thing to do is to make sure we're using a valid version of PHP and that we've enabled all the extensions that Laravel requires (check the docs for that). In your Cpanel, go to "Select PHP version", select the one you want (v7.3 or v7.4 recommended in Mar 2020) and enable all the extensions you need by checking the correspondent box. We need to access our server via SSH so you'd need to generate a key and authorise it. You can find a guide on how to do it in this article.

To connect to the server, I use MobaXterm, a free SSH client that allows you to upload/download files via SFTP and has an explorer window (and it's free). If you're on Mac/Unix, you can use the terminal. Once we're connected to our server, navigate to public_html and create a folder named composer with cd public_html && mkdir composer && cd composer. Go into this folder and execute the following command:

cp /opt/alt/php73/etc/php.ini /home/YOURUSER/public_html/composer

Note: the php73 folder is for PHPv7.3, if you're using a different version, the folder name would be different.

This will copy the php.ini file to from the default PHP installation folder to the one we've just created. Now open the file with an editor with nano php.ini and add the following lines at the end:

max_execution_time = 300
max_input_time = 300
memory_limit = 512M
suhosin.executor.include.whitelist = phar
detect_unicode = Off

Now we're ready to install Composer, the PHP dependency manager. Just run the following command

php -r "readfile('https://getcomposer.org/installer');" | php -c php.ini

With composer installed, we'll now be able to clone or copy our application and install the dependencies.

Assuming that you have your site in a repository, you can clone it directly to the public_html folder with git clone https://github.com/YOUR_USER/you-repo.git

If you don't have your web in a repository or if you just prefer to upload it manually, you can use FTP or the File Manager from the Namecheap cPanel. Just remember to upload all files/folder of your app except the vendor and node_modules folders, as these ones contain all the PHP and Javascript dependencies and we'll install them directly in the server with Composer and NPM.

Once your site is uploaded, go into the folder that contains all your files and run composer install to install all the PHP dependencies of your project (like Laravel, Symfony etc...).

The last thing would be to generate our site's private key with php artisan key:generate.

Install NPM for JS dependencies

By default, Namecheap shared hosting does not have NPM/Node.js installed. We can install Node Version Manager (or NVM) with the following command:

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

This command will download and execute the installation script and NVM will be installed in the /.nvm folder. Exit the SSH console and access again so your profile is refreshed and the nvm command is available. Now install the Node.js version you want, for example, to install v11 execute nvm i 11

Note: Looks like some dependencies required for Node v12 are not installed by default in the Namecheap shared hosting, so the latest version you can install is v11 😕

Now if we run node -v or npm -v we should receive the version numbers, which confirms the installation was successful. Navigate to your project folder inside public_html and execute npm install to install all your dependencies. Once done, execute npm run prod to compile all your assets in the resources folder of your project.

Note: In my case, npm run prod was getting stuck so I had to run the following command instead (which does exactly the same btw)

NODE_ENV=production node_modules/webpack/bin/webpack.js --hide-modules --config=node_modules/laravel-mix/setip/webpack-config.js

Configure and migrate your database

You'll probably need a database for your Laravel application.... In the Namecheap cPanel, go to MySQL Databases and create a database and username/password. Make sure you add the user to the database and grant it all the permissions required. Now you need to create an .env file and configure the database details inside it. As Laravel ships with an example env file that you can just rename that one with mv .env.example .env and then open it with the editor with nano .env .

Note: If you're using environment variables in your .env file, you'll just need to create them in the terminal with export MY_ENV_VARIABLE=value .

Now you can migrate your database from your local/development environment or create your tables using the migration files from your project.

If you want to import some data from your development/local environment you can use DBeaver or Sequel Pro to create a DDL or SQL file that will contain all the table creation and data insert queries (search for any option to export or dump database). Once you have your export file go to the cPanel > phpMyAdmin and select your database. Go to the Import tab and select your file and click Go at the end to upload it and execute it.

If you don't need to migrate any data and prefer to use the migrations files, once the connection details are configured in the .env file, you'd just need to run php artisan migrate.

Note: If you get an error similar to this one

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes (SQL: alter table `users` add unique `users_email_unique`(`email`))

You'll need to edit the file app/Providers/AppServiceProvider.php (use nano app/Providers/AppServiceProvider.php) as detailed in this article.

Once this is done, our code is deployed in our server and the database is ready. We just need to indicate our webserver to point to our app.

Configure webserver

First, go to your cPanel > Domains and you should see your domain name and the document root pointing to public_html. This means that the webserver (Apache) is serving your page from the public_html folder. The problem is, our Laravel project is inside its own folder inside public_html. Let's say your registered domain is awesome.com and that the folder you've uploaded your files inside public_html is named awe_web. If you'd open a browser and go to awesome.com/awe_web/public you should see your site 🎉🎉 . However, we don't want to access our site with that domain, we'd want to use just our .com domain.

In order to tell Apache to look inside our Laravel project folder, we need to set up a redirect rule in the .htaccess file. Open an SSH terminal to the server and run nano public_html/.htaccess to open the file with the editor. It should be empty so add the following lines:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?YOUR_DOMAIN.com$
RewriteCond %{REQUEST_URI} !^/YOUR_FOLDER/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /YOUR_FOLDER/public/$1
RewriteCond %{HTTP_HOST} ^(www.)?YOUR_DOMAIN.com$
RewriteRule ^(/)?$ YOUR_FOLDER/public/index.php [L]

Replace YOUR_DOMAIN with your registered domain name and YOUR_FOLDER with the name of the folder that contains your Laravel project files. With these changes, if we go to our domain, it should open our Laravel project's home page 🤘.

Included in categories

coding laravel deployments