Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/juanVillamilEchavarria/Leo_Counter-app/llms.txt

Use this file to discover all available pages before exploring further.

The development mode of Leo Counter mounts your local source tree directly into the running containers using Docker bind mounts. This means every change you make to a PHP controller, a domain class, or a React component is visible inside the container the moment you save the file — no image rebuild required. Vite’s Hot Module Replacement (HMR) then pushes React changes to the browser without a full page refresh, giving you a tight, fast feedback loop.

Prerequisites

Docker Engine

Docker Engine installed and running. Your user must belong to the docker group on Linux.

Docker Compose v2

Docker Compose v2 (docker compose) must be available. Verified automatically by the startup scripts.

Git

Git is required to clone the repository and is also configured inside the container by dev.sh.
On Linux, if your user is not yet in the docker group run sudo usermod -aG docker $USER and open a new session before continuing.

Start the Development Environment

1

Clone the repository

git clone https://github.com/juanVillamilEchavarria/Leo_Counter-app
cd Leo_Counter-app
2

Grant execute permission to the script

chmod +x dev.sh
3

Run the development bootstrap

./dev.sh
The script validates Docker, creates the .env from .env.example if it does not yet exist, builds the Dockerfile.dev image, starts the support services (MariaDB, Redis, Mailhog, PhpMyAdmin), waits for the database health check to pass, then starts the app container, installs PHP and Node dependencies, generates the application key, runs migrations and seeders, and creates the storage symlink.
dev.sh also runs git config --global --add safe.directory /var/www/html inside the container. This lets Git commands work correctly when the source is owned by your host user but the container runs as www-data.
On Fedora, RHEL, or any system with SELinux enforcing, the script automatically applies the correct file context to the storage/ and bootstrap/cache/ directories so that the container can write to the bind-mounted paths:
sudo chcon -Rt container_file_t storage bootstrap/cache
If container_file_t is unavailable it falls back to svirt_sandbox_file_t. On systems where SELinux is disabled the step is skipped entirely.
4

Start Vite HMR in a second terminal

Open a new terminal window in the project root and run:
docker compose -f docker-compose.dev.yml exec app pnpm run dev
Vite binds to 0.0.0.0:5173 inside the container (port 5173 is forwarded to your host) and sets the HMR host to localhost so the browser connects back correctly. React components hot-reload without a full page refresh.

How Bind Mounts Work

In development, the entire project root is mounted into the container at /var/www/html:
volumes:
  - .:/var/www/html:z          # full source tree
  - dev_node_modules:/var/www/html/node_modules  # node_modules in named volume
  - ./storage:/var/www/html/storage:z            # storage separate from source
The :z suffix relabels the bind mount for SELinux on Fedora/RHEL systems. node_modules lives in a named Docker volume rather than a host directory to avoid cross-filesystem hardlink errors with pnpm’s content-addressable store. PHP reads your edited files directly — there is no copy step. Apache reloads PHP on every request in development mode, so a saved controller or domain class change is immediately live on the next browser request.

Vite HMR Configuration

vite.config.ts configures the development server to listen on all interfaces and use localhost as the HMR target:
server: {
    host: '0.0.0.0',
    port: 5173,
    hmr: {
        host: 'localhost',
    },
},
The laravel-vite-plugin entry point is resources/js/app.tsx, which bootstraps Inertia.js and the React application. When Vite detects a change, it pushes a module update over the WebSocket connection to the browser and React applies it without unmounting the component tree.

Useful Development Commands

All commands target the docker-compose.dev.yml file and run inside the app container.
docker compose -f docker-compose.dev.yml exec app composer require vendor/package
Composer writes to composer.json and composer.lock on the bind-mounted source, so the changes appear on your host immediately.
docker compose -f docker-compose.dev.yml exec app pnpm install
docker compose -f docker-compose.dev.yml exec app php artisan migrate
docker compose -f docker-compose.dev.yml exec app php artisan config:clear
Run this any time you edit .env and the application does not pick up the new values.
docker compose -f docker-compose.dev.yml exec app php artisan test
Pest (running on top of PHPUnit) is configured in phpunit.xml with an in-memory SQLite database so tests run in isolation without touching the development MariaDB instance.
docker compose -f docker-compose.dev.yml exec app php artisan tinker

Stopping and Restarting

# Stop all dev containers and remove the network
docker compose -f docker-compose.dev.yml down

# Start everything again (skips the full bootstrap)
docker compose -f docker-compose.dev.yml up -d
After a clean down, restart with up -d rather than running dev.sh again. The script is intended for the initial setup. Subsequent starts with up -d reuse the already-installed dependencies from the bind mount and named volumes.

Build docs developers (and LLMs) love