Docker for Beginner Developers

You clone a Laravel project, and the first afternoon disappears into installing the right PHP version, hunting for a missing extension, and arguing with a local MySQL server. Or th...

Docker for Beginner Developers

You clone a Laravel project, and the first afternoon disappears into installing the right PHP version, hunting for a missing extension, and arguing with a local MySQL server. Or the reverse happens: the app runs fine on your machine and breaks on a teammate's because their PHP is a minor version behind. Docker exists to make that problem go away, and this guide takes you from zero to running a full Laravel stack with one command.

We will stay practical. No Kubernetes, no cluster talk. By the end you should understand the core ideas, be able to write your own Dockerfile, use Docker Compose for local development, and know how to fix the errors beginners hit most often.

The Three Ideas You Need

  • Image: a read-only template containing a minimal OS, a runtime such as PHP 8.3, extensions, and your code. You build it from a recipe called a Dockerfile.
  • Container: a running instance of an image. One image can start many containers. Anything written inside a container disappears when the container is removed, unless it lives in a volume.
  • Volume: storage that lives outside the container. Database files and uploads belong in volumes so they survive rebuilds.

Containers are not virtual machines. A VM boots a full operating system with its own kernel and needs a fair amount of RAM. A container shares the host kernel and carries only what the app needs, so it usually starts in seconds. On Windows and macOS, Docker Desktop quietly runs a small Linux VM for you, and you rarely have to think about it.

Installing Docker

  1. On Windows or macOS, install Docker Desktop. On Windows, use the WSL 2 backend; file access for PHP projects is much faster there.
  2. On Linux, install Docker Engine and the Compose plugin from Docker's official repository rather than an old distro package.
  3. Run docker run hello-world. A welcome message means you are ready.
  4. On Linux, add your user to the docker group so you do not need sudo for every command, then log out and back in.

A licensing note: Docker Desktop is free for personal use, education, and small businesses, but larger companies need a paid plan. Check Docker's current terms. OrbStack on macOS and Rancher Desktop are alternatives worth a look.

A Dockerfile for a Laravel Project

Here is a minimal development Dockerfile for Laravel 11 on PHP 8.3. Save it as Dockerfile in the project root.

FROM php:8.3-cli

RUN apt-get update && apt-get install -y git unzip libzip-dev \
    && docker-php-ext-install pdo_mysql zip \
    && rm -rf /var/lib/apt/lists/*

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

COPY composer.json composer.lock ./
RUN composer install --no-interaction --no-scripts --no-autoloader

COPY . .
RUN composer dump-autoload --optimize

EXPOSE 8000
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]

Why it is written this way:

  • Copy order matters. Composer files are copied first, so the expensive composer install layer is cached and only rebuilt when dependencies change. Editing a controller does not trigger a full vendor download.
  • --host=0.0.0.0 is required. Without it, the dev server only listens on localhost inside the container and your browser cannot reach it.
  • Composer comes from its official image through COPY --from, which avoids an install script.

Add a .dockerignore so heavy or secret files stay out of the image:

vendor
node_modules
.env
.git
storage/logs/*

Docker Compose: App and Database Together

Real apps need more than one service. Compose describes them all in a single compose.yaml:

services:
  app:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/var/www/html
    environment:
      DB_CONNECTION: mysql
      DB_HOST: db
      DB_PORT: 3306
      DB_DATABASE: laravel
      DB_USERNAME: laravel
      DB_PASSWORD: secret
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: rootsecret
    volumes:
      - dbdata:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      retries: 10

volumes:
  dbdata:

Note DB_HOST: db. Inside a Compose network, each service is reachable by its name. Writing 127.0.0.1 is the classic beginner mistake: inside a container, that address points to the container itself. Environment variables set by Compose also take priority over values in Laravel's .env.

  1. docker compose up -d --build builds the image and starts everything in the background.
  2. docker compose exec app composer install, because the bind mount replaces the image's vendor folder with your local project folder.
  3. docker compose exec app php artisan key:generate, then php artisan migrate the same way.
  4. Open http://localhost:8000.

Commands You Will Use Daily

CommandWhat it does
docker compose up -dStart all services in the background
docker compose downStop and remove containers (volumes are kept)
docker compose logs -f appFollow the app's logs live
docker compose exec app bashOpen a shell inside the container
docker compose psShow the status of each service
docker compose down -vStop and delete volumes too (database data is lost)

Common Mistakes and Fixes

Connection refused to the database

Either DB_HOST still says 127.0.0.1, or the app connects before MySQL is ready. Use the service name and a healthcheck with condition: service_healthy.

Port already in use

A local MySQL, MAMP, or another dev server is holding port 3306 or 8000. Stop it, or map to a different host port such as "8080:8000".

Permission denied in storage

On Linux, files created by the container may belong to root. Run chmod -R 775 storage bootstrap/cache inside the container, or run the container with your own UID.

Database data vanished

You either skipped the volume or ran down -v. Keep MySQL data in a named volume and take a dump before risky experiments.

Huge images

Without .dockerignore, node_modules and .git get copied in and can add hundreds of megabytes for nothing.

When Docker Is Worth It

Docker pays off when more than one person works on the project, when the app depends on several services such as MySQL, Redis, or a search engine, or when you juggle projects on different PHP versions. If you are in your first weeks with Laravel, a plain local setup is simpler, and if your production target is shared hosting, you will still deploy the traditional way described in our shared hosting deployment guide while using Docker only for development.

Laravel also ships Sail, an official wrapper around Docker Compose with sensible defaults. Sail gets you started fast; writing your own Dockerfile, as above, teaches you what is actually happening.

Checklist Before Sharing Your Setup

  • The Dockerfile pins a specific image tag (php:8.3-cli), never latest.
  • .dockerignore excludes vendor, node_modules, .env, and .git.
  • Passwords in compose.yaml are development-only.
  • Database data lives in a named volume.
  • The README lists the three to five commands needed to run the project from a fresh clone.
  • Someone other than you has tested the setup from a clean checkout.

Start with one small project, run docker compose up, and get used to reading logs when something fails. Once that feels routine, add Redis for queues or a mail catcher for testing emails. For other tools that pair well with Docker, see 15 free tools for beginner web developers.

Yudhi
Written by
Yudhi
Founder & Lead Developer, GudangCode

Yudhi is the founder of GudangCode and a Laravel developer who has built dozens of ready-to-use business information systems — from POS and HRIS to management apps. He writes guides and articles on GudangCode to help Indonesian developers run, understand, and deploy Laravel source code correctly.

LaravelPHPMySQLSistem Informasi Bisnis See all articles by Yudhi
Want the full source code & apps?

Sign up free to download ready-to-use business applications, information systems, and Laravel source code.

Sign Up Free & Download
Docker Pemula Teknologi & Development
Share this article
Back to Blog
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →

Get Full Access Now!

Join our membership and unlock exclusive access to all premium features. Fast, easy, and ready to use instantly.

Join Membership Now
Tim Support
Online
Isi data dulu untuk mulai chat:
Beri rating & testimoni sebelum menutup:
Live chat by gudangcode.com