Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Vagrant for Reproducible Dev Environments

By Kokil Thapa | Last reviewed: September 2026

Vagrant for Reproducible Dev Environments solves a problem every PHP team hits eventually. One developer runs PHP 8.3 on Ubuntu 24.04. Another still uses XAMPP on Windows with PHP 8.1. A third skips Redis locally and wonders why queues fail in staging. The app works on one machine and breaks on another. A reproducible build mindset starts at the laptop, not only in CI. Vagrant wraps a virtual machine in a single Vagrantfile so everyone boots the same OS, extensions, and services with two commands.

What is Vagrant for Reproducible Dev Environments?

Vagrant is a CLI tool from HashiCorp. It sits on your host OS and talks to a hypervisor such as VirtualBox, VMware, or Hyper-V. You describe one VM in a Vagrantfile. Vagrant downloads a base box, boots the VM, mounts your project folder, and runs provisioning scripts.

The result is a disposable computer inside your computer. Your Laravel code stays on the host filesystem. PHP-FPM, Nginx or Apache, MySQL, and Redis run inside the guest. When something breaks, you destroy the VM and rebuild. That beats hours of manual package installs.

I still reach for Vagrant on client projects where Docker is overkill or blocked by corporate policy. It also helps freelancers who must match a client's exact Linux stack without reformatting their personal laptop. For full-stack delivery that includes server setup, see our Linux system administration service.

Vagrant Dev Environment StackHost OS (macOS / Windows / Linux)Project folder synced to /vagrantVagrant CLIHypervisorVagrantfileGuest VM (Ubuntu 24.04)PHP 8.3 · Nginx · MySQL 8.4 · RedisProvisioned on every vagrant up
How Vagrant for Reproducible Dev Environments layers host tools, a hypervisor, and a provisioned guest VM

Core files you commit to Git

  • Vagrantfile — Ruby DSL defining box, network, synced folder, and provisioner
  • provision.sh or Ansible playbooks — idempotent install steps
  • .env.example — database host often 127.0.0.1 with forwarded port
  • Optional README section with vagrant up and vagrant ssh commands

Never commit secrets. Share box version pins and package lists instead. That matches how we treat Ubuntu environment variables on production servers.

How do you install Vagrant and create your first VM?

Install a hypervisor first. VirtualBox is free and works on all major host OSes. Download Vagrant from HashiCorp, then verify both tools from your terminal.

# macOS with Homebrew
brew install --cask virtualbox vagrant

# Verify
vagrant --version
VBoxManage --version

Initialize a project directory and bring the VM online:

  1. mkdir my-laravel-app && cd my-laravel-app
  2. vagrant init ubuntu/jammy64 — creates a starter Vagrantfile
  3. Edit the Vagrantfile with your PHP stack (see next section)
  4. vagrant up — downloads the box on first run, boots, provisions
  5. vagrant ssh — shell into the guest as user vagrant

First boot can take ten to twenty minutes on a slow connection. The box image caches locally. Later runs finish in under a minute if you only restart an existing VM.

Official install steps live in the HashiCorp Vagrant installation docs. VirtualBox hardware requirements are documented on virtualbox.org.

How do you configure a Vagrantfile for Laravel and PHP 8.3?

Below is a practical Vagrantfile for Laravel 13 on PHP 8.3 with MySQL 8.4 LTS. Laravel 13 requires PHP 8.3 or higher. Laravel 12 still runs on PHP 8.2 if you maintain older apps.

# Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/jammy64"
  config.vm.hostname = "laravel-dev"

  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "forwarded_port", guest: 3306, host: 33060, host_ip: "127.0.0.1"
  config.vm.network "forwarded_port", guest: 6379, host: 63790, host_ip: "127.0.0.1"

  config.vm.synced_folder ".", "/vagrant", type: "virtualbox"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2
  end

  config.vm.provision "shell", path: "provision.sh"
end

Pair it with an idempotent shell provisioner:

#!/usr/bin/env bash
set -euo pipefail

export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y software-properties-common curl unzip git

add-apt-repository -y ppa:ondrej/php
apt-get update
apt-get install -y nginx mysql-server-8.4 redis-server \
  php8.3-fpm php8.3-cli php8.3-mysql php8.3-redis php8.3-xml \
  php8.3-mbstring php8.3-curl php8.3-zip php8.3-gd php8.3-intl

curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

cd /vagrant
if [ ! -f .env ]; then cp .env.example .env; fi
sudo -u vagrant composer install --no-interaction
sudo -u vagrant php artisan key:generate --force
sudo -u vagrant php artisan migrate --force

On the host, open http://localhost:8080. Your .env should use DB_HOST=127.0.0.1 and DB_PORT=33060 because MySQL listens inside the guest but forwards to the host loopback.

