Automated Laravel Deployment via GitLab CI/CD Pipelines

The implementation of a Continuous Integration and Continuous Deployment (CI/CD) pipeline for a Laravel application represents a critical transition from manual, error-prone deployments to a streamlined, automated software delivery lifecycle. By integrating GitLab CI/CD with containerization technologies and cloud infrastructure, developers can ensure that every code commit is systematically validated, tested, and deployed without manual intervention. This architectural approach eliminates the "it works on my machine" phenomenon by utilizing Docker to standardize environments across development, staging, and production. The primary objective is to create a fail-safe mechanism where code quality is enforced through automated linting and unit testing before the application ever reaches a live server.

Architectural Infrastructure and Technology Stacks

The choice of a technology stack for Laravel CI/CD determines the scalability and reliability of the deployment process. Depending on the organizational needs, the infrastructure can range from simple Ubuntu servers to complex Kubernetes clusters or managed cloud services like AWS Elastic Beanstalk.

Lightweight Kubernetes Implementation (K3s)

For those seeking a modern, container-orchestrated environment on a budget, a combination of K3s and Hetzner provides a high-performance solution.

Component Specification/Role
Server Provider Hetzner VPS
Hardware Specs 4GB RAM / 2 CPU cores
Operating System Debian
Kubernetes Distribution K3s (Lightweight)
Deployment Automation ArgoCD
Container Management Portainer
Networking/Security Cloudflare DNS and SSL
Cost Approximately $5

In this configuration, K3s allows for the management of Laravel containers with minimal overhead, while ArgoCD implements a GitOps pattern, ensuring the state of the cluster matches the configuration stored in the Git repository. Portainer provides a graphical interface for container management, offering visibility into the health and logs of the application.

AWS Elastic Beanstalk Integration

Alternatively, AWS Elastic Beanstalk offers a managed approach to deployment, abstracting the underlying EC2 infrastructure. This setup typically involves a multi-branch strategy where the staging branch triggers automatic deployment and the master branch requires manual approval to prevent accidental production outages.

Containerization Strategy for Laravel

Containerizing a Laravel application ensures that the PHP environment, system dependencies, and web server configurations remain identical across all stages of the pipeline.

The PHP Dockerfile Configuration

A robust php.dockerfile is essential for defining the runtime environment. The following configuration utilizes a PHP 8-Apache base image to provide a stable web server environment.

```dockerfile

Base image with PHP and Apache

FROM php:8-apache

Install system dependencies and PHP extensions

RUN apt-get update && apt-get install -y \
curl \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libzip-dev \
zip \
unzip \
supervisor \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install gd bcmath pdo pdo_mysql zip

Install pcov for laravel test coverage

RUN pecl install pcov && \
docker-php-ext-enable pcov

Enable Apache modules

RUN a2enmod rewrite

Set working directory

WORKDIR /var/www/html

Copy existing application directory contents

COPY ./src .

Install Composer

COPY --from=composer /usr/bin/composer /usr/bin/composer

Copy custom Apache virtual host configuration

COPY conf/apache/000-default.conf /etc/apache2/sites-available/000-default.conf

Expose port 80

EXPOSE 80

Start Apache in the foreground

CMD ["apache2-foreground"]
```

The inclusion of pcov is a strategic choice for Laravel developers, as it allows for high-performance code coverage analysis during the testing phase. The a2enmod rewrite command is mandatory for Laravel, as it enables the Apache mod_rewrite module, which allows the framework to handle pretty URLs via the .htaccess file.

Application Structure

A standard Laravel project structure integrated into a CI/CD pipeline typically separates the application logic from the orchestration configurations.

  • laravel-app/
    • app/
    • artisan
    • bootstrap/
    • composer.json
    • composer.lock
    • config/
    • database/
    • eslint.config.js
    • node_modules/
    • package.json
    • package-lock.json
    • phpunit.xml
    • public/
    • resources/
    • routes/
    • storage/
    • tests/
    • tsconfig.json
    • vendor/
    • vite.config.ts
  • docker/
    • compose.yaml

GitLab CI/CD Pipeline Design

The .gitlab-ci.yml file acts as the brain of the automation process, defining the sequence of stages that every code push must undergo.

Pipeline Stages and Variables

A comprehensive pipeline is divided into four primary stages: build, test, quality, and deploy. This ensures that no code is deployed if it fails a test or violates quality standards.

```yaml
default:
image: docker:latest
services:
- docker:dind

beforescript:
- echo "$CI
REGISTRYPASSWORD" | docker login -u $CIREGISTRYUSER $CIREGISTRY --password-stdin

variables:
DOCKERDRIVER: overlay2
MYSQL
DATABASE: laravel
MYSQLROOTPASSWORD: secret
MYSQLUSER: laravel
MYSQL
PASSWORD: secret
TESTDBHOST: mysql
TESTDBPORT: 3306
IMAGE: $CIREGISTRYIMAGE/app:latest

stages:
- build
- test
- quality
- deploy
```

