How to Set Up Laravel Sail on Fedora

I love Fedora Linux and I love Laravel Sail. Getting them to work together took a little bit of elbow grease, so here's how I did it!

The Laravel logo and the Fedora Linux logo on either side of a white heart.
Laravel, Linux, Dev Environment
Feb 1, 2023

Even though I use macOS as my daily driver operating system, I have always loved Linux machines. Ever since I first used an Ubuntu VM back in college to write C code for my Operating Systems course, I’ve been hooked on the experience of developing software on Linux.

Recently, I decided to switch my distro from anything Debian-based (Ubuntu, Pop_OS!) to Fedora. It’s been a wonderful transition so far, but there was one issue that was causing a real pain point for me–I couldn’t get Laravel Sail working.

Well, after some time tinkering and experimenting, I have figured out a way to do it on Fedora.

How to use Laravel Sail on Fedora

Install Docker

Fedora does not come preinstalled with Docker, instead coming with a drop-in Docker replacement called Podman. I won’t get into the specific differences here, but keep reading past the tutorial if you want to know why that’s an important fact I had to learn through experimentation.

As with any major software installation, it’s a good idea to ensure your OS is up to date before starting. To that end, we can update our installed packages with the following command:

sudo dnf upgrade

Once our installed packages are up to date, we will need to install the dnf-plugins-core package and add a new dnf software repository using the config-manager plugin. This Docker repository will allow us to download the Docker container engine for Fedora:

sudo dnf install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo

Now that we have added the repository, we can use dnf to install the following packages:

  • docker-ce - The Docker container engine
  • docker-ce-cli - The CLI tool for the Docker container engine
  • [containerd.io](http://containerd.io) - A runtime for running containers
  • docker-compose-plugin - Docker Compose functionality
sudo dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin

It’s important to note for later that this installation command not only installs the specified packages but also creates a docker group on our system. This docker group has no users assigned to it yet, but we will take care of that in a later step.

Now that we have installed Docker on our system, we need to start it up and test it out! We can enable Docker with systemctl as follows:

sudo systemctl start docker

Now you should have a Docker container environment up and running on your machine. You can test it out by running Docker’s hello-world container, which will print the famous “Hello World” to your terminal if Docker is set up correctly:

sudo docker run hello-world

If you got the correct output, congratulations! You’ve installed Docker!

Configuring Docker

At this point, if you attempt to run sail up on any of your Laravel Sail projects, you may notice that Sail is still not working. It was at right about this moment that my heart sank and I realized what was going on.

To make a long story very short, I’ll paraphrase the Docker docs: when the Docker daemon starts up, it binds to a Unix socket instead of a TCP port. By default, the root user owns this Unix socket, which means that all non-root users can only access this socket via sudo. This presents a bit of a problem since Laravel Sail will attempt to run Docker without sudo. We certainly could go in and fiddle with Sail’s underpinnings, but there is a better way.

I should mention that, by continuing beyond this point, you will be permitting non-root users to run Docker without sudo. In other words, you will be granting root privileges to the user. Please, please make sure that the user you are granting these permissions to is a trusted entity!

Ok, with the security warning out of the way, here’s how we do it:

You might remember earlier on in the post I mentioned that, by installing the Docker container engine and its related packages, we also had a docker Unix group created for us. This is the group that will provide access to the Unix socket that Docker has bound itself to. All we have to do to allow a non-root user to run Docker without sudo is to add them to the docker group:

sudo usermod -aG docker $USER

Once you have run this command and assigned your user to the docker group, you will need to log out and back in for the change to take effect. Once you’ve done that, try running Docker’s hello-world container again, but this time without the sudo:

docker run hello-world

If you see the same successful output as before, congratulations! You have successfully added your user to the docker group!

Now that your user can run Docker without sudo, you will be able to run Laravel Sail as usual! If you’re coming from a Windows or macOS computer, enjoy the nice speed boost that Docker’s container engine on Linux provides!

So…what was this “Podman” you mentioned earlier?

Right, right. Podman. This is cool!

Podman touts itself as a drop-in Docker replacement; even going so far as to mimic the commands that you would typically run in Docker in its own CLI. However, there are a few key differences that make Podman a very attractive and worthwhile successor.

First, you’ll remember that one of the packages we installed earlier with dnf was the containerd.io package. Docker uses this containerd daemon to run behind the scenes and launch and manage all of the containers on your system. While typically robust, using a single daemon to manage your containers acts as a single point of failure and can cause problems if an issue arises. Additionally, this daemon requires root-level permissions (as we discussed earlier) and can pose a potential security threat if any bad actors got their hands on this daemon.

Podman does things a bit differently. Firstly, Podman considers itself a “daemonless” system. By using a technology similar to containerd called conmon which is a lightweight container runtime monitor that, importantly, doesn’t need to run as a single daemon, Podman manages to duck around the “single point of failure” concern. Additionally, Podman’s containers don’t need to run as root. Instead, they run with the exact permissions of the user that launched the container, preventing a whole laundry list of security issues (assuming the user has the correct permissions, to begin with)! Podman containers can be run as root, however, if the need arises, but that seems to be only on very rare occasions for most general use cases.

Podman and Laravel Sail

Sadly, the Laravel team has no current plan to implement a version of Laravel Sail that runs on Podman. I have a feeling that, if Podman continues to gain popularity in the containerization space, their decision might not last forever.

If you ARE interested in using Podman instead of Docker to develop and deploy your Laravel apps, there’s nothing stopping you from building up your own containerized development environment with Podman instead of Docker. Admittedly though, using Sail is so convenient, so I’m willing to wait and see if the Laravel team will ever be open to a PR to start using Podman. It’s a very interesting technology and I think there’s a lot of promise there with regards to security and performance!

What do you think? Does Podman pique your interest? Are you just happy that running Docker on Linux is a much snappier and more performant experience than Windows or macOS? I’d love to know what you think!