Reproducible development environment
At the beginning of the year I started a project together with a friend. After some analysis we choose to use Laravel framework because it fits our necessities.
The difficulties when working with complete mature and complete frameworks like Laravel, is managing the different dependencies, plugins and IDE settings between collaborators. To have as little as friction as possible I planned to create a reproducible development environment which we can use to start coding without too much fuss.
We are working on different OSes, but luckily both of us can easily start a container and attach to it. In this article I would like to specify how I did set-up it, and which changes I made to be able to use it with Podman (and Podman compose) on my Fedora Atomic Sway installation.
Laravel and Sail
Laravel offers Sail, a nice command line tool to manage and interact with Laravel's default Docker environment. Sail can be installed via composer inside a Laravel application root folder, so it is not really dependency free, but once installed in the project directory, allowing another developer to have only Docker installed and still be able to contribute to a project without worrying in installing additional dependencies.
A nice addition is the flag --devcontainer that can be passed to the php artisan sail:install command to automatically create a template of a .devcontainer.json file inside the project, that is automatically detected by VSCode to be open via the []Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).
Configuration
I briefly talked about the challenges of setting up some common development tool in my previous post. Here I would like to explain better which changes are needed when configuring such environment on Fedora Atomic, and why these changes are needed.
Compose.yaml
Sail assumes that Docker is used, in this case Podman is the container manager of choice, for this reason it is important to map the correct Selinux flag to the different volumes defined in compose.yaml, for example:
mysql:
image: 'mysql:8.4'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_EXTRA_OPTIONS: '${MYSQL_EXTRA_OPTIONS:-}'
volumes:
- 'sail-mysql:/var/lib/mysql:Z'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh:Z'
Compose override and environment variables
Since Podman is rootless by default, usersn mode should be specified, so that a user with root permissions with the same UID of the Host OS user can be used inside the container. This is necessary for the correct start of the Laravel's container.
The necessary changes can be written inside a docker-compose.override.yaml file:
x-podman:
in_pod: ${PODMAN_IN_POD:-false} # this is required to be false for userns_mode to work
services:
laravel.test:
user: "0:0" # ensure PID 1 is root
userns_mode: "keep-id:uid=${WWWUSER:-1000},gid=${WWWGROUP:-1000}" # keep-id | host (default)
environment:
SUPERVISOR_PHP_USER: "${SUPERVISOR_PHP_USER:-sail}"
Additionaly the SAIL_DOCKER_BINARY variable should be equal to podman, the way I configured it is by exporting the variable in my .zshrc file.
Nice addition
When creating a .devcontainer.json file it is possible to define in a declarative way extensions for our development environment in VSCode and their settings. For example I've decided to automatically install Prettier, Laravel Intellisense, Laravel Artisan and more to ensure a consistent experience between workstations and developers.
Note that by default podman compose will be used if docker-compose is not installed, while I have not experienced any issues with the sail up and VSCode Dev Containers extensions, devpod up command need docker-compose as backend to work correctly.
Conclusion
Setting up the necessary tools for coding a web application in Laravel is very simple, but some attention is needed when working with Podman and using an IDE installed via Flatpak. Fortunately modern tools like Dev Containers are able to ease the creation of a shareable workspace.
Let me know what you think about this post on Mastodon.