The docker:dind (Docker-in-Docker) service is utilized to allow the pipeline to build and push Docker images from within a GitLab runner. The before_script section ensures that the runner is authenticated with the GitLab Container Registry before attempting any image operations.

The Build Stage

The build stage is responsible for transforming the source code into a deployable artifact. This process involves optimizing the composer dependencies and building the Docker image.

yaml build: stage: build script: - docker pull $IMAGE || true - docker run --rm -v $PWD/src:/app composer install --optimize-autoloader --prefer-dist --no-scripts - docker build -f php.dockerfile --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $IMAGE --tag $CI_REGISTRY_IMAGE/app:$CI_COMMIT_SHA --tag $IMAGE . - docker push $IMAGE - docker push $CI_REGISTRY_IMAGE/app:$CI_COMMIT_SHA only: - main cache: key: ${CI_COMMIT_REF_SLUG}-composer paths: - src/vendor/ policy: push

By utilizing --optimize-autoloader, the build process ensures that the class map is optimized for production, reducing the overhead of file lookups. The use of $CI_COMMIT_SHA as a tag provides an immutable reference to the specific version of the code, enabling precise rollbacks if a production bug is discovered.

Testing and Quality Assurance

Automated testing is the primary shield against regression bugs. In a professional Laravel CI/CD setup, this involves both functional testing and static code analysis.

Unit and Feature Testing

Laravel developers typically utilize PHPUnit or Pest for testing. The CI/CD pipeline invokes these tools during the test stage. A specialized .env.ci file is used during this phase to define environment variables specifically for the testing environment, ensuring that the production database is never touched during a test run.

Code Quality with PHP CodeSniffer

The quality stage employs PHP CodeSniffer (PHP-CS) to ensure that the code adheres to defined styling standards (such as PSR-12). This prevents "style wars" during code reviews and maintains a clean, readable codebase across a team of multiple developers.

Advanced Deployment Strategies

Deployment varies significantly based on the target environment. Whether deploying to a VPS or a managed cloud, the goal is to minimize downtime and ensure configuration consistency.

AWS Elastic Beanstalk Deployment

When deploying to AWS, the pipeline leverages the EB CLI. To facilitate this, an IAM user with "Elastic Beanstalk Full Access" is required. The deployment process typically includes:

  • Running eb init to initialize the environment.
  • Using .ebextensions YAML files to instruct the AWS server on specific tasks.
  • Executing composer install and php artisan migrate to prepare the database and dependencies.

A critical configuration for Elastic Beanstalk is specifying that the application is served from the /public directory and configuring Apache to force HTTPS redirects, which is a mandatory security requirement for modern web applications.

GitOps with ArgoCD and K3s

In the Kubernetes model, the pipeline does not "push" the code to the server. Instead, it updates the image tag in the registry, and ArgoCD "pulls" the change into the cluster. This ensures that the cluster state is always synchronized with the Git repository.

Prerequisites for Implementation

To successfully execute these CI/CD setups, the following requirements must be met:

  • GitLab account with a project repository.
  • Docker and Docker Compose installed on local development machines.
  • An Ubuntu or Debian server with Docker installed for production hosting.
  • AWS Account with an IAM user configured for Beanstalk access (for AWS users).
  • EB CLI installed and initialized via eb init.
  • Domain and SSL configuration via Cloudflare (for K3s/VPS users).

Conclusion

The transition to an automated CI/CD pipeline for Laravel transforms the development experience from a high-risk manual process to a predictable, engineering-driven workflow. By integrating Docker, the environment is standardized, eliminating discrepancies between local development and production. The use of GitLab CI/CD's multi-stage pipeline—encompassing build, test, quality, and deployment—ensures that only code that passes rigorous testing and style checks is allowed into the production environment.

Whether opting for the lightweight efficiency of K3s on a Hetzner VPS or the managed scalability of AWS Elastic Beanstalk, the core principle remains the same: automation reduces human error and accelerates the time-to-market. The strategic use of Docker image tagging via commit SHAs and the implementation of manual triggers for the master branch provides a necessary balance between speed and safety. Ultimately, this infrastructure allows developers to focus on writing features rather than managing the complexities of server deployment.

Sources

  1. Build with Code - Laravel CI/CD
  2. 9ovind - Laravel Full CI/CD Setup with Kubernetes and Docker
  3. Dev.to - Deploy Laravel to AWS Beanstalk with GitLab CI

Related Posts