Migrating an existing project from Laravel Homestead to Laravel Sail local development environment

In our organization Laravel Homestead was adopted as a default way to create a local development environment and we were hesitant to do the change to Docker based local environment. The hesitation was not coming from some particular technical reasons but it was more about the convenience and don't try to fix something that is not broken philosophy. But one of our colleagues started to experience some performance issues in his environment and the first thought was that it must be the computer configuration because the computer that he was working on was not super new and was with some older generations of processors. After some deeper investigation the final conclusion was that actual bottleneck was Vite performance and how the files are mounted and read from the host machine to the Homestead guest machine. I believe that the issue was solvable if we spent time to optimize the configurations but we have decided that this is the time when we should probably take the step and go on with the container based local development environment.

And long story short, we migrated from Homestead to Sail and the same project on the same computer became very fast and our colleague could happily continue to work on his project on the same machine.

So, as I needed to practically pass the migration process it was not hard for me to document it and share it with you. In general it is not something complex and it is not something that you cannot figure it out by yourself by following the documentation but why not provide a straightforward streamlined process that everyone that is planning to do the same can follow.

Preparation

There are a few things that you can do in order to prepare the migration.

  1. Make a backup of your database from your existing environment so you can later import it in the newly installed database service
  2. If you are using Minio for object storage make a backup of your buckets so you can later add them in your new Minio service
  3. Make sure that you have Docker installed on your computer. The easiest way to install it is by following the instructions on the official Docker documentation and install Docker Desktop. As a side note I can only mention that if you are on Linux

you have the option to install Docker Engine only without Docker Desktop. For me this is the preferred way because installed in this way you reduce the probability for performance issues because Docker Engine can run natively on Linux. If you decide to use Docker Desktop on Linux that is fine too but you need to be aware that Docker Desktop installs a virtual machine on which it is running the Docker Engine. If you want to have only Docker Engine natively on Linux but still want to have some UI to manage the containers then you can spin up Portainer container as an alternative for Docker Desktop but that is out of the scope of this article.

The instructions provided below are tested on Linux but they should work on Mac also. If you are using Windows the process is the same but you might need to do some small additional search to find out how to do the particular things on Windows.

Installing and configuring Laravel Sail

There is a clear explanation in the official documentation how to install it but here we will cover a way in which actually your existing Homestead can help you in the transition.

The first thing is to install Sail into the existing application. Let's install the composer dependency first:

composer require laravel/sail --dev

Please note that you can freely run this inside your Homestead virtual machine as you usually do with other composer dependencies.

After sail package is installed you need to run the artisan command in order to generate the compose.yml file that contains the configurations for building and running the containers. And guess what you can also run this command in your Homestead virtual machine.

php artisan sail:install

If you need to install some additional services you can do that even in this step by specifying which Sail-supported services you want to install

For example if you want to activate minio, redis and mailpit you can run:

php artisan sail:install --with=minio,redis,mailpit

This command will generate a compose.yml file that contains all the services.

Creating an alias so you can use it as a short command

By default, Sail commands are invoked using the vendor/bin/sail script that is included with all new Laravel applications, for example:

./vendor/bin/sail up

However, instead of repeatedly typing vendor/bin/sail to execute Sail commands, it is better to set an alias that allows you to execute Sail's commands more easily:

alias sail='sh $([ -f sail ] && echo sail || echo vendor/bin/sail)'

As a Mac or Linux user to make sure this is always available, you may add this to your shell configuration file in your home directory, such as ~/.zshrc or ~/.bashrc, and then restart your shell.

Once the shell alias has been configured, you may execute Sail commands by simply typing sail. The instructions in this post will assume you have configured this alias.

Adjusting the .env file

Some adjustments need to be done before you spin up the containers with sail in order to be sure that everything works. If you are using MySQL as a database change the value of the DB_HOST variable:

DB_HOST=mysql 

If you are using Redis as a cache driver change the value of the CACHE_DRIVER variable:

CACHE_DRIVER=redis

If you are using Minio you might want to check the Port and adjust it in your values in your .env values related to the object storage connection. The Minio instance that Sail creates listens on Port 9000, so you need to add:

AWS_ENDPOINT=http://minio:9000
AWS_URL=http://localhost:9000/bucketname

It is also important to know that Sail is reading the variables from .env file and it is using them during the creation of the containers. If you are migrating an existing project you do not need to change anything but optionally if you want to make some changes to the database password, database name, database username etc. it is the right moment to do that.

Setting the domain in your hosts file

Check your APP_URL variable in your .env file. It should be something like:

APP_URL=http://myapp.test

In your /etc/hosts file add the following:

127.0.0.1   myapp.test

So once your Sail containers are up you can access your application over myapp.test domain locally.

Starting and stopping Sail

Now you are ready to start the Sail containers. Make sure that you are in the root directory of the project in your terminal and run:

sail up

or

sail up -d

if you want Sail to run in the background.

To stop your Sail containers you can run:

sail stop

Prepare and run your Laravel application

To fully load the Laravel application you need to do the following steps.

Migrate the database and at the same time check if the database connection works.

sail artisan migrate

Run the database seeders if you have them.

sail artisan db:seed

If you are actively using a front-end framework install your npm packages.

sail npm install

Run your development server if you are using a front-end framework like VueJS or React.

sail npm run dev

Now if you type in myapp.test in your browser you should be able to reach your application.

Importing your data

We mentioned at the top that you should prepare a database backup and a backup of your files from your Homestead's Minio instance. Now it is time to import them.

For importing your database you can use any database client that you are using during development. Just make sure to check the official Laravel Sail documentation for instructions of how to connect.

However for importing the files in the newly created Minio instance things are not straightforward. As you know the recent Community version of the Minio UI app does not provide any interface for managing files and permissions. Because of that we must utilize "mc" the Minio's official command line tool to do the job.

We first need to install "mc" on the local machine. To do that you can run the following command:

curl --progress-bar -L https://dl.min.io/aistor/mc/release/linux-amd64/mc \
--create-dirs \
-o $HOME/aistor-binaries/mc

Once 'mc' is installed we need to create an alias so we can use that alias to connect to our Sail Minio instance.

mc alias set myapp_minio http://localhost:9000 sail password

Please note that in the command above "sail" is the default username and "password" is the default password that Sail creates during the creation of the Minio container.

Once we have the alias we can use it and start creating buckets as a first step. To create a private bucket run:

mc mb myapp_minio/bucketname

For the name of your bucket it is convenient to check what you have in your .env file settings and use the same.

To create a public bucket you can run:

mc mb myapp_minio/public-bucketname

Make it public after that:

mc anonymous set public myapp_minio/public-bucketname

Finally you can copy your files from the local machine to the appropriate bucket by using the following command:

mc cp --recursive /path/to/local/folder/ myapp_minio/bucketname/