Dockerizing My Local Development Environment
Dockerizing My Local Development Environment
The Problem with Manual Setup
- Project A: Laravel 9, PHP 8.1, MySQL 5.7
- Project B: Laravel 10, PHP 8.2, MySQL 8.0
- Project C: Laravel 11, PHP 8.3, PostgreSQL 14
My Current Docker Setup
version: '3.8'services: app: build: context: . dockerfile: Dockerfile volumes: - .:/var/www/html ports: - "8000:8000" environment: - APP_ENV=local - DB_HOST=db depends_on: - db - redis db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: myapp volumes: - db_data:/var/lib/mysql ports: - "3306:3306" redis: image: redis:alpine ports: - "6379:6379" frontend: image: node:20-alpine working_dir: /app volumes: - ./frontend:/app command: npm run dev ports: - "3000:3000"volumes: db_data:The Benefits
1. Consistency Across Teams
git clone <repo>cd projectdocker compose up -d2. Isolation
3. Production Parity
Frontend Development with Docker
# Development stageFROM node:20-alpine AS developmentWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .EXPOSE 3000CMD ["npm", "run", "dev"]# Production build stageFROM node:20-alpine AS buildWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npm run build# Production runtime (nginx)FROM nginx:alpine AS productionCOPY --from=build /app/dist /usr/share/nginx/htmlCOPY nginx.conf /etc/nginx/conf.d/default.confCommon Commands I Use
alias dcu="docker compose up -d"alias dcd="docker compose down"alias dcr="docker compose restart"alias dce="docker compose exec app"alias dcl="docker compose logs -f"docker compose exec app php artisan migratedocker compose exec app php artisan tinkerThe Learning Curve
- Volume permissions on Linux/Mac can be tricky
- Performance on macOS used to be painful (Docker Desktop has improved)
- Debugging inside containers requires setup
My Recommendation
For years, I managed my development environment manually - installing PHP, MySQL, Node.js versions directly on my machine. It worked until it didn't. "Works on my machine" became an all-too-familiar phrase. Here's how Docker changed my workflow. Last year, I was working on three different Laravel projects simultaneously: Switching between them was a nightmare. PHP version managers helped, but database versions and other dependencies were still painful. I now use Docker Compose for all projects. Here's a typical `docker compose.yml` for my Laravel projects: New team member onboarding is now: No more "install PHP, then MySQL, then Redis, then..." Each project runs in its own container with exact versions it needs. No conflicts, no surprises. My local environment now closely mirrors production. I caught a bug last month that only appeared in MySQL 8.0's strict mode - something I would have missed with my old setup. For React/Vue projects, I use a multi-stage Dockerfile: Created some handy aliases in my `.zshrc`: Running artisan commands: Docker isn't without its challenges: But the benefits far outweigh the initial learning investment. If you're still managing local dependencies manually, give Docker a try. Start with a simple `docker compose.yml` for your next project. You might struggle for the first few days, but you'll thank yourself later. Have you Dockerized your dev environment? What challenges did you face?
Enjoyed this note?
There are more thoughts on software engineering, architecture, and developer workflows in the archive.