Wondering how to configure Tugboat for a Laravel project? One of the claims of Laravel is “One Framework, Many Flavors”, so every Laravel project tends to have different requirements. You may need to do some customizing, but this should get you started.

The following documentation assumes you are using Composer to manage your Laravel project, and that you are using Blade templates styled with Tailwind CSS; as frontend tooling, your choice is Vite.

If you are using Livewire or Inertia, or any other option, it should be pretty similar.

Configuring Laravel

A common practice for managing Laravel settings is to leave sensitive information, such as database credentials, in environment variables. For development, you might have a an or .env.example file on git.

This pattern works very well with Tugboat. It lets you keep a Tugboat-specific set of configurations in your repository, where you can copy it into place with a configuration file command.

So let’s create a .tugboat/.env.tugboat with your variables, and customize it for tugboat. You might want to base it on your production values, or, less common, your dev environment values as a basis. The choice is yours. But for sure you want to configure these values:






  • The APP_URL will use an environment variable for setting the url host.
  • The LOG_CHANNEL will be the standard output, as this way we will see it more easily on the Tugboat UI or via the Tugboat CLI without needing to open a shell on it.
  • The DB_* variables will depend on the database engine you pick on your config.yml, this assumes mysql.
  • The MAIL_* variables will point to tugboat SMTP server, so the mails are never delivered but instead captured and visible on your preview dashboard.
  • For files and queue system, you will use the local filesystem and database respectively, but more complex options are also supported.
  • You could also set your APP_KEY here with ${TUGBOAT_REPO_ID}.

See Enviroment variables for more options on environment variables available.

Configure Tugboat

The Tugboat configuration is managed by a YAML file at .tugboat/config.yml in the git repository. Here’s a basic configuration you can use as a starting point, with comments to explain what’s going on:

# Default Laravel 11 Tugboat starter config.
  # What to call the service hosting the site.
    # This uses PHP 8.3.x with Apache: update to match your version of PHP.
    image: tugboatqa/php:8.3-apache

    # Set this as the default service. This does a few things
    #   1. Clones the git repository into the service container
    #   2. Exposes port 80 to the Tugboat HTTP proxy
    #   3. Routes requests to the preview URL to this service
    default: true
    # Wait until the mysql service is done building.
    depends: database

    # A set of commands to run while building this service
      # Commands that set up the basic preview infrastructure
        # Install opcache and mod-rewrite.
        - docker-php-ext-install opcache
        - a2enmod headers rewrite
        # Install node
        - apt-get update
        - apt-get install -yq ca-certificates curl gnupg
        - mkdir -p /etc/apt/keyrings
        - curl -fsSL | gpg --dearmor -o
        - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] nodistro main" |
          tee /etc/apt/sources.list.d/nodesource.list
        - apt-get update
        - apt-get install -yq nodejs
        # Copy the tugboat .env we created before
        - cp "${TUGBOAT_ROOT}/.tugboat/.env.tugboat" "${TUGBOAT_ROOT}/.env"
        # Link the document root to the expected path. This example links
        # /public to the docroot
        - ln -snf "${TUGBOAT_ROOT}/public" "${DOCROOT}"
        # Ensure storage permissions
        - chgrp -R www-data "${TUGBOAT_ROOT}/storage"
        - find "${TUGBOAT_ROOT}/storage" -type d -exec chmod 2775 {} \;
        - find "${TUGBOAT_ROOT}/storage" -type f -exec chmod 0664 {} \;
        # Composer install
        - composer install --optimize-autoloader
        # Generate the random key if you didn't set APP_KEY before.
        - php artisan key:generate
        # Install the workers
        - mkdir -p /etc/service/webserver
        - cp .tugboat/etc/service/webserver/run /etc/service/webserver/run
        - chmod +x /etc/service/webserver/run
        # Clear caches.
        - php artisan config:cache
        # Generate the db structure with some data. Here you have several choices:
        # 1. If you have seeders on your project, you might just run migrate with --seed.
        # - php artisan migrate --seed
        # 2. You might want just the structure without any test data.
        # - php artisan migrate
        # 3. Or you might load a database dump from somewhere else. That's up to you.
        # If that's your case you might want to do that in the database update step though.
        - php artisan migrate --seed
        # Compile vite templates
        - npm install
        - npm run build
        - composer install --optimize-autoloader
        # Clear caches.
        - php artisan config:cache
        # Run any pending migrations. This will ensure your data has the last
        # migrations applied.
        - php artisan migrate --force
        # Compile vite templates
        - npm install
        - npm run build

    # Use the latest available version of MariaDB by not specifying a
    # version
    image: tugboatqa/mariadb:10.5

Configuring queue runners

At the end of the init step, you can see that we are copying a .tugboat/etc/service/webserver/run file and marking it as executable. This is a quick way of having a background process.

In this .tugboat/etc/service/webserver/run we are going to run the default worker of your Laravel application:

su -s /bin/bash -c 'cd ${TUGBOAT_ROOT} && php artisan queue:work' www-data

If you want to customize your queue runners, have separate runners per queue, or any other customization, read Running a Background Process for more information.

Want to know more about something mentioned in the comments of this config file? Check out these topics:

Start Building Previews!

Once the Tugboat configuration file is committed to your git repository, you can start building previews!