GitLab Laravel Continues Deployment tutorial

Automation can be a game-changer, especially when it comes to deploying web applications. If you’ve ever manually deployed a Laravel project, you know how tedious and error-prone it can be. That’s where GitLab CI/CD swoops in like a superhero. With just a little bit of setup, you can automate the entire deployment process, giving you more time to focus on building great applications.

In this guide, I’ll show you step-by-step how to automatically deploy a Laravel project using GitLab CI/CD. It’s not just about the “how” but also the “why,” so you can walk away with a solid understanding of what’s happening under the hood.

Prerequisites

Before we dive in, make sure you have the following:

  1. A Laravel Project: Your code should already be hosted on GitLab.
  2. A Deployment Server: This could be a VPS from providers like DigitalOcean, AWS, or Linode, etc.
  3. SSH Access: You’ll need SSH keys for secure communication between GitLab and your server.

If you’re missing any of these, don’t worry. I’ll touch on setting up the basics as we go.

Setting Up Your Deployment Environment

Start by ensuring your server is ready to run Laravel. This involves installing PHP, Composer, and the required extensions. Here’s a quick checklist:

  1. Install PHP: Ensure you have PHP installed.
  2. Install Composer: Laravel relies on Composer to manage dependencies.
  3. Set Up a Web Server: Use Nginx or Apache, whichever you’re comfortable with.
  4. Database Configuration: Ensure your database, like MySQL or PostgreSQL is running and accessible.

Setting Up SSH Keys

For GitLab to securely communicate with your server, you need to set up SSH keys:

  1. Generate a key pair on your local machine:
    ssh-keygen -t rsa -b 4096 -C "[email protected]"
  2. Add the public key to your server’s ~/.ssh/authorized_keys.
  3. Add the private key to GitLab CI/CD variables (more on this later).

Preparing the Webserver for Continuous Deployment

To prepare your webserver for seamless Continuous Deployment, follow these steps:

  1. Start by logging into your webserver using SSH. You can either use an existing user or create a new one specifically for deployment purposes. To create a new user, execute the following command:
sudo adduser deployer
  1. To avoid the need to change file permissions every time, add the web server user (e.g., www-data) to the deployer group:
sudo usermod -a -G deployer www-data
  1. Create a new directory to host your project:
sudo mkdir /var/www/your_project
  1. Next, change the owner of the project directory to the deployer user:
sudo chown -R deployer:deployer /var/www/your_project
  1. If your project requires a specific configuration file, you can place it in the newly created directory. Otherwise, you can omit the cp .env.local $CI_COMMIT_SHA/ command in the configuration steps below.
  1. If you don’t already have an SSH key, generate one by logging in as the deployer user:
su deployer

Then, create the SSH key using the following command (remember to replace [email protected] with your actual email address):

ssh-keygen -t ed25519 -C "[email protected]"
  1. To enable SSH access, add the content of the public key to the authorized_keys file:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
  1. Finally, copy the content of the private key, as it will be needed for the GitLab configuration:
cat ~/.ssh/id_rsa

By following these steps, you’ll ensure that your webserver is properly set up for Continuous Deployment, allowing for smooth and efficient deployment of your project.

The steps are the same for Symfony CI/CD configuration. You can follow the same process to prepare your Laravel project for deployment.

Writing the GitLab CI/CD Configuration File

The heart of your automation lies in the .gitlab-ci.yml file. Let’s break it down.

Defining Stages

Stages are the backbone of your pipeline. For Laravel deployment, we’ll use:

  1. Build: Install dependencies and build project.
  2. Test: Run automated tests.
  3. Deploy: Push the application to the server.

Sample .gitlab-ci.yml

Here’s a basic configuration to get you started:

image: bogkonstantin/php-7.4-node-12-debug:latest

stages:
   - build
   - test
   - deploy

build:
   stage: build
   only:
      - master
   artifacts:
      paths:
         - ./
   script:
      - export APP_ENV=prod
      - composer install --no-dev --optimize-autoloader
      - npm install
      - npm run prod
      - rm -r node_modules

test:
   stage: test
   script:
      - php artisan test

deploy:
   stage: deploy
   only:
      - master
   before_script:
      - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
      - eval $(ssh-agent -s)
      - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
      - mkdir -p ~/.ssh
      - chmod 700 ~/.ssh
      - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config'
   script:
      - zip -r $CI_COMMIT_SHA.zip .
      - scp -p $CI_COMMIT_SHA.zip $SSH_USER@$SSH_HOST:/var/www/$PROJECT_FOLDER/
      - ssh $SSH_USER@$SSH_HOST "cd  /var/www/$PROJECT_FOLDER/ && unzip -q $CI_COMMIT_SHA.zip -d $CI_COMMIT_SHA && rm $CI_COMMIT_SHA.zip && cp .env.local $CI_COMMIT_SHA/ && ln -sfn $CI_COMMIT_SHA current && exit"

This file defines what happens at each stage. You can tweak it to suit your specific needs.

Setting up a GitLab repository for Continuous Deployment

To enable or disable GitLab CI/CD Pipelines for your project, follow these steps:

  1. Open GitLab and navigate to your project.
  2. Click on “Settings” in the sidebar menu.
  3. In the Settings page, select “General” from the tabs on the left.
  4. Scroll down and click on “Visibility, project features, permissions” to access the related options.
  5. Expand the “Repository” section.
  6. Look for the “CI/CD” toggle and enable or disable it based on your desired configuration.

Now, let’s proceed with adding the necessary environment variables:

  1. Go back to your project’s Settings.
  2. This time, select “CI/CD” from the tabs on the left.
  3. Scroll down to find the “Variables” section.
  4. Click on the “Add Variable” button to create a new variable.
  5. For each variable, add the following details:
    • Variable Key: SSH_PRIVATE_KEY
    • Variable Value: Copy the contents of the id_rsa file from the previous step.
    • Variable Key: SSH_USER
    • Variable Value: deployer (or the desired username)
    • Variable Key: SSH_HOST
    • Variable Value: Your server’s IP address
    • Variable Key: PROJECT_FOLDER
    • Variable Value: Enter the desired folder name
  6. Click on the “Add Variable” button to save each variable.

By configuring these environment variables, you provide essential information for your CI/CD pipeline to connect and deploy to the target server. The SSH_PRIVATE_KEY variable allows secure authentication, SSH_USER specifies the username (e.g., deployer), SSH_HOST indicates the server’s IP address, and PROJECT_FOLDER denotes the desired folder name.

Rollback Strategy for Safe Deployments

Deployments don’t always go as planned. That’s why you need a rollback strategy:

  1. Database Backups: Before running migrations, back up the database.
  2. Previous Builds: Keep the last working version of your app accessible.
  3. Error Notifications: Set up alerts for pipeline failures.

Troubleshooting Common Issues

  • Pipeline Fails at SSH Step: Ensure your SSH keys are correctly configured.
  • PHP Errors: Double-check that your server’s PHP version matches your development environment.
  • Permission Issues: Use chmod and chown to fix file permission errors.

Enhancing Your Pipeline

Once you’ve got the basics down, consider these enhancements:

  1. Add Static Analysis: Use tools like PHPStan or Laravel Pint for code quality.
  2. Implement Zero-Downtime Deployment: Tools like Laravel Envoyer can ensure your app stays online during updates.
  3. Multi-Environment Pipelines: Create separate pipelines for staging and production.

Conclusion

Congratulations! You’ve set up a fully automated deployment pipeline for your Laravel project using GitLab CI/CD. This setup not only saves you time but also reduces the risk of human error. As you grow more comfortable with CI/CD, you can refine and expand your pipeline to include additional quality checks and deployment strategies.

Remember, automation is an iterative process. Start simple and build from there.