A Guide To Continue Developing Laravel Application Using Docker With Sail, WSL2 (Ubuntu), and VS Code

Arung Isyadi
7 min readDec 31, 2023

--

I don’t know if you’ve ever been in a similar situation, but this is my story. I hope this story can assist anyone on a tight schedule or wishing to use Docker for a legacy project. Also, the article would be my documentation that I believe I can use in the future.

An old-time client asked me to have his legacy projects (one using Laravel 8 and the other using native PHP 5.6) containerized using Docker. So like most developers out there (me especially), I googled for any article regarding implementing Docker to an existing project. There is one provided by Laravel, but it’s very short and it doesn’t inform any usage of WSL2. I searched around a little bit more only to find several articles here and there that I had to combine to get things worked. So I thought, I’d better make these findings into a single article that will help me in the future setting up this kind of project. Also, the article will be useful if I am leading a team that will need a document to set things up on their localhost. If you find this article is helping you then it will be a blessing for me. I’m not a master of Docker, so any critics or inputs are most welcome.

This article will not go in-depth regarding installing WSL2 and Docker. But I will list here those requirements as one of the steps. So you know which steps needed to be executed first and hopefully, things are working great for you as it is for mine.

Installing and Setting Up WSL2

There is official documentation to do this that you can find at https://learn.microsoft.com/en-us/windows/wsl/install, A few notes that I would like to say on this article are:

  1. Do not use the wsl --install command, install the WSL2 using the Microsoft Store instead.
  2. It’s best to restart your PC after all the WSL2 distros you would like to use have been installed. It worked like a charm to me.
  3. If you’re having an issue with Hyper-V because you’re using Windows Home Edition like me, use this article to help you out.
    https://wethegeek.com/enable-hyper-v-in-windows-11-home/

Now, open the WSL2 distro of your choice (I’m using the WSL2 Ubuntu Distro, so the command or file names might be different). You will be on the home directory (~ or /mnt/home/[your-username]). Do these steps now (You can do it later actually. But for me, it’s better to set things up before we jump to the main event).

Open your .bashrc file nano .bashrc

Enter this line of code at the bottom line of the file.

alias sail=’[ -f sail ] && sh sail || sh vendor/bin/sail’

This will create an alias for “vendor/bin/sail”, so you don’t need to type ./vendor/bin/sail to use Sail commands.

Installing and Setting Up Docker

Just follow the instructions here
https://docs.docker.com/desktop/wsl/
It has a very complete step-by-step instruction and there is nothing more that I would like to add as notes.

Clone The Repository and Activate Sail

Now clone your repository to your WSL2 Distro (Ubuntu), I’m using GitHub for this example. Make sure you’re in the home root directory by running

cd ~

Then clone the repository using the command below.

git clone https://github.com/[username]/[repository-name].git

You will be asked for your GitHub username and password. Use your GitHub username and use your personal access token as the password.

Now go to the newly cloned repository, if you are using a specific branch (like I did, I used “docker”) you need to checkout to that branch before continuing.

git checkout [branch-name]

Next, run the command below to install all the packages you need (including Laravel Sail).

docker run --rm \
-u "$(id -u):$(id -g)" \
-v "$(pwd):/var/www/html" \
-w /var/www/html \
laravelsail/php83-composer:latest \
composer install --ignore-platform-reqs

You will need to match the “laravelsail/phpXX-…” to match the PHP version you’d like to use.

After all the composer packages installation is complete.

Copy your .env.example file to .env, generate the Laravel key, and then open it and adjust the parameters. The parameters will be updated once you install Laravel Sail, but it’s OK several parameters are still going to be needed. For example, mine is using MailTrap so I will need the credentials to be on the .env file.

cp .env.example .env
php artisan key:generate
nano .env

Now run the command below to ensure you’re using the most updated Laravel Sail.

composer require laravel/sail --dev

Next, we want to install the Laravel Sail to our existing app. Run the command below. Since we will be using VS Code, we want to use the .devcontainer file to sync the VS Code with our container better.

php artisan sail:install --devcontainer

Now we’ll need to open the file in VS Code to set up several settings before we can fully run a containerized Laravel. Open your WSL2 CLI, and type the commands below.

cd [your-repository-name]
code .

After the VS Code has been opened from WSL2, open up docker-composer.yml and .env in the newly opened VS Code.

docker-compose.yml

You will find several variables there, I won’t cover them all in this article (maybe will be covering them in another article) but I will cover several of them that for me a bit essential because I still have Laragon running on my localhost.

  1. ${APP_PORT:-80}: This is the port that will be used for the app to be accessed through a web browser like Chrome or Firefox, it will take its value from “APP_PORT” in .env or else will use port 80. Change it to anything you like, I am going to use port 81 so I will put “APP_PORT=81” in my .env file.
  2. ${FORWARD_DB_PORT:-3306}: This is the forwarded port for the MySQL container on this app. You will want to change this if you still have another MySQL server running, also you will want to keep the port noticed in case you want to use MySQL tools like HeidiSQL or others.

Now, let’s check the .devcontainer folder. Inside it, there is a devecontainer.json file. Edit is as how you see it fits you. I have some recommendations though, copy the code below to the devcontainer.json file and save it.

// https://aka.ms/devcontainer.json
{
"name": "Existing Laravel App",
"dockerComposeFile": [
"../docker-compose.yml"
],
"service": "laravel.test",
"workspaceFolder": "/var/www/html",
"customizations": {
"vscode": {
"extensions": [
"DEVSENSE.phptools-vscode"
// "mikestead.dotenv",
// "amiralizadeh9480.laravel-extra-intellisense",
// "ryannaddy.laravel-artisan",
// "onecentlin.laravel5-snippets",
// "onecentlin.laravel-blade"
],
"settings": {
"php.format.codeStyle": "PSR-2"
}
}
},
"remoteUser": "sail",
"postCreateCommand": "chown -R 1000:1000 /var/www/html 2>/dev/null || true"
// "forwardPorts": [],
// "runServices": [],
// "shutdownAction": "none",
}

Now edit your vite.config.js file to be like the one below.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
server: {
https: false,
hmr: {
host: 'localhost'
}
}
});

Now run the command below on your WSL2 CLI.

sail up

Open the VS Code terminal by hitting CTRL+~ and run the below command.

sail npm i && sail npm run dev

Continue Your Development

At this stage, you are already able to continue your app development using Docker and Laravel Sail. You can modify your file and push updates to the repository as you normally do. But there are (sometimes) requirements to update the file directly on the container. You can do it by reopening the VS Code inside the container, just remember that your container won’t recognize sail commands.

To reopen VS Code inside the container check on the left bottom corner of your VS Code there is a blueish button saying “WSL: [Your WSL2 Distro]. Click it and choose “Reopen in Container”.

Finish

The article has come to an end. Hopefully, it helps you and everyone else that needs it. I welcome all critiques and feedback, let’s have a good discussion if you see there is a better way to do this.

--

--

Arung Isyadi

Tech Leader | Scrum Master | Seasoned Engineering Team Lead | AI/ML Enthusiast