Install Laravel 6

Laravel is the most PHPopular framework. Learn how to install and tune Laravel 6 on fortrabbit Professional Apps.

Get ready

Please make sure to have followed our get ready guide before starting here.

Quick start

Following the fastest way to start with a fresh installation. Please scroll below for migrating an existing Laravel. Execute the following in your terminal on your local machine:

# 1. Use Composer to create a local Laravel project named like your App
$ composer create-project laravel/laravel --prefer-dist {{app-name}}
# this installs Laravel locally and will take a while

# 2. Change into the folder
$ cd {{app-name}}

# 3. Initialize a local Git repo
$ git init .

# 4. Add all files
$ git add -A

# 5. Commit files for the first time
$ git commit -m 'Initial'

# 6. Add fortrabbit as a remote
$ git remote add fortrabbit {{ssh-user}}@deploy.{{region}}.frbit.com:{{app-name}}.git

# 7. Initial push and upstream
$ git push -u fortrabbit master
# this will install Laravel on remote and take another while

# The next deployments will be much faster
# 8. Push from now on only
$ git push

Got an error? Please see the access troubleshooting. Did it work? Cool, when this is done, you can visit your App URL in the browser to see the Laravel welcome screen:

Setup

Don't stop with a plain vanilla installation. Make it yours! Check out the following topics if you have an existing Laravel installation or if you would like to setup Laravel so that you can run in a local development environment as well as in your fortrabbit App:

Setup for an existing code base

You can also push your existing Laravel installation to fortrabbit. When you already using Git, you can add fortrabbit as an additional remote, like described above under point 6. When moving from another host to fortrabbit, please also read our migration guide as well.

MySQL configuration

If you have chosen Laravel in the Software Preset when creating your App, we will automatically populate the "right" environment variables for the MySQL connection. So, you don't need to set anything! Just keep config/database.php as it is. Here is the source again for reference:

<?php
return [
    'connections'   => [
        'mysql' => [
             'driver' => 'mysql',
             'host' => env('DB_HOST', '127.0.0.1'),
             'port' => env('DB_PORT', '3306'),
             'database' => env('DB_DATABASE', 'forge'),
             'username' => env('DB_USERNAME', 'forge'),
             'password' => env('DB_PASSWORD', ''),
             'unix_socket' => env('DB_SOCKET', ''),
             'charset' => 'utf8mb4',
             'collation' => 'utf8mb4_unicode_ci',
             'prefix' => '',
             'prefix_indexes' => true,
             'strict' => true,
             'engine' => null,
         ],
    ],
];

The all CAPITAL configs above are what is going to be replaced with contents from the environment variables. For your local development setup you can populate the .env with your local database credentials. See our ENV var article as well. We are also offering an alternative more secure setup using App secrets, see here.

Emoji support

Laravel uses the utf8mb4 character set by default, which includes support for storing "emojis 🔥" in the database. You need to manually configure the default string length generated by migrations in order for MySQL to create indexes for them in your AppServiceProvider:

use Illuminate\Support\Facades\Schema;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191);
}

Database import and export

There are various use cases to export and import the database. Likely you want to:

  1. Export the database from your old webhosting
  2. Export your local database to import it to the fortrabbit database
  3. Export the remote database from fortrabbit to bring your local installation up-to-date

Read on in the MySQL article on how to do that and other tasks.

Working with artisan migrate

You might want to update database on the App with the artisan migrate command at some point. You can execute remote commands via SSH, for example:

$ ssh {{ssh-user}}@deploy.{{region}}.frbit.com 'php artisan migrate --force'
$ ssh {{ssh-user}}@deploy.{{region}}.frbit.com 'php artisan migrate:rollback --force'

If APP_ENV is set to production - which is the default - then Laravel expects --force for migrate commands. You can also add this command to your composer.json to have it run automatically every time you push changes.

"scripts": {
    "post-install-cmd": [
        "php artisan migrate --no-interaction --force",
    ],
}

With that in place, any time you deploy your code, database changes will be applied immediately. If no database changes are required, nothing happens, so it is safe to run all the time. Just make sure to test your upgrades and migrations locally first.

