Deploying your app or website on a server with git
Published in code on February 06th, 2023.
How many times have you run the same commands over and over again during your deployments?
There's an easy way to combine everything as one.
This article comes right after the one where I've explained how to setup a git repository on your own server and has as a prerequisite everything I've presented there.
*It also applies only to single node servers. This is an important disclaimer, as you'd want to look directly into a proper CI/CD pipeline if you're using clustered servers. But not every website or application has to use a load balancer and span <insert_geeky_devops_terms_here>, so let's get going 😊.
The magic, taking place
The idea is to standardise your process and add every command you usually run on your server into one single file that you'll trigger once per deployment.
The first step is to SSH into your server and create a new shell script:
cd <your_app>
vi run_deployment
You can name the file in any other way you wish.
Put your application down
A good practice would be to bring down your application, so that it cannot be accessed by end users throughout your deployment. This works in a scenario where ideally you'd have a 503 page layout available, with a proper message for your users, that you can quickly activate with a CLI command.
In case you're using Laravel, you may do the following:
php artisan down
Fetch your code
In order to pull-in your most recent commits onto the server, you may consider doing something like:
git reset --hard
git clean -df
git pull origin <branch>
The first command would reset all your files on the server which are part of the version control, while the second will clean every untracked file as well. Use these carefully. There are multiple reasons why your host might contain modified tracked files or new untracked files and you should decide the applicability of these commands on a project and / or server level. Also, you'll need to make sure that your .gitignore is up-to-date.
Then you'll fetch & merge the content from your chosen <branch>. Replace this with your branch of choice, depending on the environment where you're performing these actions.
Install your dependencies
If you are using composer, npm or similar, you may consider installing your newest dependencies by running:
composer install
npm install
together with any relevant parameters into your env. For example, if you're deploying the app in production, you might want to append --no-dev to your composer command.
Build your code
Here you'd trigger the right script(s) defined into your system, like in the package.json file, that will build your .js, .css and any other assets available.
npm run build
Run your application-specific scripts
Another category of operations you might be performing for every deployment are database migrations, clearing the cache or restarting your queues. Once again, applicable for Laravel, you might have something like:
php artisan migrate
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan permission:cache-reset
php artisan queue:restart
php artisan horizon:terminate
Bring your application up
Just do the opposite of the first command, clear the 503 and bring the application back up for your users. For Laravel, this would be:
php artisan up
One file, all commands
Add these or any other commands that might be applicable to your case into your own run_deployment file and you'd end up with something like this:
# Put the application down
php artisan down
# Fetch the code
git reset --hard
git clean -df
git pull origin <branch>
# Install dependencies
composer install --optimize-autoloader --no-dev
npm install
# Build the code
npm run build
# Migrate the database
php artisan migrate
# Clear the cache
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan permission:cache-reset
# Restart the queues
php artisan queue:restart
php artisan horizon:terminate
# Put the application up
php artisan up
Save the file.
Trigger the deployment
Now, with every planned deployment, you'll have to cd into the right directory and trigger one command. Your deployment actions will then run in full and the right order.
bash run_deployment
This will make things much much faster. Of course, you might want to think about certain edge cases exclusive to you project (like running seeders, maybe restarting your workers because of a new queue, etc.) whenever such would apply and I'm sure you'd be able to fit the steps in somewhere along the way.