Support the ongoing development of Laravel.io →
Article Hero Image

Laravel CI Pipeline: Jenkins + n8n + GitLab CI Guide 2025

29 Jul, 2025 17 min read

Photo by Wolfgang Weiser on Unsplash

Introduction

Modern Laravel development demands robust CI/CD pipelines that can automatically handle deployments, database migrations, and infrastructure management. If you're struggling with manual deployments, inconsistent environments, or worried about running critical commands like php artisan migrate in production, you're not alone. Building effective CI/CD for Laravel applications requires careful planning and the right tool combinations.

The challenge becomes even more complex when your production environment runs on Kubernetes, and you need seamless integration between GitLab CI, Jenkins, and workflow automation tools like n8n. Many developers find themselves caught between fragmented tools, manual processes, and the fear of breaking production systems.

In this comprehensive guide, you'll learn how to build a complete Laravel CI/CD pipeline that automatically triggers database migrations in production when code is merged to master, using Jenkins to orchestrate n8n workflows that execute kubectl commands safely in your Kubernetes environment.

Understanding the CI/CD Architecture

The Complete Pipeline Overview

Our CI/CD architecture consists of four main components working in harmony:

GitLab CI serves as the trigger point, detecting changes when developers merge code to the master branch. While GitLab CI vs GitHub Actions each have their strengths, GitLab CI excels at code integration when you're already using GitLab for version control. Jenkins acts as the orchestration layer, managing the overall deployment process and maintaining deployment history. n8n handles workflow automation, providing a visual interface for complex deployment logic. Finally, Kubernetes hosts our production Laravel application, providing scalability and reliability.

This architecture ensures that every merge to master automatically triggers a sequence of events: GitLab CI detects the change, Jenkins receives the webhook, n8n executes the deployment workflow, and kubectl commands run the necessary database migrations and application updates.

Benefits of This Multi-Tool Approach

Using multiple specialized tools might seem complex, but it provides significant advantages. GitLab CI excels at code integration and testing, Jenkins offers robust build management and plugin ecosystem, n8n provides visual workflow design with excellent error handling, and Kubernetes delivers production-grade container orchestration.

This separation of concerns means each tool can focus on what it does best, while maintaining clear boundaries and responsibilities. You get the reliability of Jenkins, the flexibility of n8n, the integration capabilities of GitLab CI, and the scalability of Kubernetes.

Setting Up GitLab CI for Laravel

Basic GitLab CI Configuration

Start by creating a .gitlab-ci.yml file in your Laravel project root. This file defines the pipeline stages and triggers that will initiate your deployment process:

stages:
  - test
  - build
  - deploy

variables:
  JENKINS_URL: "https://your-jenkins-instance.com"
  JENKINS_JOB: "laravel-production-deploy"

test:
  stage: test
  image: php:8.2
  before_script:
    - apt-get update -qq && apt-get install -y -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev
    - curl -sS https://getcomposer.org/installer | php
    - php composer.phar install --no-dev --no-scripts
  script:
    - cp .env.example .env
    - php artisan key:generate
    - php artisan test
  only:
    - master
    - merge_requests

