Category: DevOps

  • Setting up a simple Bitbucket pipeline for a Laravel application

    If you’re using Bitbucket, then using their Pipelines feature as your CI/CD tool is a natural choice. Here’s a pipeline script that I use as a starting point for my new projects.

    For every pull request created, the pipeline will perform the following tasks:

    • Running your test suite.
    • Ensuring code standards are adhered to.
    • Running static analysis against your codebase.

    The pipeline

    Bitbucket Pipelines uses a Docker container under the hood, and is configured by placing a bitbucket-pipelines.yml file in the root folder of your repository.

    I’ve got a sample configuration file below, that works for a relatively standard Laravel application.

    image: php:7.4-fpm
    pipelines:
      pull-requests:
        '**':
          - step:
              name: Run tests
              services:
                - docker
              caches:
                - composer
                - node
              script:
                - apt-get update
                - apt-get install -y unzip libzip-dev libpng-dev zip git
                - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
                - docker-php-ext-configure zip
                - docker-php-ext-install zip bcmath pcntl gd
                - php -r "file_exists('.env') || copy('.env.example', '.env');"
                - composer install --no-progress --no-suggest --prefer-dist --no-interaction
                - vendor/bin/phpcs --standard=PSR2 -n app
                - apt-get update && apt-get install -y curl gnupg gnupg2 && curl -sL https://deb.nodesource.com/setup_10.x | bash - && apt-get install -y nodejs
                - php artisan key:generate
                - npm install
                - npm run dev
                - php artisan test --parallel
                - vendor/bin/phpstan analyse --memory-limit=512M

    Lessons learned

    • The earlier you can get these steps automated, the better. Pro tip: do it BEFORE you hire your first developer!
    • Bitbucket Pipelines is a pain to configure. But it’s really cheap if you’re already using Bitbucket.

    End

    What do you think about my pipeline setup? Would you do anything differently?

  • Early stage DevOps strategy for launching your Laravel application

    At the early stages of a tech startup, the amount of DevOps work required is very limited. This makes it unfeasible to get an expert to handle your server and application setup.

    A more likely scenario is that you, as tech lead, will need to handle this yourself.

    Here’s the strategy I’ve used for many projects over the years. It’s kept the Mindbeat platform running from 2018 till 2022 with 100% uptime (it’s easier than you think).

    Simple application server setup

    The strategy

    • Use managed services so that your only point of failure is your application server.
      Since we use AWS – I used Amazon SQS and Amazon RDS as our managed queue and database.
    • Use a server management tool in a way that allows you to reproduce your application servers. I use Laravel Forge.
    • Use a zero-downtime deployment tool in a way that allows you to deploy your latest release at the click of a button. I use Laravel Envoyer.
    • Set up 2 (identical) application servers to host your application. 2 is infinitely better than 1, and slightly worse than 3. Setting up 2 servers from day 1 means you’ll be ready to horizontally scale to any amount of servers.
    • Set up load balancing using Cloudflare.

    When to use this strategy

    • When you’re bootstrapped, and don’t have a DevOps resource
    • When your application is monolithic, or is close to that.
    • When you can anticipate increased usage and can plan ahead to add more servers to handle the load. (I’ve never had to do this!)

    When not to use this strategy

    • When your application is spread across many services
    • When your application needs to handle huge spikes in traffic
    • When your architecture can’t be arranged to only have a single-point of failure that is unmanaged.

    Lessons learned

    • Grant at least one other developer on your team full access to your application servers. You’ll have an amount of team coverage in case you’re ever unreachable and something is breaking.
    • Spend some time to ensure that Cloudflare’s load balancing features can gauge the health of you application server.
    • Configure Cloudflare to automatically route traffic away from an unhealthy application server.
    • Ensure that “Session affinity” is set to “on” in Cloudflare – so that logged in users are routed to the same application server every time.
    • Don’t bother upgrading your servers. Provision fresh servers and keep your old servers running until you can do a safe changeover.

    End

    This setup has some hard requirements when it comes to using managed services, and requires your application to be monolithic.

    In return you get a hassle-free, developer-friendly setup that you can rely on.