Search by

Docker-based local development environment and CLI for Maho Commerce applications, orchestrating development runtimes and services.

Maintainers

Package info

github.com/empiricompany/harbor

Language:Shell

Type:maho-module

pkg:composer/empiricompany/harbor

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 2

Open Issues: 0

v0.1.0 2026-09-05 11:30 UTC

This package is auto-updated.

Last update: 2026-09-05 22:44:07 UTC


README

Harbor is a Docker-based local development environment for Maho Commerce. It provides a small Bash CLI around Docker Compose and convenient commands for the Maho containers.

Harbor is for local development only. It is not a production deployment or hardening solution.

Requirements

  • Docker with the Compose plugin;
  • a Maho project checkout;
  • Composer only to install or update the package.

All commands must be run from the Maho project root.

Install and start

composer require --dev empiricompany/harbor
./vendor/bin/harbor init
./vendor/bin/harbor up -d
./vendor/bin/harbor doctor

Harbor is a local-development tool, so --dev keeps it out of production installations.

init creates the local .harbor configuration. Review .harbor/.env before starting the stack. Do not commit .harbor/.env.

The first application image build may take several minutes:

./vendor/bin/harbor up -d --build

Daily commands

Stack lifecycle

./vendor/bin/harbor up -d
./vendor/bin/harbor up -d --build
./vendor/bin/harbor ps
./vendor/bin/harbor logs
./vendor/bin/harbor logs cron
./vendor/bin/harbor logs -f app
./vendor/bin/harbor stop
./vendor/bin/harbor restart
./vendor/bin/harbor down

down removes containers and the network but keeps volumes. To remove volumes as well, use:

./vendor/bin/harbor down -v

Warning: this permanently removes local database data. Harbor asks for confirmation and refuses this operation in non-interactive mode.

Commands in the app container

./vendor/bin/harbor php --version
./vendor/bin/harbor composer install
./vendor/bin/harbor maho cache:flush
./vendor/bin/harbor bin phpunit
./vendor/bin/harbor mysql --execute='SELECT 1'
./vendor/bin/harbor redis --raw ping

Shell access

./vendor/bin/harbor shell
./vendor/bin/harbor shell --service db
./vendor/bin/harbor root-shell

shell opens Bash in app by default. Use --service or -s to select a different running service. root-shell opens Bash as root in app.

Generic container commands

Use exec when no dedicated wrapper exists:

./vendor/bin/harbor exec --service app php -v
./vendor/bin/harbor exec --service app --user root bash
./vendor/bin/harbor exec --service app --no-tty php script.php

Options before the command:

  • --service/-s selects the Compose service;
  • --user/-u selects the container user;
  • --no-tty disables TTY allocation.

Compose customization

Harbor keeps the generated base configuration in .harbor/compose.yaml and loads these optional project-owned layers in order:

.harbor/compose.yaml
.harbor/docker.override.yaml
.harbor/docker.install.yaml

Do not edit the generated base file. Put local or persistent customizations in .harbor/docker.override.yaml; use .harbor/docker.install.yaml for services or settings needed during installation. Both files are optional and can be created manually.

Example: enable Xdebug and add a Node service:

services:
  app:
    environment:
      XDEBUG_MODE: develop,debug
    extra_hosts:
      - host.docker.internal:host-gateway

  node:
    image: node:22
    working_dir: /app
    volumes:
      - ../:/app
    networks:
      - harbor

Start the service and use it with exec:

./vendor/bin/harbor up -d
./vendor/bin/harbor exec --service node node --version

Xdebug

Xdebug is included in the default app image. Configure your IDE to listen for PHP debug connections on port 9003, then enable the debug environment in .harbor/docker.override.yaml:

services:
  app:
    environment:
      XDEBUG_MODE: develop,debug
      XDEBUG_CONFIG: client_host=host.docker.internal client_port=9003
    extra_hosts:
      - host.docker.internal:host-gateway