For booking platforms like Adventure Third Pole Trek, matching queue and cache services locally prevents silent production bugs. Validate JSON API payloads during development with our JSON formatter tool.

Vagrant Daily Workflowvagrant upBoot VMProvisionInstall stackCode syncHost to guestvagrant sshDev shellInside the guest VMcomposer install · php artisan migratephp artisan queue:work · npm run build on hostvagrant halt · vagrant destroy when resetting
Daily Vagrant commands that keep Laravel development reproducible across the team

Where to run Composer and Node

Run Composer and Artisan inside the VM. That guarantees the PHP binary matches production. For front-end assets, many teams run Node.js 26 LTS on the host with Vite 8.x because GUI file watchers perform better outside VirtualBox shared folders.

If you must run npm inside the guest, switch the synced folder to NFS on macOS or Linux. VirtualBox shared folders are slow with thousands of small files. I have seen npm install take five times longer on a default mount.

How does Vagrant compare to Docker for local development?

Both tools aim at reproducibility. They differ in isolation model, boot time, and mental overhead. Docker runs containers on a shared kernel. Vagrant runs full VMs with their own kernel and init system.

CriteriaVagrantDocker / Sail
IsolationFull VM, closest to bare metal VPSContainer processes, lighter weight
Boot timeMinutes on first provisionSeconds once images exist
Resource use2 GB RAM typical minimumOften lower per service
Production parityExcellent for Apache + PHP-FPM stacksExcellent for microservices
Windows frictionVirtualBox or Hyper-V setupDocker Desktop licensing concerns
Team onboardingvagrant up if hypervisor alloweddocker compose up or Sail

Read our deeper comparison in Laravel Sail vs Docker Compose for local dev and Docker Compose for local Laravel. Choose Vagrant when you need systemd services, custom kernel modules, or a near-copy of an Ubuntu VPS. Choose Docker when you want fast resets and many isolated services.

Vagrant VM vs Docker ContainersVagrant PathGuest kernel + systemdFull LAMP / LEMP stackMatches VPS closelyDocker PathShared host kernelOne container per serviceFast rebuild cyclesPick based on team skill and hosting target
Vagrant full-VM isolation compared with Docker service containers for reproducible local stacks

How do you share Vagrant setups across a development team?

Reproducibility dies when the Vagrantfile lives on one laptop. Commit it beside application code. Tag box versions explicitly instead of relying on a moving ubuntu/jammy64 pointer.

Team checklist

  1. Pin config.vm.box_version in the Vagrantfile
  2. Document required host RAM and VirtualBox extensions
  3. Add a Makefile or composer run dev:up script wrapping Vagrant commands
  4. Run the same migrations in provision and CI — see database migrations in team environments
  5. Maintain a staging box that mirrors production — our guide on staging that mirrors production covers the same principles

On legal-tech portals such as Mijar Law Associates, document upload paths and PHP upload limits must match across dev machines. A shared Vagrant provisioner sets upload_max_filesize once for everyone.

For Symfony apps, environment-specific config patterns in Symfony multi-environment config translate directly into Vagrant env files.

Private boxes for advanced teams

Pack a golden VM with vagrant package. Upload the .box file to internal storage. Point teammates to that artifact. Updates roll out by publishing box version 1.0.1 and bumping the Vagrantfile pin. This resembles immutable images in preview environments for every PR, but at the workstation layer.

What are the most common Vagrant mistakes on real projects?

Most failures are boring infrastructure issues, not Ruby syntax errors. I have hit each of these on production-adjacent client work.

  • Non-idempotent provisioners — appending the same line to php.ini on every vagrant up breaks PHP. Use guarded blocks or Ansible.
  • Wrong synced folder type on Windows — enable Guest Additions or switch to SMB/NFS where supported.
  • Port collisions — another MySQL instance on the host grabs 3306. Forward guest ports to high host ports as shown above.
  • Drift between Vagrant and production — PHP 8.5 on VPS but 8.1 in an old box causes subtle type errors. Rebuild boxes when upgrading production.
  • Skipping vagrant destroy tests — if only vagrant reload works, new hires will fail on fresh clones.

HashiCorp documents provisioner types in the official Vagrant provisioning guide. Treat that page as the source of truth for shell, Ansible, and Docker provisioners.

Vagrant Troubleshooting Decision TreeSomething broke?Slow file syncTry NFS / SMBPort in useChange host portProvision errorRead guest logStill stuck?vagrant destroy && vagrant upReproducible Dev Environments survive when reset paths are documented
Troubleshooting flow for Vagrant for Reproducible Dev Environments when sync, ports, or provisioning fail