Logging

Per default Laravel writes all logs to storage/logs/... Since you don't have direct file access, you need to configure Laravel to write to the PHP error_log method instead.

Laravel's logging.php config allows you to define various log channels. Make sure to add the errorlog channel to the stack or simply set the default channel via ENV var:

LOG_CHANNEL=errorlog

You can now use our regular log access to view the stream.

Flare (no business association) is an error tracker for Laravel, which provides a searchable log archive and SMS, Email & Slack notifications.

Dealing with user sessions

Since you might have multiple Nodes and no persistent shared storage, you can not rely on files to keep sessions. Using the database driver is the easiest way to persist user sessions across multiple Nodes. This is a good exercise for migrations:

# Create a migration for the session table  - locally
$ php artisan session:table

# Apply the migration - locally
$ php artisan migrate

# Add, commit and push the migration file
$ git add .
$ git commit -m "session migration"
$ git push

# Run the migration on the App via SSH remote execution
$ ssh {{ssh-user}}@deploy.{{region}}.frbit.com php artisan migrate --force

Add a new ENV var SESSION_DRIVER with the value database in the Dashboard to make use of the database sessions.

Go to ENV vars for the App: {{app-name}}

Using the Object Storage for assets

fortrabbit Pro Apps have an ephemeral storage. If you require a persistent storage, for user uploads or any other runtime data your App creates, you can use our Object Storage Component. Once you have booked the Component in the Dashboard the credentials will become available via the App secrets. Using our object-storage driver reduces the configuration efforts to a minimum:

composer require fortrabbit/laravel-object-storage

To make your App access the Object Storage, open up config/filesystems.php and modify it as following:

return [
    'default' => env('FILESYSTEM_DRIVER', 'local'),
    'cloud'   => env('FILESYSTEM_CLOUD', 's3'),
    'disks'   => [
            's3' => [
                'driver' => 'object-storage'
                // no further settings required
            ],
            // other disk …
    ]
];

If you want to use the Object Storage with your fortrabbit App and a local storage with your local development setup then replace the "default" value in filesystems.php as well. Set FILESYSTEM_DRIVER in your local .env file to the value local and the environment variables in the Dashboard to the value s3. Also see the README of the repo.

Using Laravel Mix

Laravel Mix compiles JS and CSS to really small and handy files using webpack, also see the Laravel docs on this. You can use Mix locally - not on fortrabbit as there is no Node on remote. You can extend the Mix with the webpack-s3-plugin to export your minified assets to the Object Storage. This is how it works. To start, execute in your terminal:

# Get your Object Storage credentials
$ ssh {{app-name}}@deploy.{{region}}.frbit.com secrets OBJECT_STORAGE

Then put the values to your .env file and prefix the keys with OBJECT_STORAGE_. In your webpack.mix.js you load the plugin and configure it with the env vars:

const mix = require('laravel-mix');
const S3Plugin = require('webpack-s3-plugin');

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

// S3Plugin config
if (process.env.npm_config_env === 'production') {
    mix.webpackConfig({
        plugins: [
            new S3Plugin({
                // Only upload css and js
                include: /.*\.(css|js)/,
                s3Options: {
                    accessKeyId: process.env.OBJECT_STORAGE_KEY,
                    secretAccessKey: process.env.OBJECT_STORAGE_SECRET,
                    endpoint: process.env.OBJECT_STORAGE_SERVER,
                    region: process.env.OBJECT_STORAGE_REGION,
                    signatureVersion: 'v2'
                },
                s3UploadOptions: {
                    Bucket: process.env.OBJECT_STORAGE_BUCKET
                },
                // the source dir
                directory: 'public'
            })
        ]
    });
}

Back in your terminal:

# Install package via NPM
$ npm install webpack-s3-plugin --save

# Run the publish task
$ npm run production --env=production

Mind that you need to tell your source code to look for the minified CSS & JS files on the offshore Object Storage.

Another option might be to combine fortrabbit with GitHub Actions so you can have builds running over at GitHub and deploy everything along with artefacts afterwards. See our blog post.

Setting up Memcache

Make sure you enabled the Memcache Component. Then you can use the App Secrets to attain your credentials. Modify the memcached connection in your config/cache.php like so:

// locally: use standard settings
$servers = [[
    'host' => env('MEMCACHED_HOST', '127.0.0.1'),
    'port' => env('MEMCACHED_PORT', 11211),
    'weight' => 100,
]];

// on fortrabbit: construct credentials from App secrets
if (getenv('APP_SECRETS')) {
    $secrets = json_decode(file_get_contents(getenv('APP_SECRETS')), true);
    $servers = [[
        'host' => $secrets['MEMCACHE']['HOST1'],
        'port' => $secrets['MEMCACHE']['PORT1'],
        'weight' => 100
    ]];
    if ($secrets['MEMCACHE']['COUNT'] > 1) {
        $servers []= [
            'host' => $secrets['MEMCACHE']['HOST2'],
            'port' => $secrets['MEMCACHE']['PORT2'],
            'weight' => 100
        ];
    }
}

if (extension_loaded('memcached')) {
    $timeout_ms = 50;
    $options = [
      // Assure that dead servers are properly removed and ...
      \Memcached::OPT_REMOVE_FAILED_SERVERS => true,

      // ... retried after a short while (here: 2 seconds)
      \Memcached::OPT_RETRY_TIMEOUT         => 2,

      // KETAMA must be enabled so that replication can be used
      \Memcached::OPT_LIBKETAMA_COMPATIBLE  => true,

      // Replicate the data, write it to both memcached servers   
      \Memcached::OPT_NUMBER_OF_REPLICAS    => 1,

      // Those values assure that a dead (due to increased latency or
      // really unresponsive) memcached server is dropped fast
      \Memcached::OPT_POLL_TIMEOUT          => $timeout_ms,        // milliseconds
      \Memcached::OPT_SEND_TIMEOUT          => $timeout_ms * 1000, // microseconds
      \Memcached::OPT_RECV_TIMEOUT          => $timeout_ms * 1000, // microseconds
      \Memcached::OPT_CONNECT_TIMEOUT       => $timeout_ms,        // milliseconds

      // Further performance tuning
      \Memcached::OPT_NO_BLOCK              => true,
    ];
}    

return [
    // other code …
    'stores' => [
        // other code …
        'memcached' => [
            'driver'        => 'memcached',
            'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
            'servers'       => $servers,
            'options'       => $options ?? []
        ],
        // other code …
    ],
    // other code …
];

In addition, set the CACHE_DRIVER environment variable so that you can use memcached in your production App on fortrabbit. If you don't have memcached on your local machine, set the driver to file or array via .env.

Using Redis

Redis can be used in Laravel as a cache or a queue or both. fortrabbit does not offer hosted Reds, so first integrate with Redis Cloud or similar external service, then configure the redis database connection in config/database.php:

// locally: use standards
$redis = [
    'host'     => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port'     => env('REDIS_PORT', 6379),
    'database' => 0,
];

// on fortrabbit: construct credentials from App secrets
if (isset(getenv('APP_SECRETS'))) {
    $secrets = json_decode(file_get_contents(getenv('APP_SECRETS')), true);
    $redis = [
        'host'     => $secrets['CUSTOM']['REDIS_HOST'],
        'port'     => $secrets['CUSTOM']['REDIS_PORT'],
        'password' => $secrets['CUSTOM']['REDIS_PASSWORD']
        'persistent' => 1
    ];
}

return [
    // other code …
    'redis' => [
        'cluster' => false,
        'default' => $redis
    ],
    // other code …
];

If you plan on using Redis as a cache, then open config/cache.php and set the CACHE_DRIVER environment variable to redis in the Dashboard). For queue usage, see below.

Queueing

Laravel supports multiple queue drivers. One which can be used with fortrabbit out of the box is database, which simple uses your database connection as a queue. That's great for small use-cases and tinkering, but if your App handles very many queue messages you should consider Redis.

Once you've decided the queue you want to use just open config/queue.php and set default to either redis, database, sqs - or even better: set the QUEUE_CONNECTION environment variable accordingly in the Dashboard.

To run php artisan queue:work in the background, spin up a new Worker and define the artisan command as a Nonstop Job.

Using Laravel Envoy

Easy. Here is an Envoy.blade.php example:

@servers(['fr' => '{{ssh-user}}@deploy.{{region}}.frbit.com'])

@task('ls', ['on' => 'fr'])
    ls -lha
@endtask

@task('migrate', ['on' => 'fr'])
    php artisan migrate
@endtask

Then execute locally:

$ envoy run ls
$ envoy run migrate

Using artisan down

artisan down generates the file storage/framework/down, which is then checked from your App's HTTP kernel as middleware — as far as we know. Modifying files via SSH remote execution does only affect the deployment Node, not your live App. Any file changes via SSH remote exec do not affect your App.

There are at least two options to do this:

  1. Add artisan down as a post-install-cmd script in composer.json, then git push (remove the command and push again to bring it back online)
  2. Use a custom middleware and command which uses another source than a file like memcache or database

MySQL configuration with App secrets

Beside using ENV vars to set your configs, you can use fortrabbit App secrets — also see the article) - to attain credentials. Here is an example for config/database.php:

<?php
// locally: use standard settings
$mysql = [
    'driver'    => 'mysql',
    'host'      => env('DB_HOST', 'localhost'),
    'database'  => env('DB_DATABASE', 'forge'),
    'username'  => env('DB_USERNAME', 'forge'),
    'password'  => env('DB_PASSWORD', ''),
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
];


// on fortrabbit: construct credentials from App secrets
if (isset(getenv('APP_SECRETS'))) {
    $secrets = json_decode(file_get_contents(getenv('APP_SECRETS')), true);
    $mysql = [
        'driver'    => 'mysql',
        'host'      => $secrets['MYSQL']['HOST'],
        'port'      => $secrets['MYSQL']['PORT'],
        'database'  => $secrets['MYSQL']['DATABASE'],
        'username'  => $secrets['MYSQL']['USER'],
        'password'  => $secrets['MYSQL']['PASSWORD'],
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
    ];
}

return [
    'default'       => env('DB_CONNECTION', 'mysql'),
    'connections'   => [
        'mysql' => $mysql,
    ],
    'migrations' => 'migrations'
    // possible other code …
];

This configuration contains environment detection, so the App can run on your local machine with your local database, as well as with the one on fortrabbit. You can also use App secrets to store custom third party access.

Working with Redis

Redis can be used in Laravel as a cache or a queue or both. fortrabbit does not offer Redis services on it's own. To use Redis, you will need to book an external hosted Redis service. We have an article for redislabs.

  1. On the fortrabbit side, turn on the Redis extension in the Dashboard under the Apps settings.
  2. Then setup an Account with a Redis provider.
  3. Then configure the redis database connection in config/database.php:
// locally: use standards
$redis = [
    'host'     => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port'     => env('REDIS_PORT', 6379),
    'database' => 0,
];

// on fortrabbit: construct credentials from App secrets
if (isset(getenv('APP_SECRETS'))) {
    $secrets = json_decode(file_get_contents(getenv('APP_SECRETS')), true);
    $redis = [
        'host'     => $secrets['CUSTOM']['REDIS_HOST'],
        'port'     => $secrets['CUSTOM']['REDIS_PORT'],
        'password' => $secrets['CUSTOM']['REDIS_PASSWORD']
        'persistent' => 1
    ];
}

return [
    // other code …
    'redis' => [
        'cluster' => false,
        'default' => $redis
    ],
    // other code …
];

If you plan on using Redis as a cache, then open config/cache.php and set the CACHE_DRIVER environment variable to redis in the Dashboard).

Sending mail

You can not use sendmail on fortrabbit but Laravel provides a API over the popular SwiftMailer library. The mail configuration file is app/config/mail.php, and contains options allowing you to change your SMTP host, port, and credentials, as well as set a global form address for all messages delivered by the library.

Further readings

Craft CMS

Install guides

Develop & deploy

Teamwork

Platform

Stacks

Need individual help?
Learn about Company plans ›
Looking for an old article?
See the full list of articles ›
Found an error?
Contribute on GitHub ›