The test stage is crucial for maintaining code quality before deployment. For comprehensive guidance on Laravel testing strategies, check out our guide on [Laravel testing with unit, feature, and integration tests](https://mycuriosity.blog/laravel-testing-unit-feature-and-integration-tests) to ensure your CI pipeline catches issues early.

deploy_production:
  stage: deploy
  script:
    - |
      curl -X POST \
        -H "Authorization: Bearer $JENKINS_API_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{\"parameter\": [{\"name\": \"GIT_COMMIT\", \"value\": \"$CI_COMMIT_SHA\"}, {\"name\": \"BRANCH\", \"value\": \"$CI_COMMIT_REF_NAME\"}]}" \
        "$JENKINS_URL/job/$JENKINS_JOB/buildWithParameters"
  only:
    - master
  when: manual

Advanced GitLab Integration

For more sophisticated deployments, configure GitLab to pass additional metadata to Jenkins. This includes commit information, branch details, and deployment environments:

deploy_production:
  stage: deploy
  variables:
    DEPLOYMENT_METADATA: |
      {
        "commit_sha": "$CI_COMMIT_SHA",
        "commit_message": "$CI_COMMIT_MESSAGE",
        "branch": "$CI_COMMIT_REF_NAME",
        "pipeline_id": "$CI_PIPELINE_ID",
        "environment": "production",
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
      }
  script:
    - echo "$DEPLOYMENT_METADATA" > deployment_metadata.json
    - |
      curl -X POST \
        -H "Authorization: Bearer $JENKINS_API_TOKEN" \
        -H "Content-Type: application/json" \
        -F "metadata=@deployment_metadata.json" \
        "$JENKINS_URL/job/$JENKINS_JOB/buildWithParameters"

Configuring Jenkins for Laravel Deployments

Jenkins Job Setup

Create a new Jenkins pipeline job specifically for Laravel deployments. This job will receive triggers from GitLab CI and orchestrate the entire deployment process through n8n workflows.

Install the necessary Jenkins plugins: HTTP Request Plugin, Build Authorization Token Root Plugin, and Pipeline Plugin. These plugins enable Jenkins to receive webhooks from GitLab and make HTTP requests to n8n workflows.

Jenkins Pipeline Configuration

Configure your Jenkins pipeline to accept parameters from GitLab CI and trigger n8n workflows:

pipeline {
    agent any
    
    parameters {
        string(name: 'GIT_COMMIT', defaultValue: '', description: 'Git commit SHA')
        string(name: 'BRANCH', defaultValue: 'master', description: 'Git branch')
        string(name: 'ENVIRONMENT', defaultValue: 'production', description: 'Deployment environment')
    }
    
    environment {
        N8N_WEBHOOK_URL = credentials('n8n-webhook-url')
        KUBE_CONFIG = credentials('kubernetes-config')
    }
    
    stages {
        stage('Validate Parameters') {
            steps {
                script {
                    if (!params.GIT_COMMIT) {
                        error('Git commit SHA is required')
                    }
                    echo "Deploying commit ${params.GIT_COMMIT} to ${params.ENVIRONMENT}"
                }
            }
        }
        
        stage('Trigger n8n Workflow') {
            steps {
                script {
                    def payload = [
                        git_commit: params.GIT_COMMIT,
                        branch: params.BRANCH,
                        environment: params.ENVIRONMENT,
                        jenkins_job: env.JOB_NAME,
                        jenkins_build: env.BUILD_NUMBER
                    ]
                    
                    def response = httpRequest(
                        url: "${N8N_WEBHOOK_URL}",
                        httpMode: 'POST',
                        contentType: 'APPLICATION_JSON',
                        requestBody: groovy.json.JsonBuilder(payload).toString(),
                        timeout: 300
                    )
                    
                    if (response.status != 200) {
                        error("n8n workflow failed with status: ${response.status}")
                    }
                    
                    echo "n8n workflow triggered successfully"
                    echo "Response: ${response.content}"
                }
            }
        }
        
        stage('Monitor Deployment') {
            steps {
                script {
                    // Add monitoring logic here
                    echo "Monitoring deployment progress..."
                    sleep(30)
                }
            }
        }
    }
    
    post {
        success {
            echo "Deployment completed successfully"
        }
        failure {
            echo "Deployment failed"
        }
    }
}

Security and Access Control

Configure Jenkins security properly by creating dedicated service accounts for GitLab integration. Use Jenkins credentials store to manage sensitive information like API tokens, Kubernetes configurations, and n8n webhook URLs.

Set up proper authentication tokens in GitLab CI variables and Jenkins credentials. Never hardcode sensitive information in your pipeline configurations. Use Jenkins' built-in encryption for storing Kubernetes config files and other sensitive deployment artifacts.

Building n8n Workflows for Kubernetes Deployments

Creating the Main Deployment Workflow

n8n provides a visual interface for building complex deployment workflows. Create a new workflow that receives webhooks from Jenkins and orchestrates Kubernetes deployments with proper error handling and rollback capabilities.

Your n8n workflow should include the following nodes: Webhook (to receive Jenkins triggers), Function (for data processing), HTTP Request (for kubectl commands), Condition (for deployment validation), and Slack/Email (for notifications).

Webhook Configuration in n8n

Configure the webhook node to accept deployment requests from Jenkins:

// Webhook node - HTTP method: POST
// In the Function node, process the incoming data:

const deploymentData = {
  gitCommit: $json.git_commit,
  branch: $json.branch,
  environment: $json.environment,
  jenkinsJob: $json.jenkins_job,
  jenkinsBuild: $json.jenkins_build,
  timestamp: new Date().toISOString()
};

// Validate required parameters
if (!deploymentData.gitCommit) {
  throw new Error('Git commit SHA is required');
}

if (deploymentData.environment !== 'production') {
  throw new Error('Only production deployments are supported');
}

return {
  deployment: deploymentData,
  kubeNamespace: 'laravel-prod',
  migrationCommand: 'php artisan migrate --force'
};

Kubernetes Integration Node

Create a function node that executes kubectl commands to deploy your Laravel application and run database migrations:

// Function node for Kubernetes deployment
const kubeCommands = [
  // Update deployment with new image
  `kubectl set image deployment/laravel-app laravel-app=your-registry/laravel:${$json.deployment.gitCommit} -n ${$json.kubeNamespace}`,
  
  // Wait for rollout to complete
  `kubectl rollout status deployment/laravel-app -n ${$json.kubeNamespace} --timeout=300s`,
  
  // Run database migrations
  `kubectl exec -n ${$json.kubeNamespace} deployment/laravel-app -- ${$json.migrationCommand}`,
  
  // Verify deployment health
  `kubectl get pods -n ${$json.kubeNamespace} -l app=laravel-app --field-selector=status.phase=Running`
];

return {
  commands: kubeCommands,
  namespace: $json.kubeNamespace,
  deployment: $json.deployment
};

Error Handling and Rollback Strategy

Implement comprehensive error handling in your n8n workflow. If any kubectl command fails, the workflow should automatically trigger a rollback to the previous stable version:

// Error handling function node
if ($json.error) {
  const rollbackCommands = [
    `kubectl rollout undo deployment/laravel-app -n ${$json.namespace}`,
    `kubectl rollout status deployment/laravel-app -n ${$json.namespace} --timeout=300s`
  ];
  
  return {
    action: 'rollback',
    commands: rollbackCommands,
    originalError: $json.error,
    deployment: $json.deployment
  };
}

return {
  action: 'success',
  deployment: $json.deployment
};

Kubernetes Configuration for Laravel

Laravel Deployment Manifest

Create Kubernetes manifests for your Laravel application that support rolling updates and health checks. If you're new to containerization, our introduction to Docker and Kubernetes provides the foundational knowledge needed for this setup:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: laravel-app
  namespace: laravel-prod
  labels:
    app: laravel-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  selector:
    matchLabels:
      app: laravel-app
  template:
    metadata:
      labels:
        app: laravel-app
    spec:
      containers:
      - name: laravel-app
        image: your-registry/laravel:latest
        ports:
        - containerPort: 80
        env:
        - name: APP_ENV
          value: "production"
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: laravel-secrets
              key: db-host
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: laravel-secrets
              key: db-password
        livenessProbe:
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

Database Migration Job Template

Create a Kubernetes Job template for running database migrations safely:

apiVersion: batch/v1
kind: Job
metadata:
  name: laravel-migration-${BUILD_NUMBER}
  namespace: laravel-prod
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: migration
        image: your-registry/laravel:${GIT_COMMIT}
        command: ["php", "artisan", "migrate", "--force"]
        env:
        - name: APP_ENV
          value: "production"
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: laravel-secrets
              key: db-host
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: laravel-secrets
              key: db-password
      backoffLimit: 3

RBAC Configuration

Set up proper Role-Based Access Control (RBAC) for your deployment automation:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: laravel-deployer
  namespace: laravel-prod
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: laravel-prod
  name: laravel-deployment-manager
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: ["batch"]
  resources: ["jobs"]
  verbs: ["create", "get", "list", "watch", "delete"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: laravel-deployment-binding
  namespace: laravel-prod
subjects:
- kind: ServiceAccount
  name: laravel-deployer
  namespace: laravel-prod
roleRef:
  kind: Role
  name: laravel-deployment-manager
  apiGroup: rbac.authorization.k8s.io

Advanced Pipeline Features

Blue-Green Deployment Strategy

Implement blue-green deployments for zero-downtime updates. This strategy maintains two identical production environments and switches traffic between them during deployments:

// n8n function node for blue-green deployment
const currentEnvironment = $json.currentActive; // 'blue' or 'green'
const targetEnvironment = currentEnvironment === 'blue' ? 'green' : 'blue';

const deploymentCommands = [
  // Deploy to inactive environment
  `kubectl set image deployment/laravel-app-${targetEnvironment} laravel-app=your-registry/laravel:${$json.gitCommit} -n laravel-prod`,
  
  // Wait for deployment
  `kubectl rollout status deployment/laravel-app-${targetEnvironment} -n laravel-prod --timeout=300s`,
  
  // Run migrations on target environment
  `kubectl exec -n laravel-prod deployment/laravel-app-${targetEnvironment} -- php artisan migrate --force`,
  
  // Switch service to target environment
  `kubectl patch service laravel-service -n laravel-prod -p '{"spec":{"selector":{"version":"${targetEnvironment}"}}}'`
];

return {
  commands: deploymentCommands,
  targetEnvironment: targetEnvironment,
  previousEnvironment: currentEnvironment
};

Database Migration Safety Checks

Add safety checks before running database migrations to prevent data loss:

// Migration safety check function
const safetyChecks = [
  // Check for pending migrations
  `kubectl exec -n laravel-prod deployment/laravel-app -- php artisan migrate:status`,
  
  // Backup database before migration
  `kubectl exec -n laravel-prod deployment/laravel-app -- php artisan backup:run --only-db`,
  
  // Verify backup creation
  `kubectl exec -n laravel-prod deployment/laravel-app -- ls -la storage/app/backups/`
];

return {
  checks: safetyChecks,
  backupRequired: true,
  migrationCommand: $json.migrationCommand
};

Monitoring and Alerting Integration

Integrate monitoring and alerting into your deployment pipeline to track deployment success and application health:

// Monitoring integration function
const monitoringChecks = [
  // Check application health endpoint
  {
    type: 'http',
    url: 'https://your-app.com/health',
    expectedStatus: 200
  },
  
  // Verify database connectivity
  {
    type: 'kubectl',
    command: 'kubectl exec -n laravel-prod deployment/laravel-app -- php artisan tinker --execute="DB::connection()->getPdo();"'
  },
  
  // Check application metrics
  {
    type: 'prometheus',
    query: 'up{job="laravel-app"}'
  }
];

return {
  checks: monitoringChecks,
  alertChannels: ['slack', 'email'],
  deployment: $json.deployment
};

Troubleshooting Common Issues

GitLab CI Integration Problems

Issue: GitLab CI fails to trigger Jenkins jobs Solution: Verify that your Jenkins instance is accessible from GitLab's network. Check API tokens and ensure the Jenkins job is configured to accept remote triggers. Review firewall settings and network policies.

Issue: Authentication failures between GitLab and Jenkins Solution: Regenerate API tokens in both systems. Ensure the Jenkins user has appropriate permissions for the target job. Verify that the Authorization header format is correct in your GitLab CI configuration.

Jenkins Pipeline Failures

Issue: n8n webhook timeouts in Jenkins Solution: Increase the HTTP request timeout in your Jenkins pipeline. Implement retry logic with exponential backoff. Check n8n workflow performance and optimize slow-running nodes.

Issue: Kubernetes authentication failures Solution: Verify that the Kubernetes config file is properly stored in Jenkins credentials. Check RBAC permissions for the service account. Ensure the cluster endpoint is accessible from Jenkins agents.

n8n Workflow Issues

Issue: kubectl commands failing in n8n Solution: Ensure kubectl is installed and configured in your n8n environment. Verify that the Kubernetes config is properly mounted. Check network connectivity to your Kubernetes cluster.

Issue: Workflow execution timeouts Solution: Optimize your workflow by parallelizing independent operations. Increase node timeouts for long-running operations. Implement proper error handling to avoid hanging workflows.

Kubernetes Deployment Problems

Issue: Laravel migrations failing in production Solution: Verify database connectivity from the migration job. Check database permissions and schema lock status. Implement migration rollback procedures for failed deployments.

Issue: Rolling update failures Solution: Review resource limits and requests in your deployment manifests. Check application health checks and readiness probes. Verify that your application can handle graceful shutdowns.

Performance Optimization Tips

Pipeline Execution Speed

Optimize your CI/CD pipeline execution time by parallelizing independent stages. Run tests, security scans, and code quality checks concurrently in GitLab CI. Cache dependencies and build artifacts between pipeline runs to reduce execution time.

Configure Jenkins agents with adequate resources for build operations. Use dedicated agents for Kubernetes operations to ensure consistent performance. Implement build result caching to avoid redundant operations.

Kubernetes Resource Management

Right-size your Laravel containers based on actual resource usage patterns. Monitor CPU and memory consumption during peak loads and adjust resource requests and limits accordingly. Use Horizontal Pod Autoscaling (HPA) to handle traffic spikes automatically.

Implement resource quotas and limits at the namespace level to prevent resource exhaustion. Use node affinity rules to place Laravel pods on appropriate nodes based on your infrastructure requirements.

Database Migration Optimization

Minimize migration execution time by batching database operations and using efficient SQL patterns. Test migrations on staging environments that mirror production data volumes. Implement migration rollback procedures for critical schema changes.

Use database migration locks to prevent concurrent migrations from conflicting. Monitor migration execution time and set appropriate timeouts to prevent hanging operations.

Security Best Practices

Secrets Management

Never store sensitive information in plain text within your pipeline configurations. Use Jenkins credentials store, GitLab CI variables, and Kubernetes secrets for managing API tokens, database passwords, and other sensitive data.

Implement secret rotation policies for long-lived credentials. Use service accounts with minimal required permissions for automated operations. Regularly audit access logs and credential usage.

Network Security

Secure communication between pipeline components using TLS encryption. Implement network policies in Kubernetes to restrict pod-to-pod communication. Use private registries for container images and implement image scanning for security vulnerabilities.

Configure firewall rules to allow only necessary traffic between GitLab, Jenkins, n8n, and Kubernetes components. Use VPN or private networks for sensitive deployment operations.

Access Control and Auditing

Implement comprehensive logging and auditing for all deployment activities. Track who initiated deployments, what changes were made, and when operations occurred. Use centralized logging solutions to aggregate and analyze deployment logs.

Configure role-based access control (RBAC) at every level of your pipeline. Limit production deployment permissions to authorized personnel only. Implement approval workflows for critical production changes.

FAQ

How do I handle database migration rollbacks if something goes wrong?

Database migration rollbacks require careful planning and testing. Before running migrations, always create automated backups using Laravel's backup packages or database-native tools. Implement a rollback procedure that can restore the database to its previous state and deploy the previous application version. Test your rollback procedures regularly in staging environments to ensure they work when needed.

Your n8n workflow should include rollback logic that triggers when migration failures occur. Use Kubernetes Jobs for migrations with proper timeout and retry configurations. Always verify data integrity after rollbacks and have a manual intervention plan for complex scenarios.

Can this pipeline setup work with multiple environments like staging and development?

Absolutely! Extend your pipeline to support multiple environments by parameterizing your configurations. Use GitLab CI environment-specific variables and Jenkins parameters to target different Kubernetes namespaces and configurations. Create separate n8n workflows for each environment or use conditional logic within a single workflow to handle environment-specific requirements.

Configure different trigger conditions for each environment - automatic deployments for development branches, approval-based deployments for staging, and manual triggers for production. Use environment-specific secrets and configurations to ensure proper isolation between environments.

What happens if n8n is unavailable during a deployment?

Implement high availability for n8n by running multiple instances behind a load balancer. Configure health checks in Jenkins to verify n8n availability before triggering workflows. Implement retry logic with exponential backoff to handle temporary n8n unavailability.

Consider implementing a fallback mechanism that can execute deployment operations directly through Jenkins if n8n is unavailable. Document manual deployment procedures for emergency situations. Use monitoring and alerting to detect n8n availability issues quickly.

How do I monitor the health of the entire CI/CD pipeline?

Implement comprehensive monitoring at every pipeline stage using tools like Prometheus, Grafana, and alerting systems. Monitor GitLab CI pipeline success rates, Jenkins job execution times, n8n workflow performance, and Kubernetes deployment health. Set up alerts for pipeline failures, unusual execution times, and infrastructure issues.

Create dashboard visualizations showing pipeline performance metrics, deployment frequency, and success rates. Implement log aggregation using tools like ELK stack or Fluentd to centralize pipeline logs. Use synthetic monitoring to test your entire pipeline chain regularly.

What are the resource requirements for this setup?

Resource requirements depend on your application size and deployment frequency. For a typical setup, allocate at least 2 CPU cores and 4GB RAM for Jenkins, 1 CPU core and 2GB RAM for n8n, and appropriate resources for your Laravel application based on expected load. Consider using container resource limits and requests to ensure predictable performance.

Plan for peak deployment periods when multiple teams might be deploying simultaneously. Use monitoring data to right-size your infrastructure and implement auto-scaling where appropriate. Factor in storage requirements for build artifacts, logs, and backup retention.

How do I secure sensitive data like database credentials in this pipeline?

Use each platform's native secrets management: GitLab CI variables for build-time secrets, Jenkins credentials store for pipeline secrets, and Kubernetes secrets for runtime application secrets. Never commit sensitive data to version control or expose it in logs or pipeline outputs.

Implement secret rotation policies and use tools like HashiCorp Vault or AWS Secrets Manager for centralized secret management. Use service accounts with minimal required permissions and regularly audit access to sensitive resources. Encrypt secrets at rest and in transit throughout your pipeline.

Conclusion

Building a robust Laravel CI/CD pipeline with Jenkins, n8n, and GitLab CI provides the automation, reliability, and scalability needed for modern application deployment. This comprehensive setup ensures that your database migrations run safely in production, your deployments are consistent and traceable, and your development team can focus on building features rather than managing infrastructure.

The key benefits of this architecture include automated deployment triggers that eliminate manual intervention, visual workflow management through n8n that makes complex deployments understandable, enterprise-grade orchestration via Jenkins that provides reliability and extensibility, Kubernetes-native deployments that leverage container orchestration capabilities, and comprehensive error handling with rollback capabilities that protect production systems.

Remember that successful CI/CD implementation requires ongoing maintenance, monitoring, and optimization. Start with basic functionality and gradually add advanced features like blue-green deployments, advanced monitoring, and security enhancements as your team becomes comfortable with the pipeline.

Ready to implement this Laravel CI/CD pipeline? Start by setting up your GitLab CI configuration and Jenkins job, then gradually add n8n workflows and Kubernetes integration. Share your experience and any challenges you encounter in the comments below – the community learns best when we share our real-world implementations and lessons learned.

Subscribe to our newsletter for more DevOps and Laravel deployment guides, and don't forget to bookmark this guide for reference during your implementation journey.

Last updated 15 hours ago.

driesvints liked this article

1
Like this article? Let the author know and give them a clap!

Other articles you might like

Article Hero Image July 1st 2025

The "never" Type in PHP

Introduction There may be times when you're writing a function in PHP that you know will never retur...

Read article
Article Hero Image June 30th 2025

Check if a Signed URL is Valid in Laravel Tests

Introduction There may be times when you want to check whether a URL in your Laravel application is...

Read article
Article Hero Image June 22nd 2025

Pass a Query Builder to "whereIn" to Reduce Your DB Queries

Introduction I recently learnt about a cool feature in Laravel that allows you to pass a query build...

Read article

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.