When Vagrant is not the right fit anymore, migrate incrementally. Container guides like local Laravel dev with Sail and Docker help teams transition without stopping feature work. Infrastructure-as-code readers should also review Terraform workspaces and environments for cloud parity.

Key Takeaways

  • Commit a Vagrantfile plus idempotent provision scripts so every developer boots the same PHP, web server, and database versions.
  • Forward database and Redis ports to the host loopback so GUI clients and host-side tests connect safely.
  • Pin box versions and test vagrant destroy && vagrant up on a clean clone before onboarding new teammates.
  • Run Composer and Artisan inside the guest; run Node/Vite on the host if VirtualBox shared-folder performance hurts builds.
  • Choose Vagrant for full-VM parity with Ubuntu VPS hosting; choose Docker when you need faster container cycles.
  • Document troubleshooting and resource requirements — RAM, CPU, and hypervisor choice — in the project README.

People Also Ask

Is Vagrant still used in 2026?

Yes. Docker dominates new greenfield projects, but Vagrant remains common where teams want a full Linux VM that mirrors a DigitalOcean or EC2 VPS. Legacy PHP shops, agencies with mixed Windows/macOS hosts, and regulated environments that restrict Docker Desktop still standardize on Vagrant.

Can Vagrant run without VirtualBox?

Yes. Vagrant supports VMware Desktop, Hyper-V on Windows, and libvirt/KVM on Linux. VirtualBox is simply the most common free option. Pick the provider your team already licenses or supports.

How much RAM does a Vagrant Laravel box need?

Allocate at least 2 GB to the guest for a single Laravel app with MySQL and Redis. Complex eCommerce stacks with Elasticsearch or multiple PHP versions benefit from 4 GB. Host machines with 8 GB total RAM will struggle; 16 GB is comfortable for host IDE plus guest services.

Does Vagrant replace production deployment tools?

No. Vagrant solves local reproducibility only. Production still needs Deployer, GitLab CI, or similar pipelines. The win is fewer "works on my machine" bugs before code reaches staging. Pair local Vagrant boxes with the same PHP extensions you enable on the server.

Ship consistent dev boxes before your next release

Vagrant for Reproducible Dev Environments is not flashy. It is dependable. One Vagrantfile, one provision script, and a README section can save days of onboarding friction on Laravel, Symfony, or WordPress projects. If your team needs a standardized stack, staging parity, or help moving from ad-hoc XAMPP installs to something maintainable, review our custom software development and support and maintenance offerings. You can also browse the portfolio for examples of production apps that started with disciplined local setups. When you are ready to talk through your stack, contact us with your current OS mix and target PHP version.

Frequently Asked Questions

Vagrant is a CLI tool from HashiCorp that sits on your host OS and talks to a hypervisor such as VirtualBox, VMware, or Hyper-V. You describe one VM in a Vagrantfile. Vagrant downloads a base box, boots the VM, mounts your project folder, and runs provisioning scripts. Your Laravel code stays on the host filesystem while PHP-FPM, Nginx or Apache, MySQL, and Redis run inside the guest. When something breaks, destroy the VM and rebuild. That beats hours of manual package installs and stops one developer on PHP 8.3 and another on XAMPP from diverging.

Install a hypervisor first. VirtualBox is free and works on all major host OSes. Download Vagrant from HashiCorp, then verify both tools from your terminal with vagrant --version and VBoxManage --version. macOS teams can run brew install --cask virtualbox vagrant. Initialize with vagrant init ubuntu/jammy64, edit the Vagrantfile with your PHP stack, run vagrant up to download the box and provision, then vagrant ssh to shell in. First boot can take ten to twenty minutes on a slow connection. The box image caches locally and later restarts finish in under a minute.

Set config.vm.box to ubuntu/jammy64 and forward guest port 80 to host 8080, MySQL 3306 to host 33060, and Redis 6379 to host 63790 on 127.0.0.1. Allocate at least 2 GB RAM and 2 CPUs in the VirtualBox provider block. Pair the file with an idempotent provision.sh that installs Nginx, MySQL 8.4 LTS, Redis, PHP 8.3-FPM with Laravel extensions, and Composer. Laravel 13 requires PHP 8.3 or higher; Laravel 12 still runs on PHP 8.2. Run composer install, php artisan key:generate, and migrate inside provision. Open http://localhost:8080 on the host.

Yes. Docker dominates new greenfield projects, but Vagrant remains common where teams want a full Linux VM that mirrors a VPS.

Yes. Vagrant supports VMware Desktop, Hyper-V on Windows, and libvirt/KVM on Linux. VirtualBox is simply the most common free option.

