Skip to main content

Usage

Once Laradock is installed, you drive it with a handful of Docker and Docker Compose commands. This page is the day-to-day reference: running and entering containers, switching versions, enabling services, installing tools, and preparing for production.

The golden rule: whenever you change the .env file, docker-compose.yml, or any Dockerfile, rebuild the affected container for the change to take effect:

docker-compose build {container-name}

Most recipes below end with this step. Add --no-cache to force a clean rebuild.

Containers

The core commands you use every day to start, stop, inspect, and rebuild your stack.

List running containers

docker ps

To see only the containers from this project:

docker-compose ps

Enter a container

Open a shell inside a running container to run commands in it.

  1. List the running containers with docker ps.
  2. Enter the one you want:
    docker-compose exec {container-name} bash
    Example — enter the MySQL container:
    docker-compose exec mysql bash
    Example — open the MySQL prompt directly:
    docker-compose exec mysql mysql -udefault -psecret
  3. Type exit to leave.

Tip: add --user=laradock to run as the Laradock user so created files are owned by your host user: docker-compose exec --user=laradock workspace bash.

Stop containers

Stop everything:

docker-compose stop

Stop a single container:

docker-compose stop {container-name}

Delete containers

docker-compose down

View logs

NGINX writes its logs to the logs/nginx directory. For any other container, use:

docker-compose logs {container-name}

Follow the log live with -f:

docker-compose logs -f {container-name}

See the Docker Compose logs options for more.

Build or rebuild containers

After editing any Dockerfile, rebuild for the change to take effect:

docker-compose build

Rebuild a single container instead of all of them:

docker-compose build {container-name}

Use --no-cache to force a full, clean rebuild:

docker-compose build --no-cache {container-name}

Edit a container's Compose config

Open docker-compose.yml and change whatever you need.

Change the MySQL database name:

environment:
MYSQL_DATABASE: laradock
...

Map Redis to a different host port (1111):

ports:
- "1111:6379"
...

Edit a Docker image

  1. Find the image's Dockerfile — for mysql it's mysql/Dockerfile.
  2. Edit it as you like.
  3. Rebuild the container:
    docker-compose build mysql

Add more services

To add a new service (software), edit docker-compose.yml and add your container definition. You'll want to be familiar with the Docker Compose file syntax.

PHP

Switch PHP versions and install the extensions and debuggers your project needs. PHP-FPM serves your application; the PHP-CLI lives in the Workspace container and runs Artisan, Composer, and tests.

Change the PHP-FPM version

By default the latest stable PHP version runs. PHP-FPM serves your application code.

  1. In .env, set PHP_VERSION to the version you want (any from 5.6 to 8.5):
    PHP_VERSION=8.1
  2. Rebuild the image:
    docker-compose build php-fpm

For details on the underlying base image, see the official PHP Docker images.

Change the PHP-CLI version

The PHP-CLI lives in the Workspace container and is used only for Artisan and Composer — it does not serve your application code (that's PHP-FPM's job), so changing it is usually optional.

  1. In .env, set PHP_VERSION to the version you want:
    PHP_VERSION=8.1
  2. Rebuild the Workspace:
    docker-compose build workspace

Install PHP extensions

PHP extensions are toggled per container in .env. Each container has its own section — PHP_FPM, WORKSPACE, and PHP_WORKER — with a matching flag for every extension.

  1. In .env, find the extension's flag under the relevant container's section and set it to true.
  2. Rebuild that container with --no-cache:
    docker-compose build --no-cache {container-name}

The sections below cover the debuggers and the individual extensions Laradock ships with.

Install Xdebug

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_XDEBUG
    • PHP_FPM_INSTALL_XDEBUG
  2. Rebuild:
    docker-compose build workspace php-fpm

To configure Xdebug with your IDE, see this Laravel + Laradock + PhpStorm guide.

Start or stop Xdebug

Once installed, Xdebug runs on startup by default. Control it in the php-fpm container by running these from the Laradock root:

  • Stop it starting by default: .php-fpm/xdebug stop
  • Start it: .php-fpm/xdebug start
  • Check status: .php-fpm/xdebug status

If .php-fpm/xdebug reports Permission Denied, give it execute access with chmod.

Install pcov

A fast code-coverage driver for PHP 7.1+.

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_PCOV
    • PHP_FPM_INSTALL_PCOV
  2. Rebuild:
    docker-compose build workspace php-fpm

For tuning tips, see the pcov README.

Install phpdbg

The interactive PHP debugger.

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_PHPDBG
    • PHP_FPM_INSTALL_PHPDBG
  2. Rebuild:
    docker-compose build workspace php-fpm

Install ionCube Loader

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_IONCUBE
    • PHP_FPM_INSTALL_IONCUBE
  2. Rebuild:
    docker-compose build workspace php-fpm

The latest loaders are always downloaded from ionCube.

Install the Aerospike extension

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_AEROSPIKE
    • PHP_FPM_INSTALL_AEROSPIKE
  2. Rebuild:
    docker-compose build workspace php-fpm

Install the Calendar extension

  1. In .env, set PHP_FPM_INSTALL_CALENDAR to true.
  2. Rebuild:
    docker-compose build php-fpm

Install libfaketime

Libfaketime lets you control the date and time the OS reports, set via the PHP_FPM_FAKETIME variable. For example, PHP_FPM_FAKETIME=-1d moves the clock back one day. See libfaketime for the syntax.

  1. In .env, set PHP_FPM_INSTALL_FAKETIME to true.
  2. Set PHP_FPM_FAKETIME to your desired offset.
  3. Rebuild:
    docker-compose build php-fpm

Install the YAML extension

Parse and emit YAML from PHP. See the PHP YAML reference.

  1. In .env, set PHP_FPM_INSTALL_YAML to true.
  2. Rebuild:
    docker-compose build php-fpm

Install the rdkafka extension (PHP-FPM)

  1. In .env, set PHP_FPM_INSTALL_RDKAFKA to true.
  2. Rebuild:
    docker-compose build php-fpm

Install the rdkafka extension (Workspace)

Needed for composer install when your dependencies require Kafka.

  1. In .env, set WORKSPACE_INSTALL_RDKAFKA to true.
  2. Rebuild:
    docker-compose build workspace

Install the AST extension

AST exposes the abstract syntax tree generated by PHP 7+. It's required by tools such as Phan, a static analyzer.

  1. In .env, set WORKSPACE_INSTALL_AST to true.
  2. Rebuild:
    docker-compose build workspace

To pin a specific version, set WORKSPACE_AST_VERSION before rebuilding.

Install the Decimal extension

The Decimal extension adds correctly-rounded, arbitrary-precision decimal arithmetic — useful for money, measurements, and anything where float rounding is unacceptable.

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_PHPDECIMAL
    • PHP_FPM_INSTALL_PHPDECIMAL
  2. Rebuild:
    docker-compose build workspace php-fpm

Databases

Switch database versions, manage access, and connect the document stores.

Change the MySQL version

By default MySQL 8.4 (LTS) runs. You can pin any tag published on the MySQL Docker Hub image — for example 5.7, 8.0, 8.4, or latest.

  1. In .env, set MYSQL_VERSION:
    MYSQL_VERSION=8.0
  2. Rebuild:
    docker-compose build mysql

MySQL root access

The default root credentials are username root, password root.

  1. Enter the MySQL container:
    docker-compose exec mysql bash
  2. Open the MySQL prompt (use mysql -udefault -psecret for non-root access):
    mysql -uroot -proot
  3. List users:
    SELECT User FROM mysql.user;
  4. Run anything you need — show databases;, show tables;, select ....

Create multiple databases

MySQL only.

Copy mysql/docker-entrypoint-initdb.d/createdb.sql.example to createdb.sql in the same folder, then add your statements:

CREATE DATABASE IF NOT EXISTS `your_db_1` COLLATE 'utf8mb4_general_ci' ;
GRANT ALL ON `your_db_1`.* TO 'mysql_user'@'%' ;

Change the MySQL port

Set your port in mysql/my.cnf (here 1234):

[mysqld]
port=1234

If you also need MySQL access from your host, change the internal port in docker-compose.yml accordingly ("3306:3306""3306:1234").

Use MongoDB

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_MONGO
    • PHP_FPM_INSTALL_MONGO
  2. Rebuild:
    docker-compose build workspace php-fpm
  3. Start the container:
    docker-compose up -d mongo
  4. Add a MongoDB connection to config/database.php:
    'connections' => [

    'mongodb' => [
    'driver' => 'mongodb',
    'host' => env('DB_HOST', 'localhost'),
    'port' => env('DB_PORT', 27017),
    'database' => env('DB_DATABASE', 'database'),
    'username' => '',
    'password' => '',
    'options' => [
    'database' => '',
    ]
    ],

    // ...

    ],
  5. In your Laravel .env, set DB_HOST=mongo, DB_PORT=27017, and DB_DATABASE=database.
  6. Install the Laravel MongoDB package (formerly jenssegers/mongodb, now maintained as mongodb/laravel-mongodb):
    composer require mongodb/laravel-mongodb
  7. Extend your models from the MongoDB Eloquent model, enter the Workspace, and run php artisan migrate.

Use RethinkDB

RethinkDB is an open-source database built for real-time apps. A community package, Laravel RethinkDB, provides Laravel integration.

  1. Start the container:
    docker-compose up -d rethinkdb
  2. Open the admin console at http://localhost:8090/#tables and create a database named database.
  3. Add a RethinkDB connection to config/database.php:
    'connections' => [

    'rethinkdb' => [
    'name' => 'rethinkdb',
    'driver' => 'rethinkdb',
    'host' => env('DB_HOST', 'rethinkdb'),
    'port' => env('DB_PORT', 28015),
    'database' => env('DB_DATABASE', 'test'),
    ]

    // ...

    ],
  4. In your Laravel .env, set DB_CONNECTION=rethinkdb, DB_HOST=rethinkdb, DB_PORT=28015, and DB_DATABASE=database.

See the RethinkDB docs on backing up your data.

Back up PostgreSQL (pgbackups)

Scheduled, automatic PostgreSQL backups via postgres-backup-local.

  1. Make sure the postgres container is running.
  2. Start the backup container:
    docker-compose up -d pgbackups

Backups are written to the ../backup folder on your host. The service reuses your Postgres container's POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD; adjust the schedule and retention in the pgbackups block of docker-compose.yml.

Laravel

Install Laravel and run its everyday tooling — Artisan, queues, the scheduler, and Browsersync — from the Workspace container.

Install Laravel

  1. Enter the Workspace container.
  2. Create the project with Composer (recommended over the Laravel installer):
    composer create-project laravel/laravel my-cool-app
    See the Laravel installation docs for details.
  3. Point Laradock at the new app. By default Laradock expects your app in the parent directory of the laradock folder, so update APP_CODE_PATH_HOST in .env:
    APP_CODE_PATH_HOST=../my-cool-app/
  4. cd my-cool-app and start working.

Run Artisan commands

Run Artisan, Composer, tests, and other terminal commands from the Workspace container.

  1. Make sure the Workspace is running:
    docker-compose up -d workspace
  2. Enter it:
    docker-compose exec workspace bash

    Add --user=laradock so created files are owned by your host user (avoids permission issues on rotated log files).

  3. Run anything you need:
    php artisan
    composer update
    phpunit

Run the queue worker

  1. Create a config for the worker in php-worker/supervisord.d/ by copying laravel-worker.conf.example (for example, to laravel-worker.conf).
  2. Start the worker:
    docker-compose up -d php-worker

Run the scheduler

Laradock can run the Laravel scheduler two ways:

1. Cron in the Workspace container (default). When you start Laradock, the Workspace container starts cron and runs schedule:run every minute.

2. Supervisord in the php-worker container. Preferred when you don't want to run the Workspace in production.

  1. Comment out the cron line in workspace/crontab/laradock:
    # * * * * * laradock /usr/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1
  2. Copy laravel-scheduler.conf.example in php-worker/supervisord.d/ to a new config (for example, laravel-scheduler.conf).
  3. Start the worker:
    docker-compose up -d php-worker

Use Browsersync

With Laravel Mix.

  1. Add Browsersync to your webpack.mix.js (see the Browsersync options):
    const mix = require('laravel-mix')

    // ...

    mix.browserSync({
    open: false,
    proxy: 'nginx' // replace with your web server container
    })
  2. Run npm run watch inside the Workspace container.
  3. Open http://localhost:[WORKSPACE_BROWSERSYNC_HOST_PORT] — it reloads automatically when you edit a source file.
  4. The Browsersync UI is at http://localhost:[WORKSPACE_BROWSERSYNC_UI_HOST_PORT].

Other Frameworks

Recipes for non-Laravel PHP projects.

Install Symfony

  1. In .env, set WORKSPACE_INSTALL_SYMFONY to true.
  2. Rebuild the Workspace:
    docker-compose build workspace
  3. The NGINX sites include a symfony.conf.example — edit it so root points to your project's public directory.
  4. If the containers were already running, restart them: docker-compose restart.
  5. Visit symfony.test.

Install CodeIgniter

To run CodeIgniter 3 on Laradock:

  1. In docker-compose.yml, change CODEIGNITER=false to CODEIGNITER=true.
  2. Rebuild PHP-FPM:
    docker-compose build php-fpm

Add Magento authentication

Adding Composer authentication credentials for Magento 2.

  1. In .env, set WORKSPACE_COMPOSER_AUTH to true.
  2. Add your credentials to workspace/auth.json.
  3. Rebuild the Workspace:
    docker-compose build workspace

Workspace Tools

The Workspace container is your command-line home. Toggle these tools in .env and rebuild the Workspace to add Node, package managers, CLIs, media binaries, and shell niceties.

Node.js & NVM

  1. In .env, set WORKSPACE_INSTALL_NODE to true.
  2. Rebuild:
    docker-compose build workspace

A .npmrc is included in the workspace folder and is copied into the root and laradock users' home directories on build, in case you need global npm config.

pnpm

pnpm stores a single copy of each package version on disk and hard-links it into each project's node_modules, saving large amounts of space and speeding up installs. More on the pnpm motivation.

  1. In .env, set both WORKSPACE_INSTALL_NODE and WORKSPACE_INSTALL_PNPM to true.
  2. Rebuild:
    docker-compose build workspace

Yarn

  1. In .env, set both WORKSPACE_INSTALL_NODE and WORKSPACE_INSTALL_YARN to true.
  2. Rebuild:
    docker-compose build workspace

Gulp

  1. In .env, set WORKSPACE_INSTALL_NPM_GULP to true.
  2. Rebuild:
    docker-compose build workspace

Bower

Legacy. Bower is deprecated; prefer npm, Yarn, or pnpm for new projects.

  1. In .env, set WORKSPACE_INSTALL_NPM_BOWER to true.
  2. Rebuild:
    docker-compose build workspace

Vue CLI

  1. In .env, set WORKSPACE_INSTALL_NPM_VUE_CLI to true.
  2. Optionally change the ports: WORKSPACE_VUE_CLI_SERVE_HOST_PORT (default 8080) and WORKSPACE_VUE_CLI_UI_HOST_PORT (default 8001).
  3. Rebuild:
    docker-compose build workspace

Run vue serve or vue ui from the Workspace, then browse to the matching port.

Angular CLI

  1. In .env, set WORKSPACE_INSTALL_NPM_ANGULAR_CLI to true.
  2. Rebuild:
    docker-compose build workspace

npm-check-updates

npm-check-updates upgrades your package.json dependencies to the latest versions.

  1. In .env, make sure WORKSPACE_INSTALL_NODE is true.
  2. Set WORKSPACE_INSTALL_NPM_CHECK_UPDATES_CLI to true.
  3. Rebuild:
    docker-compose build workspace

Global Composer install

Install your global Composer requirements at build time so they're available in the container afterward.

  1. In .env, set WORKSPACE_COMPOSER_GLOBAL_INSTALL to true.
  2. Add your dependencies to workspace/composer.json.
  3. Rebuild:
    docker-compose build workspace

Prestissimo

Legacy. Prestissimo parallelized downloads for Composer 1 only and is abandoned. Composer 2 (Laradock's default) already downloads in parallel, so you almost certainly don't need this.

  1. Enable Global Composer install (steps 1–2).
  2. Add "hirak/prestissimo": "^0.3" to workspace/composer.json.
  3. Rebuild:
    docker-compose build workspace

Deployer

A deployment tool for PHP.

  1. In .env, set WORKSPACE_INSTALL_DEPLOYER to true.
  2. Rebuild:
    docker-compose build workspace

See the Deployer documentation.

Laravel Envoy

A task runner.

  1. In .env, set WORKSPACE_INSTALL_LARAVEL_ENVOY to true.
  2. Rebuild:
    docker-compose build workspace

See the Laravel Envoy documentation.

Linuxbrew

Linuxbrew is the Linux port of Homebrew.

  1. In .env, set WORKSPACE_INSTALL_LINUXBREW to true.
  2. Rebuild:
    docker-compose build workspace

Supervisor

Supervisor monitors and controls long-running processes on UNIX-like systems.

  1. In .env, set both WORKSPACE_INSTALL_SUPERVISOR and WORKSPACE_INSTALL_PYTHON to true.
  2. Create a worker config in php-worker/supervisord.d/ by copying laravel-worker.conf.example.
  3. Rebuild:
    docker-compose build workspace

GNU Parallel

GNU Parallel runs multiple processes concurrently from the command line.

  1. In .env, set WORKSPACE_INSTALL_GNU_PARALLEL to true.
  2. Rebuild:
    docker-compose build workspace

FFmpeg

  1. In .env, set WORKSPACE_INSTALL_FFMPEG to true.
  2. Rebuild:
    docker-compose build workspace

If you queue conversions, also install FFmpeg in the php-worker and php-fpm containers (same flag pattern) — otherwise the php-ffmpeg binary errors out.

BBC audiowaveform

audiowaveform generates waveform data from MP3, WAV, FLAC, or Ogg Vorbis files, for rendering visual waveforms.

  1. In .env, set WORKSPACE_INSTALL_AUDIOWAVEFORM to true.
  2. Rebuild:
    docker-compose build workspace

If you queue processing, also install it in the php-worker, laravel-horizon, and php-fpm containers (same flag pattern) — otherwise the audiowaveform binary errors out.

wkhtmltopdf

wkhtmltopdf renders a PDF from HTML.

  1. In .env, set WORKSPACE_INSTALL_WKHTMLTOPDF to true.
  2. Rebuild:
    docker-compose build workspace

Also install it in the php-fpm container (same flag pattern) — otherwise the wkhtmltopdf binary errors out.

poppler-utils & antiword

poppler-utils is a set of PDF command-line tools (info, text/image extraction, format conversion, signature verification, and more). It's commonly paired with antiword, so Laradock installs both together when the flag is set.

  1. In .env, set the flag to true for each container you need it in: WORKSPACE_INSTALL_POPPLER_UTILS, PHP_FPM_INSTALL_POPPLER_UTILS, PHP_WORKER_INSTALL_POPPLER_UTILS, LARAVEL_HORIZON_INSTALL_POPPLER_UTILS.
  2. Rebuild the affected containers:
    docker-compose build workspace php-fpm php-worker laravel-horizon

Graphviz

Graphviz renders graphs from text descriptions. Enable it in whichever container needs it:

ContainerFlagRebuild
WorkspaceWORKSPACE_INSTALL_GRAPHVIZdocker-compose build workspace
PHP-FPM (most common)PHP_FPM_INSTALL_GRAPHVIZdocker-compose build php-fpm
PHP-WorkerPHP_WORKER_INSTALL_GRAPHVIZdocker-compose build php-worker

Set the flag to true, then rebuild.

dnsutils

  1. In .env, set both flags to true:
    • WORKSPACE_INSTALL_DNSUTILS
    • PHP_FPM_INSTALL_DNSUTILS
  2. Rebuild:
    docker-compose build workspace php-fpm

GitHub Copilot CLI

Requires GitHub Copilot access.

  1. In .env, set WORKSPACE_INSTALL_GITHUB_CLI to true.
  2. Rebuild and start the Workspace:
    docker-compose build workspace
    docker-compose up -d workspace
  3. Enter the Workspace:
    docker-compose exec workspace bash
  4. Authenticate, then install the Copilot extension:
    gh auth login
    gh extension install github/gh-copilot

Oh My Zsh

Oh My Zsh manages your Zsh configuration. Laradock wires it up with the Laravel autocomplete plugin.

  1. In .env, set SHELL_OH_MY_ZSH to true.
  2. Rebuild:
    docker-compose build workspace
  3. Use it:
    docker-compose exec --user=laradock workspace zsh

Configure it by editing /home/laradock/.zshrc in the running container.

Optional plugins:

  • Autosuggestions — set SHELL_OH_MY_ZSH_AUTOSUGESTIONS to true, then rebuild. Suggests commands as you type, from history and completions (zsh-autosuggestions).
  • Bash aliases — set SHELL_OH_MY_ZSH_ALIASES to true, then rebuild, to load Laradock's aliases.sh into Zsh.

Git Bash prompt

A bash prompt showing the current branch, diff with remote, and counts of staged/changed files.

  1. In .env, set WORKSPACE_INSTALL_GIT_PROMPT to true.
  2. Rebuild:
    docker-compose build workspace

Customize it by editing workspace/gitprompt.sh and rebuilding. See the bash-git-prompt repo.

Terminal aliases

On startup, Laradock copies workspace/aliases.sh into the container and sources it from ~/.bashrc. Edit that file to add your own aliases or function macros.

Powerline

  1. In .env, set both WORKSPACE_INSTALL_POWERLINE and WORKSPACE_INSTALL_PYTHON to true (Powerline requires Python).
  2. Rebuild:
    docker-compose build workspace

Use a Service

Each service runs in its own container. Start the ones you need with docker-compose up -d {container-name} and open the port listed below.

Redis

  1. Start the container:
    docker-compose up -d redis

    To run Redis commands, enter the container with docker-compose exec redis bash, then use redis-cli.

  2. In your Laravel .env, set REDIS_HOST=redis. If that variable isn't there, set the host in config/database.php instead — replace the default 127.0.0.1 with redis:
    'redis' => [
    'cluster' => false,
    'default' => [
    'host' => 'redis',
    'port' => 6379,
    'database' => 0,
    ],
    ],
  3. To use Redis for cache and sessions, set CACHE_DRIVER=redis and SESSION_DRIVER=redis in .env.
  4. Install the client:
    composer require predis/predis:^1.0
  5. Test it from Laravel:
    \Cache::store('redis')->put('Laradock', 'Awesome', 10);

Redis Cluster

  1. Start the container:
    docker-compose up -d redis-cluster
  2. Configure the cluster in config/database.php (example uses phpredis — see the Laravel Redis docs):
    'redis' => [
    'client' => 'phpredis',
    'options' => [
    'cluster' => 'redis',
    ],
    'clusters' => [
    'default' => [
    [
    'host' => 'redis-cluster',
    'password' => null,
    'port' => 7000,
    'database' => 0,
    ],
    ],
    ],
    ],

Varnish

Varnish sits behind NGINX as a caching reverse proxy. NGINX listens on 80/443, forwards to Varnish, and Varnish forwards back to NGINX on port 81 (set by VARNISH_BACKEND_PORT). The shipped config was developed and tested for WordPress, but likely works with other systems. The approach is based on this Linode guide.

Configure:

  1. Set the domain name in VARNISH_PROXY1_BACKEND_HOST.
  2. To serve multiple domains, add a configuration section per domain in .env:
    VARNISH_PROXY1_CACHE_SIZE=128m
    VARNISH_PROXY1_BACKEND_HOST=replace_with_your_domain.name
    VARNISH_PROXY1_SERVER=SERVER1
  3. Add a matching section to docker-compose.yml:
    custom_proxy_name:
    container_name: custom_proxy_name
    build: ./varnish
    expose:
    - ${VARNISH_PORT}
    environment:
    - VARNISH_CONFIG=${VARNISH_CONFIG}
    - CACHE_SIZE=${VARNISH_PROXY2_CACHE_SIZE}
    - VARNISHD_PARAMS=${VARNISHD_PARAMS}
    - VARNISH_PORT=${VARNISH_PORT}
    - BACKEND_HOST=${VARNISH_PROXY2_BACKEND_HOST}
    - BACKEND_PORT=${VARNISH_BACKEND_PORT}
    - VARNISH_SERVER=${VARNISH_PROXY2_SERVER}
    ports:
    - "${VARNISH_PORT}:${VARNISH_PORT}"
    links:
    - workspace
    networks:
    - frontend
  4. Update your Varnish config and add the NGINX config (example: nginx/sites/laravel_varnish.conf.example). Use default_wordpress.vcl rather than the older default.vcl.

Run:

  1. Rename default_wordpress.vcl to default.vcl.
  2. docker-compose up -d nginx
  3. docker-compose up -d proxy

Varnish must be built after NGINX, because it checks the domain's availability.

FAQ:

  • Purge cache: curl -X PURGE https://yourwebsite.com/
  • Reload Varnish: docker container exec proxy varnishreload
  • Reload NGINX: docker exec Nginx nginx -t then docker exec Nginx nginx -s reload
  • Allowed varnish commands: varnishadm, varnishd, varnishhist, varnishlog, varnishncsa, varnishreload, varnishstat, varnishtest, varnishtop

phpMyAdmin

  1. Start it alongside your database:
    # with MySQL
    docker-compose up -d mysql phpmyadmin

    # with MariaDB
    docker-compose up -d mariadb phpmyadmin

    For MariaDB, set PMA_DB_ENGINE=mariadb in .env (default is mysql).

  2. Open http://localhost:8081. For the default MySQL setup, use server mysql, user default, password secret.

Adminer

  1. Start the container:
    docker-compose up -d adminer
  2. Open http://localhost:8080.

Notes:

  • Load plugins via ADM_PLUGINS in .env. Some plugins need parameters and a custom file in the container — see Loading plugins.
  • Choose a design via ADM_DESIGN.
  • Set a default host via ADM_DEFAULT_SERVER — handy when connecting to an external server or a non-default container name.

pgAdmin

  1. Start it alongside Postgres:
    docker-compose up -d postgres pgadmin
  2. Open http://localhost:5050.

Default credentials — email [email protected], password admin.

ElasticSearch

  1. Start the container:
    docker-compose up -d elasticsearch
  2. Open http://localhost:9200.

Default credentials — user elastic, password changeme.

Install a plugin:

  1. Install it:
    docker-compose exec elasticsearch /usr/share/elasticsearch/bin/plugin install {plugin-name}
  2. Restart the container:
    docker-compose restart elasticsearch

MeiliSearch

  1. Start the container:
    docker-compose up -d meilisearch
  2. Open http://localhost:7700.

Master keymasterkey.

Beanstalkd

  1. Start the container:
    docker-compose up -d beanstalkd
  2. In config/queue.php, set beanstalkd as the default driver and QUEUE_HOST=beanstalkd. It listens on port 11300.
  3. Install the client:
    composer require pda/pheanstalk

Optional web console:

  1. Start it:
    docker-compose up -d beanstalkd-console
  2. Open http://localhost:2080 (change the port with BEANSTALKD_CONSOLE_HOST_PORT).
  3. Add the server — host beanstalkd, port 11300.

Mosquitto (MQTT)

  1. Optionally change the port with MOSQUITTO_PORT (default 9001).
  2. Start the container:
    docker-compose up -d mosquitto
  3. Use an MQTT client (for example, MQTT.js) to subscribe and publish:
    mqtt sub -t 'test' -h localhost -p 9001 -C 'ws' -v
    mqtt pub -t 'test' -h localhost -p 9001 -C 'ws' -m 'Hello!'

Apache Kafka

A distributed event-streaming platform. Kafka needs the zookeeper container running.

  1. Start ZooKeeper and Kafka together:
    docker-compose up -d zookeeper kafka
  2. The broker listens on port 9092.

To manage Kafka from a web UI, also start Kafka Manager:

docker-compose up -d kafka-manager

Open http://localhost:9020 and add a cluster pointing at the ZooKeeper host zookeeper:2181.

Mailu

  1. You'll need a registered domain and a reCAPTCHA key pair for signup email.
  2. Set these in .env:
    MAILU_RECAPTCHA_PUBLIC_KEY=<YOUR_RECAPTCHA_PUBLIC_KEY>
    MAILU_RECAPTCHA_PRIVATE_KEY=<YOUR_RECAPTCHA_PRIVATE_KEY>
    MAILU_DOMAIN=laradock.io
    MAILU_HOSTNAMES=mail.laradock.io
  3. Open http://YOUR_DOMAIN.

Mailpit

  1. Start the container:
    docker-compose up -d mailpit
  2. Open http://localhost:8125.
  3. Configure your Laravel .env:
    MAIL_MAILER=smtp
    MAIL_HOST=mailpit
    MAIL_PORT=1125
    MAIL_USERNAME=null
    MAIL_PASSWORD=null

Grafana

  1. Optionally change the port with GRAFANA_PORT (default 3000).
  2. Start the container:
    docker-compose up -d grafana
  3. Open http://localhost:3000.

Default credentials — user admin, password admin.

Graylog

  1. Set a password in your Laravel .env. GRAYLOG_SHA256_PASSWORD is what's used; GRAYLOG_PASSWORD is just a reminder of the plain text. The password must be at least 16 characters.
    GRAYLOG_PASSWORD=somesupersecretpassword
    GRAYLOG_SHA256_PASSWORD=b1cb6e31e172577918c9e7806c572b5ed8477d3f57aa737bee4b5b1db3696f09

    Generate the hash with: echo -n somesupersecretpassword | sha256sum

  2. Start the container:
    docker-compose up -d graylog
  3. Open http://localhost:9000 and sign in as admin with your password.
  4. Go to System → Inputs and launch a new input.

NetData

  1. Start the container:
    docker-compose up -d netdata
  2. Open http://localhost:19999.

Tarantool

  1. Optionally set TARANTOOL_PORT and TARANTOOL_ADMIN_PORT (defaults 3301 and 8002).
  2. Start both containers:
    docker-compose up -d tarantool tarantool-admin
  3. Open the admin tool at http://localhost:8002 and set Hostname to tarantool — your data then appears in the panel.
  4. To use the console:
    docker-compose exec tarantool console

See the Tarantool documentation.

Jenkins

  1. Start the container:
    docker-compose up -d jenkins
  2. Open http://localhost:8090/.
  3. Sign in — default user admin, password from:
    docker-compose exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
  4. Install plugins and create your admin user.

Notes:

  • Enter as root with docker-compose exec --user root jenkins bash.
  • Add a user at http://localhost:8090/securityRealm/addUser; restart at http://localhost:8090/restart.
  • Review authorization at http://localhost:8090/configureSecurity/.

GitLab

  1. Start the container:
    docker-compose up -d gitlab
  2. Open http://localhost:8989.

Set your own domain with GITLAB_DOMAIN_NAME (default http://localhost).

GitLab Runner

  1. Get the registration token from your GitLab project (Settings → CI/CD → Runners).
  2. Set these in .env:
    GITLAB_DOMAIN_NAME=http://gitlab
    GITLAB_RUNNER_REGISTRATION_TOKEN=<value-from-step-1>
    GITLAB_CI_SERVER_URL=http://gitlab
  3. Add runner settings to docker-compose.yml:
    gitlab-runner:
    environment: # used during `gitlab-runner register`
    - RUNNER_EXECUTOR=docker # change from shell (default)
    - DOCKER_IMAGE=alpine
    - DOCKER_NETWORK_MODE=laradock_backend
    networks:
    - backend # connect to the network where gitlab runs
  4. Start the runner:
    docker-compose up -d gitlab-runner
  5. Register it:
    docker-compose exec gitlab-runner bash
    gitlab-runner register
  6. Add a .gitlab-ci.yml to your project, push, and confirm the pipeline runs:
    before_script:
    - echo Hello!

    job1:
    scripts:
    - echo job1

SonarQube

SonarQube is an automatic code-review tool that detects bugs, vulnerabilities, and code smells across branches and pull requests.

  1. In .env, set SONARQUBE_HOSTNAME to your domain (for example, sonar.example.com).
  2. Start the container:
    docker-compose up -d sonarqube
  3. Open http://localhost:9000/.

Troubleshooting:

  • Database error:
    docker-compose exec --user=root postgres
    source docker-entrypoint-initdb.d/init_sonarqube_db.sh
  • Logs error:
    docker-compose run --user=root --rm sonarqube chown sonarqube:sonarqube /opt/sonarqube/logs

OneDev

A self-hosted Git server with built-in CI/CD pipelines and issue tracking.

  1. Start the container:
    docker-compose up -d onedev
  2. Open http://localhost:6610 and complete the setup wizard.

Git over SSH is available on port 6611. Change either port with ONEDEV_HTTP_PORT and ONEDEV_SSH_PORT in .env.

Portainer

  1. Start the container:
    docker-compose up -d portainer
  2. Open http://localhost:9010.

Minio

  1. Configure it: tweak the MINIO_* settings in .env, and optionally install the Minio client in the Workspace with WORKSPACE_INSTALL_MC=true.
  2. Start the container:
    docker-compose up -d minio
  3. Open http://localhost:9000.
  4. Create a bucket via the web UI or the client:
    mc mb minio/bucket
  5. Point your clients at it:
    AWS_URL=http://minio:9000
    AWS_ACCESS_KEY_ID=access
    AWS_SECRET_ACCESS_KEY=secretkey
    AWS_DEFAULT_REGION=us-east-1
    AWS_BUCKET=test
    AWS_USE_PATH_STYLE_ENDPOINT=true
  6. Configure the s3 disk in filesystems.php:
    's3' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION'),
    'bucket' => env('AWS_BUCKET'),
    'endpoint' => env('AWS_URL'),
    'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false)
    ],

Set AWS_USE_PATH_STYLE_ENDPOINT=true for local use only.

Thumbor

Thumbor is a smart imaging service for on-demand cropping, resizing, and flipping of images.

  1. Review the Thumbor settings in .env.
  2. Start the container:
    docker-compose up -d thumbor
  3. Try an example: http://localhost:8000/unsafe/300x300/i.imgur.com/bvjzPct.jpg

See the Thumbor documentation.

AWS EB CLI

  1. Add your SSH keys to the aws-eb-cli/ssh_keys folder.
  2. Start the container:
    docker-compose up -d aws
  3. Enter it:
    docker-compose exec aws bash
  4. Initialize your project with eb init. See the EB CLI docs.

Keycloak

  1. Start the container:
    docker-compose up -d keycloak
  2. Open http://localhost:8081.

Default credentials — user admin, password secret.

Metabase

  1. Start the container:
    docker-compose up -d metabase
  2. Open http://localhost:3030.

See Running Metabase on Docker for configuration.

Confluence

Confluence is a licensed Atlassian product — get an evaluation licence from Atlassian.

  1. Start the container:
    docker-compose up -d confluence
  2. Open http://localhost:8090.

Pin a version with CONFLUENCE_VERSION. See versioning.

With NGINX and SSL:

  1. Copy nginx/sites/confluence.conf.example and replace the sample domain with yours.
  2. Configure SSL keys for your domain.

Confluence stays reachable on 8090 regardless.

Selenium

  1. Start the container:
    docker-compose up -d selenium
  2. Open http://localhost:4444/wd/hub.

Tomcat

Apache Tomcat for running Java web applications (WAR files).

  1. Start the container:
    docker-compose up -d tomcat
  2. Open http://localhost:8080.

Drop .war files into ${DATA_PATH_HOST}/tomcat/webapps to deploy them. Set the version with TOMCAT_VERSION and the host port with TOMCAT_HOST_HTTP_PORT in .env.

Traefik

Traefik is a reverse proxy that terminates TLS and routes to your containers via labels. To use it, don't expose each container's ports — define Traefik labels instead.

  1. In .env, set ACME_DOMAIN to your domain and ACME_EMAIL to your email.
  2. Update docker-compose.yml so the routed container uses labels rather than published ports. For example, NGINX becomes:
    nginx:
    build:
    context: ./nginx
    args:
    - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER}
    - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT}
    - CHANGE_SOURCE=${CHANGE_SOURCE}
    volumes:
    - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
    - ${NGINX_HOST_LOG_PATH}:/var/log/nginx
    - ${NGINX_SITES_PATH}:/etc/nginx/sites-available
    depends_on:
    - php-fpm
    networks:
    - frontend
    - backend
    labels:
    - "traefik.enable=true"
    - "traefik.http.services.nginx.loadbalancer.server.port=80"
    # https router
    - "traefik.http.routers.https.rule=Host(`${ACME_DOMAIN}`, `www.${ACME_DOMAIN}`)"
    - "traefik.http.routers.https.entrypoints=https"
    - "traefik.http.routers.https.middlewares=www-redirectregex"
    - "traefik.http.routers.https.service=nginx"
    - "traefik.http.routers.https.tls.certresolver=letsencrypt"
    # http router
    - "traefik.http.routers.http.rule=Host(`${ACME_DOMAIN}`, `www.${ACME_DOMAIN}`)"
    - "traefik.http.routers.http.entrypoints=http"
    - "traefik.http.routers.http.middlewares=http-redirectscheme"
    - "traefik.http.routers.http.service=nginx"
    # middlewares
    - "traefik.http.middlewares.www-redirectregex.redirectregex.permanent=true"
    - "traefik.http.middlewares.www-redirectregex.redirectregex.regex=^https://www.(.*)"
    - "traefik.http.middlewares.www-redirectregex.redirectregex.replacement=https://$$1"
    - "traefik.http.middlewares.http-redirectscheme.redirectscheme.permanent=true"
    - "traefik.http.middlewares.http-redirectscheme.redirectscheme.scheme=https"
    instead of the port-publishing version:
    nginx:
    build:
    context: ./nginx
    args:
    - PHP_UPSTREAM_CONTAINER=${NGINX_PHP_UPSTREAM_CONTAINER}
    - PHP_UPSTREAM_PORT=${NGINX_PHP_UPSTREAM_PORT}
    - CHANGE_SOURCE=${CHANGE_SOURCE}
    volumes:
    - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
    - ${NGINX_HOST_LOG_PATH}:/var/log/nginx
    - ${NGINX_SITES_PATH}:/etc/nginx/sites-available
    - ${NGINX_SSL_PATH}:/etc/nginx/ssl
    ports:
    - "${NGINX_HOST_HTTP_PORT}:80"
    - "${NGINX_HOST_HTTPS_PORT}:443"
    depends_on:
    - php-fpm
    networks:
    - frontend
    - backend

Networking & Domains

Use a custom domain

Use a real domain instead of the Docker IP. Assuming your domain is laravel.test:

  1. Map it to localhost in your /etc/hosts:
    127.0.0.1 laravel.test
  2. Open http://laravel.test.

Optionally set the server name in your NGINX config:

server_name laravel.test;

Add CA certificates

To install your own CA certificates, drop them in the workspace/ca-certificates folder. They're added to the workspace container's system CA store on build.

Production & Deployment

Prepare Laradock for production

For production, create a dedicated Compose file — for example production-docker-compose.yml — that includes only the containers you'll actually run:

docker-compose -f production-docker-compose.yml up -d nginx mysql redis ...

Security: do not forward database ports in production. Docker publishes them on the host unless told otherwise, which is insecure. Remove lines like:

ports:
- "3306:3306"

See this post on Docker and iptables for why.

Set up Google Cloud

Configure Docker for the Google Container Registry, then authenticate:

gcloud auth configure-docker
gcloud auth login

Environment & Platform

Workspace access, host-specific tuning, and scheduling.

Access the workspace over SSH

Reach the Workspace at localhost:2222 by setting INSTALL_WORKSPACE_SSH to true.

To change the forwarded port, edit docker-compose.yml:

workspace:
ports:
- "2222:22" # edit this line
...

Then connect:

ssh -o PasswordAuthentication=no \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-p 2222 \
-i workspace/insecure_id_rsa \
laradock@localhost

Replace laradock@localhost with root@localhost to log in as root.

Change the timezone

Set the TZ build argument for the workspace container in docker-compose.yml to any value from the TZ database. For example, New York:

workspace:
build:
context: ./workspace
args:
- TZ=America/New_York
...

We also recommend setting the timezone in Laravel.

Add locales to PHP-FPM

Add locales:

  1. In .env, set PHP_FPM_INSTALL_ADDITIONAL_LOCALES to true.
  2. Add the locale codes to PHP_FPM_ADDITIONAL_LOCALES.
  3. Rebuild: docker-compose build php-fpm.
  4. Check them: docker-compose exec php-fpm locale -a.

Change the default locale (default is POSIX):

  1. In .env, set PHP_FPM_DEFAULT_LOCALE to your locale, for example en_US.UTF8.
  2. Rebuild: docker-compose build php-fpm.
  3. Check it: docker-compose exec php-fpm locale.

Add cron jobs

Add your cron jobs to workspace/crontab/laradock, after the php artisan line:

* * * * * laradock /usr/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1

# Custom cron
* * * * * root echo "Every Minute" > /var/log/cron.log 2>&1

Change the timezone if you don't want UTC. On Windows, make sure this file uses LF line endings, or the cron jobs silently fail.

Improve speed on macOS

Sharing code into containers via osxfs is slower than on Linux, which can hurt on larger projects (background). Modern Docker Desktop's VirtioFS reduces this a lot; if you still need more, the workarounds below help.

Workaround A: Dinghy

Dinghy creates its own VM via docker-machine without touching your existing docker-machine VMs.

  1. brew tap codekitchen/dinghy
  2. brew install dinghy
  3. dinghy create --provider virtualbox (VirtualBox required; other providers are supported)
  4. Copy the env variables it prints into your shell profile so Docker uses the VM's server.
  5. docker-compose up ...

Workaround B: d4m-nfs

You can use d4m-nfs either through Laradock's built-in integration or as a standalone tool.

B.1 — Built-in docker-sync integration

docker-sync runs an intermediate container holding a copy of your app files that the other containers read quickly, while a host process continuously syncs changes into it. It's preconfigured for macOS and works on Windows by changing DOCKER_SYNC_STRATEGY.

Laradock ships sync.sh to install, run, and stop docker-sync (you may need chmod 755 sync.sh).

  1. Configure Laradock as usual and confirm your sites work.
  2. Set DOCKER_SYNC_STRATEGY in .env (see the syncing strategies):
    # osx: 'native_osx' (default)
    # windows: 'unison'
    # linux: docker-sync not required

    DOCKER_SYNC_STRATEGY=native_osx
  3. Set APP_CODE_CONTAINER_FLAG=:nocopy in .env.
  4. Install the docker-sync gem on the host:
    ./sync.sh install
  5. Start docker-sync and the environment, naming the services you want (as with docker-compose up):
    ./sync.sh up nginx mysql

    The first run copies all files into the intermediate container, which can take 15+ minutes.

  6. Stop everything:
    ./sync.sh down

Optional aliases — add to ~/.bash_profile to avoid retyping:

alias devup="cd /PATH_TO_LARADOCK/laradock; ./sync.sh up nginx mysql" #add your services
alias devbash="cd /PATH_TO_LARADOCK/laradock; ./sync.sh bash"
alias devdown="cd /PATH_TO_LARADOCK/laradock; ./sync.sh down"

Additional commands:

./sync.sh bash # open bash on the workspace container
./sync.sh sync # manually trigger a sync
./sync.sh clean # remove the docker-sync container (host files untouched)

Notes:

  • You can run Laradock with or without docker-sync using the same .env and docker-compose.yml — the config is overridden automatically when docker-sync is used.
  • If a container can't access the synced files, set a user with UID 1000 in its Dockerfile (the UID nginx and php-fpm use). Changing permissions to 777 works but isn't recommended.

See the docker-sync documentation.

B.2 — Standalone d4m-nfs tool

d4m-nfs mounts an NFS volume instead of osxfs.

  1. In Docker's File Sharing preferences, remove everything except /tmp.
  2. Restart Docker.
  3. Clone d4m-nfs into your home directory:
    git clone https://github.com/IFSight/d4m-nfs ~/d4m-nfs
  4. Create ~/d4m-nfs/etc/d4m-nfs-mounts.txt with:
    /Users:/Users
  5. Make sure /etc/exports exists and is empty (watch for collisions from Vagrant or a previous run).
  6. Run the script (may need sudo):
    ~/d4m-nfs/d4m-nfs.sh
  7. Start your containers: docker-compose up ...

If you hit errors, restart Docker, ensure there are no spaces in d4m-nfs-mounts.txt, and confirm /etc/exports is clear.

Maintenance

Track your Laradock changes

To keep your Laradock customizations under version control while staying able to pull upstream updates:

  1. Fork the Laradock repository.
  2. Use your fork as a submodule.
  3. Commit your changes to your fork.
  4. Pull from the main repository periodically.

Upgrade Laradock

Moving from Docker Toolbox (VirtualBox) to Docker Desktop, and Laradock v3 to v4:

  1. Stop the docker VM: docker-machine stop {default}.
  2. Install Docker Desktop for Mac or Windows.
  3. Upgrade Laradock to v4.*.*: git pull origin master.
  4. Use Laradock as usual: docker-compose up -d nginx mysql.

If the last step fails, rebuild everything with docker-compose build --no-cache. Warning: container data might be lost.