The XDEBUG_CONFIG value makes the app container connect back to the host IDE. Rebuild the app image after adding or changing this configuration:

./vendor/bin/harbor up -d --build
./vendor/bin/harbor debug -r 'echo "debug\n";'

Use harbor debug for requests that should start an Xdebug session. It enables xdebug.start_with_request=yes for that PHP invocation; regular php and maho commands do not force a debug session.

Inspect the Compose layers with:

./vendor/bin/harbor config

Keep secrets in .harbor/.env or environment variables, not in committed override files.

Scheduled Maho jobs

The stack runs the built-in Maho cron groups through Ofelia:

  • always: every minute;
  • default: every five minutes.

Add custom jobs to the app service in .harbor/docker.override.yaml:

services:
  app:
    labels:
      ofelia.job-exec.catalog-reindex.schedule: "@every 10m"
      ofelia.job-exec.catalog-reindex.command: "sh -c 'cd /app && ./maho indexer:reindex catalog_product_flat'"
      ofelia.job-exec.catalog-reindex.user: maho
      ofelia.job-exec.catalog-reindex.no-overlap: "true"

Use a unique job name, recreate the application container, and inspect the cron logs:

./vendor/bin/harbor up -d
./vendor/bin/harbor logs cron

Maho installation

Harbor does not create or modify app/etc/local.xml. The Maho installer owns that file.

For the web installer, open:

https://localhost:8443/

Use these internal database values:

Setting Value
Database host db
Database port 3306
Database name value from .harbor/.env
Database user value from .harbor/.env
Database password value from .harbor/.env
Database engine mysql
HTTPS URL https://localhost:8443/

For the CLI installer, run the Maho command in the app container:

./vendor/bin/harbor maho install \
  --license_agreement_accepted yes \
  --db_host db --db_name maho --db_user maho \
  --db_pass '<database password>' --db_engine mysql \
  --url https://localhost:8443/ --use_secure 1 \
  --secure_base_url https://localhost:8443/ \
  --admin_firstname Admin --admin_lastname User \
  --admin_email admin@example.test --admin_username admin \
  --admin_password '<admin password>'

Database backup and restore

Export with the Maho database command:

./vendor/bin/harbor maho db:export var/backups/backup.sql.gz --compression=gzip

Restore a backup only when you intend to replace the local database:

./vendor/bin/harbor down -v
./vendor/bin/harbor up -d
./vendor/bin/harbor maho db:import \
  /app/var/backups/backup.sql.gz \
  --compression=gzip --drop-tables

Warning: the down -v step permanently deletes the current database volume.

Optional services and URLs

Mailpit is included by default:

Web UI: http://localhost:8025
SMTP:   mailpit:1025 from containers

Optional services are controlled through Compose profiles. List available services and profiles with:

./vendor/bin/harbor services

Enable profiles through .harbor/.env or an override layer using HARBOR_PROFILES, for example:

HARBOR_PROFILES=redis,adminer

Adminer and phpMyAdmin use the default local URLs when enabled:

Adminer:    http://localhost:8082
phpMyAdmin: http://localhost:8081

Diagnostics and convenience commands

./vendor/bin/harbor doctor
./vendor/bin/harbor config
./vendor/bin/harbor open
./vendor/bin/harbor open admin
./vendor/bin/harbor open mailpit

doctor checks Docker, Compose, configuration, and running services. config renders the merged Compose configuration. open accepts app, admin, or mailpit and defaults to app.

Dev Containers

With VS Code and the Dev Containers extension installed:

./vendor/bin/harbor up -d
./vendor/bin/harbor devcontainer

Reopen the project in the generated container. Use --force to replace an existing configuration:

./vendor/bin/harbor devcontainer --force

Contributing

See CONTRIBUTING.md for the development workflow and quality checks.

License

Harbor is released under the MIT License. See LICENSE.