Allocate at least 2 GB to the guest. Complex stacks with Elasticsearch or multiple PHP versions benefit from 4 GB; hosts with only 8 GB total RAM will struggle.

Both tools aim at reproducibility but differ in isolation model, boot time, and mental overhead. Docker runs containers on a shared kernel with second-scale boots and lower per-service overhead. Vagrant runs full VMs with their own kernel, closest to a bare-metal VPS, with minutes-long first provision and roughly 2 GB RAM minimum. Vagrant suits systemd services, custom kernel modules, and Apache plus PHP-FPM stacks mirroring Ubuntu VPS hosting. Docker and Laravel Sail fit fast resets and many isolated microservices. Team onboarding is vagrant up when the hypervisor is allowed, versus docker compose up or Sail.

Commit the Vagrantfile beside application code because reproducibility dies when it lives on one laptop. Pin config.vm.box_version explicitly instead of relying on a moving ubuntu/jammy64 pointer. Document required host RAM and VirtualBox extensions in the README. Add a Makefile or composer run dev:up script wrapping Vagrant commands. Run the same migrations in provision and CI. For advanced teams, pack a golden VM with vagrant package, upload the .box file to internal storage, and bump the Vagrantfile pin when publishing version 1.0.1. A shared provisioner also sets PHP upload limits once for everyone on document-heavy portals.

Non-idempotent provisioners that append the same line to php.ini on every vagrant up break PHP. Use guarded blocks or Ansible instead. Wrong synced folder type on Windows requires Guest Additions or SMB or NFS where supported. Port collisions happen when host MySQL grabs 3306, so forward guest ports to high host ports like 33060. Drift between Vagrant and production, such as PHP 8.5 on the VPS but 8.1 in an old box, causes subtle type errors. Rebuild boxes when upgrading production. Skipping vagrant destroy tests means new hires fail on fresh clones if only vagrant reload works.

Run Composer and Artisan inside the VM so the PHP binary matches production. For front-end assets, many teams run Node.js 26 LTS on the host with Vite 8.x because GUI file watchers perform better outside VirtualBox shared folders. If you must run npm inside the guest, switch the synced folder to NFS on macOS or Linux. Default VirtualBox shared folders are slow with thousands of small files. I have seen npm install take five times longer on a default mount compared to running Node on the host.

No. Vagrant solves local reproducibility only. Production still needs Deployer, GitLab CI, or similar pipelines. The win is fewer works-on-my-machine bugs before code reaches staging. Pair local Vagrant boxes with the same PHP extensions you enable on the server. In my experience on client projects, a committed Vagrantfile saves onboarding days but never substitutes zero-downtime deploy workflows on Ubuntu VPS hosting. Treat local boxes as the first layer of consistency, not the last mile of release automation.

Commit the Vagrantfile defining box, network, synced folder, and provisioner. Commit provision.sh or Ansible playbooks with idempotent install steps. Include .env.example where database host is often 127.0.0.1 with forwarded ports. Add an optional README section documenting vagrant up and vagrant ssh commands. Never commit secrets. Share box version pins and package lists instead, matching how Ubuntu environment variables are handled on production servers. That keeps every clone bootable without exposing credentials while still giving new developers an identical PHP, web server, and database stack.

MySQL listens inside the guest VM, but Vagrant forwards guest port 3306 to host 127.0.0.1 on port 33060. Set DB_HOST=127.0.0.1 and DB_PORT=33060 in your .env on the host filesystem where Laravel code lives via the synced folder at /vagrant. Redis follows the same pattern on host port 63790. GUI database clients and host-side tests connect through the loopback forward without exposing services to the wider network. This setup matches how I configure legal-tech and booking platforms where queue and cache services must behave locally like staging.

VirtualBox shared folders perform poorly with thousands of small files, which hurts npm install and Vite file watchers during Laravel front-end builds. I have seen npm install take five times longer on a default mount. The practical fix most teams use is running Node.js 26 LTS and Vite 8.x on the host while keeping PHP inside the guest. If npm must run inside the guest, switch the synced folder to NFS on macOS or Linux. On Windows, enable Guest Additions or use SMB or NFS where supported to reduce sync friction during daily development.

Choose Vagrant when you need full VM isolation that mirrors a DigitalOcean or EC2 Ubuntu VPS, including systemd services, custom kernel modules, or Apache plus PHP-FPM stacks. I still reach for Vagrant on client projects where Docker is overkill or blocked by corporate policy, and for freelancers who must match a client's exact Linux stack without reformatting their laptop. Choose Docker or Laravel Sail when you want second-scale container resets, lower per-service overhead, and many isolated services. Vagrant wins production parity and regulated environments; Docker wins boot speed and lighter daily iteration cycles.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: