{"id":20037049,"url":"https://github.com/antistatique/docker-php-dev","last_synced_at":"2026-05-06T09:40:20.312Z","repository":{"id":44910310,"uuid":"165024583","full_name":"antistatique/docker-php-dev","owner":"antistatique","description":"Docker image for Drupal development environment","archived":false,"fork":false,"pushed_at":"2022-08-14T20:25:16.000Z","size":429,"stargazers_count":3,"open_issues_count":12,"forks_count":0,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-01-12T18:51:53.634Z","etag":null,"topics":["docker","docker-image"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/antistatique/php-dev","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antistatique.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-10T08:50:37.000Z","updated_at":"2023-05-05T15:25:50.000Z","dependencies_parsed_at":"2022-09-05T13:10:48.043Z","dependency_job_id":null,"html_url":"https://github.com/antistatique/docker-php-dev","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antistatique%2Fdocker-php-dev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antistatique%2Fdocker-php-dev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antistatique%2Fdocker-php-dev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antistatique%2Fdocker-php-dev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antistatique","download_url":"https://codeload.github.com/antistatique/docker-php-dev/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241466521,"owners_count":19967476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-image"],"created_at":"2024-11-13T10:17:57.975Z","updated_at":"2026-05-06T09:40:15.282Z","avatar_url":"https://github.com/antistatique.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Docker image for PHP+Node development\n\n![GH Workflow Status](https://github.com/antistatique/docker-php-dev/workflows/.github/workflows/ci.yml/badge.svg)\n\n## Setup\n\nA `docker-compose.yml` file must be created in project working directory. Follow setup related to\nthe project type. This image support any PHP/Node project and have an apache server running and\nrendering content in the working diretory. Folling type of project have a dedicted helper tool:\n\n* Drupal (`docker-as-drupal`)\n\nThe volume `/var/www` can have a delay before updates made on the host are visible in the\ncontainer ; remove `:cached` if it's an issue but that will result to slowest command\nexecution time in docker\n\n### PHP \u0026 Node versions\n\nThe version for PHP and Node can be selected in image tag, follwing versions are availables :\n\n* PHP 5.6\n  * Node 8\n* PHP 7.0\n  * Node 8\n  * Node 10\n* PHP 7.1\n  * Node 6\n  * Node 8\n  * Node 9\n  * Node 10\n  * Node 11\n  * Node 12\n* PHP 7.2\n  * Node 8\n  * Node 9\n  * Node 10\n  * Node 11\n  * Node 12\n* PHP 7.3\n  * Node 10\n  * Node 11\n  * Node 12\n* PHP 7.4\n  * Node 10\n  * Node 11\n  * Node 12\n * PHP 8.0\n  * Node 12\n  * Node 14\n\n### Drupal setup\n\nThis setup using _Mailcatcher_ as mail server, and mysql as database (remove mail service if\nnot required).\n\nFollowing environement variable are available:\n\n```bash\nAPACHE_DOCUMENT_ROOT          # Apache Document Root (default to \"/var/www/web\")\nPHP_MEMORY_LIMIT              # Set PHP mermory limit (default to \"256M\")\n\nAPP_ENV                       # Eq: development, test, production. This environment variable\n                              # is used to load specific settings per environment.\n\nDATABASE_URL                  # Database URL scheme, should be different for dev and test services\nDATABASE_DUMP                 # Database dump file path (default to \"/var/backups/db-reset.sql\"). Must\n                              # be located in a volume shared by dev and test services.\nSMTP_HOST                     # \u003chost:port\u003e to mail server (default to mail:1025 as docker mailcatcher service)\nSITE_NAME                     # Drupal site name (default set to \"Drupal Website\")\nSITE_CONFIG_DIR               # Drupal configuration sync directory (default to /var/www/config/d8/sync)\nSITE_UUID                     # Drupal site UUID (default set to UUID in system.side.yml file)\nSITE_HASH_SALT                # Drupal hash salt (default to random string)\nSITE_INSTALL_PROFILE          # Drupal installation profile (default to standard)\nPRIVATE_FILES                 # Path to private files diretory (add it to settings on bootstrap)\nDEFAULT_CONTENT               # Default content modules to use\nLOG_DIR                       # Default to /var/www/log (behat and phpunit output directories are inside)\nREQUIRED_DIRECTORIES          # List of directories to create (separate by space)\nDRUPAL_CONFIG_SET             # Configurations keys to be overriden\n\nBEHAT_PROFILE                 # Behat config profile (default to \"default\")\nPHPUNIT_DEFAULT_GROUP         # Default phpunit group used if \"--group\" is not set\nSIMPLETEST_BASE_URL           # Default to \"http://test:8888\"\nSIMPLETEST_DB                 # Default to DATABASE_URL, can be overwrited\nSYMFONY_DEPRECATIONS_HELPER   # Default to weak, can be overwrited\nTEST_SERVER_PORT              # Default to 8888\nCONFIG_IMPORT_ATTEMPTS        # Number of attemps to run config:import (default to 5)\n\nDISABLE_DEVELOPMENT           # Set to disable development mode (that means we skip some restore\n                              # steps after running tests or other stuff like that. Use for one\n                              # time running container)\nLOCK_TIME                     # Lock time on running server and when run tests. Use format \"2018-12-24 12:24:00\"\n                              # See https://github.com/wolfcw/libfaketime for more information\nTEST_ENABLE_MODULES           # Modules to enable when running tests, separate by space\nTEST_DISABLE_MODULES          # Modules to disable when running tests, separate by space (default: big_pipe)\nTEST_USER                     # Set a default user to run tests\n```\n\n`behat.yml` file must have a docker profile and MailCatcher webmail url can be setup like\nin follwing example if used:\n\n```yaml\ndocker:\n  extensions:\n    Alex\\MailCatcher\\Behat\\MailCatcherExtension\\Extension:\n      url: http://mail:1080\n```\n\n`docker-compose.yml`:\n\n```yaml\nversion: '3.6'\n\nservices:\n  # Drupal development server\n  dev:\n    image: antistatique/php-dev:7.1-node8\n    ports:\n      - \"8080:80\"\n    depends_on:\n      - db\n      - mail\n    environment:\n      APP_ENV: development\n      DATABASE_URL: mysql://drupal:drupal@db/drupal_development\n      PRIVATE_FILES: /var/www/web/sites/default/files/private\n      DEFAULT_CONTENT: project_default_content\n    restart: always\n    volumes:\n      - .:/var/www:cached\n      - backups:/var/backups\n\n  # Drupal test server\n  test:\n    image: antistatique/php-dev:7.1-node8\n    command: docker-as-wait --mysql -- docker-as-drupal apache-server\n    ports:\n      - \"8888:8888\"\n    depends_on:\n      - db\n      - mail\n    environment:\n      APP_ENV: test\n      DATABASE_URL: mysql://drupal:drupal@db/drupal_test\n      PRIVATE_FILES: /var/www/web/sites/default/files/private\n      DEFAULT_CONTENT: project_default_content\n    restart: \"no\"\n    volumes:\n      - .:/var/www:cached\n      - backups:/var/backups\n\n  # Database\n  db:\n    image: mariadb:10.1\n    ports:\n      - \"3306:3306\"\n    environment:\n      MYSQL_USER: drupal\n      MYSQL_PASSWORD: drupal\n      MYSQL_DATABASE: drupal\\_%\n      MYSQL_ROOT_PASSWORD: root\n    restart: always\n    volumes:\n      - database:/var/lib/mysql\n\n  # Mail\n  mail:\n    image: schickling/mailcatcher\n    ports:\n      - \"1025:1025\"\n      - \"1080:1080\"\n    restart: always\n\nvolumes:\n  database:\n  backups:\n```\n\n**settings.php files**\nYou can create different PHP settings file based on the `APP_ENV` environment.\nThe format is `${APP_ENV}.settings.php`:\n\n```\n# ./web/sites/default/development.settings.php\n\n$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';\n$config['backerymails.settings']['reroute']['status'] = TRUE;\n// ...\n```\n\nFinally, a local settings PHP file is loaded if you create the script `./web/sites/default/settings.local.php`.\n\nUse `docker-compose up` to start services then following command to boostrap (or reset) the\nDrupal installation: `docker-compose exec dev docker-as-drupal bootstrap`. Test service must\nbe started manualy after bootstrap by running `docker-compose restart test`.\n\n\n**DRUPAL_CONFIG_SET**\n\nThe Drupal Configurations Override environement variable is kind of special. It may contain 1 or many items te be declared as follow:\n\nSingle\n```\n  DRUPAL_CONFIG_SET: \u003e-\n    search_api.server.solr backend_config.connector_config.host solr\n```\n\nMultiple\n```\n  DRUPAL_CONFIG_SET: \u003e-\n    search_api.server.solr backend_config.connector_config.host solr;\n    search_api.server.solr backend_config.connector_config.core watchdreamer\n```\n\n_Note the trailing `;` at the end of each line - excepted on the last one._\n\n### Custom docker image\n\nTo install more packages or change some setup in docker image, a local `Dockerfile` can  be created\nand the `docker-compose.yml` file must be updated to use _build_ instead of _image_ config.\n`Dockerfile` _FROM_ tag must be set properly, refer to comment in following file example for more\ninformation about how to install a package or enable PHP extension.\n\n```yaml\nservices:\n  dev:\n    build: .\n```\n\n```Dockerfile\nFROM antistatique/php-dev:7.2-node11\n\n# Install dependencies\nRUN set -ex; \\\n  \\\n  mkdir -p /usr/share/man/man1 /usr/share/man/man7; \\\n  \\\n  if command -v a2enmod; then \\\n    a2enmod rewrite; \\\n  fi; \\\n  \\\n  savedAptMark=\"$(apt-mark showmanual)\"; \\\n  \\\n  # install the installation dependencies we need\n  apt-get update; \\\n  # apt-get install -y --no-install-recommends \\\n  #  libjpeg-dev \\\n  #  libpng-dev \\\n  #  libpq-dev \\\n  #  libzip-dev \\\n  #  gnupg \\\n  #; \\\n  \\\n  # install the PHP extensions we need\n  # docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr; \\\n  # docker-php-ext-install -j \"$(nproc)\" \\\n  #   gd \\\n  #   opcache \\\n  #   pdo_mysql \\\n  #   pdo_pgsql \\\n  #   zip \\\n  # ; \\\n  # \\\n  # install xdebug for PHP 7.x\n  # if [ $(echo \"%%PHP_VERSION%% \u003e= 7.0\" | bc -l) -eq 1 ]; then \\\n  #   pecl install xdebug; \\\n  #   docker-php-ext-enable \\\n  #     xdebug \\\n  #   ; \\\n  # fi; \\\n  \\\n  # reset apt-mark's \"manual\" list so that \"purge --auto-remove\" will remove all build dependencies\n  apt-mark auto '.*' \u003e /dev/null; \\\n  apt-mark manual $savedAptMark; \\\n  ldd \"$(php -r 'echo ini_get(\"extension_dir\");')\"/*.so \\\n    | awk '/=\u003e/ { print $3 }' \\\n    | sort -u \\\n    | xargs -r dpkg-query -S \\\n    | cut -d: -f1 \\\n    | sort -u \\\n    | xargs -rt apt-mark manual; \\\n  \\\n  # install running dependencies (custom sources can be add here)\n  # curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - ; \\\n  # echo \"deb http://dl.yarnpkg.com/debian/ stable main\" | tee /etc/apt/sources.list.d/yarn.list; \\\n  \\\n  apt-get update; \\\n  # apt-get install -y --no-install-recommends \\\n  #   unzip \\\n  # ; \\\n  \\\n  apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \\\n  rm -rf /var/lib/apt/lists/*\n\n# Add local setup here\n\n```\n\n## Usage\n\nStart services with `docker-compose up`, _CTRL+C_ to stop them. `--build` option can be use when\na custom `Dockerfile` exists to force to re-build the image.\n\n`docker-compose` use directory name as default project name to prefix container and volume\nname, that can be overrided with `-p \u003cname\u003e` options in case of conflict.\n\n### Managing docker\n\n```bash\ndocker-compose up             # Start services (CTRL+C to stop)\ndocker-compose up -d          # Start services (deamonize)\ndocker-compose up --build     # Start services and force build of local Dockerfile if exists\ndocker-compose pull           # Pull remote images (to update them)\n\ndocker-compose stop           # Stop services\ndocker-compose down           # Remove containers and network interfaces (do not remove db storage)\ndocker-compose rm             # Remove all stopped service containers\n\ndocker-compose log            # Display services' log (-f to follow log output)\n\ndocker system prune           # Remove unused data (dandling images, stopped containers, unused\n                              # networks and build caches)\ndocker system prune --all     # Remove all images, containers and networks\ndocker volume ls              # list all existing volums (on computer)\ndocker volume rm \u003cvolume\u003e     # Remove named volume (to reset database)\n\n# Run the commmand in existing service container\ndocker-compose exec \u003cservice name\u003e \u003ccomand\u003e\n```\n\n### Drupal\n\n\n`docker-as-drupal` script is used to manage database, Drupal install or run behat.\n\n*bootstrap* must be run to setup Drupal project, that will install dependencies, install\nDrupal, setup database and all required settings. A database dump is also created before\nloading default content to be used to setup test environment (or reseet default content\nlater).\n\nAvailable options are:\n\n```bash\ndocker-compose exec dev docker-as-drupal bootstrap [options]\n\n  --skip-dependencies      # Do not run composer and yarn install\n  --skip-install           # Do not run Drupal install (only if arealdy installed)\n  --skip-db-reset          # Do not reset database using SQL dump (only when --skip-install)\n  --skip-styleguide-build  # Do not run yarn build\n  --with-default-content   # Load default content (force reset database when --skip-install)\n  --install-only           # Same ass --skip-dependencies --skip-styleguide-build\n```\n\n*setup* ensure that Drupal settings.php file is populated and docker related settings are\nproperly set. Except install dependencies, same process is done before most of other commands.\n\n```bash\ndocker-compose exec dev docker-as-drupal setup [options]\n\n  --with-dependencies      # Run composer and yarn install\n```\n\n*db-reset* reset database using database dump made by last bootstrap command or _db-reset_\ncommand.\n\nAvailable options are:\n\n```bash\ndocker-compose exec dev docker-as-drupal db-reset [options]\n\n  --update-dump            # Update database dump (include updated Drupal config, but not\n                           # default content)\n  --with-default-content   # Load default content (before dump)\n```\n\n*db-dump* dump database. The dump can be used with _db-restore_ to reset database to saved\nstate.\n\nAvailable options are:\n\n```bash\ndocker-compose exec dev docker-as-drupal db-dump [options]\n\n    --file=\u003cpath\u003e            # Path to dump file (not required)\n```\n\n*db-restore* reset database to saved state using database dump made by last _db-dump_.\n\nAvailable options are:\n\n```bash\ndocker-compose exec dev docker-as-drupal db-restore [options]\n\n    --file=\u003cpath\u003e            # Path to dump file (not required)\n```\n\n*db-update* update database, entities and import config.\n\n*php-server* run `drush runserver $TEST_SERVER_HOST:$TEST_SERVER_PORT` command.\n\nAvailable options are:\n\n```bash\ndocker-compose exec test docker-as-drupal php-server [options]\n\n  --with-db-reset          # Reset database before launch server\n  --with-default-content   # Load default content (force reset database)\n  --help                   # Display runserver help\n  -- \u003c...\u003e                 # any runserver valid args\n```\n\n*apache-server* run `apache2 -D FOREGROUND -c \"DocumentRoot $APACHE_DOCUMENT_ROOT\" -c \"Listen $TEST_SERVER_PORT\"` command.\n\nAvailable options are:\n\n```bash\ndocker-compose exec test docker-as-drupal apache-server [options]\n\n  --with-db-reset          # Reset database before launch server\n  --with-default-content   # Load default content (force reset database)\n  --cache                  # Do not invalidate opcache (server must be restarted\n                            # reload cache)\n  --help                   # Display apache help\n  -- \u003c...\u003e                 # any apache valid args\n```\n\n*behat* setup database and settings properly then run behat command including any options\nlike file path, _--rerun_ or more.\n\nAvailable options are:\n\n```bash\ndocker-compose exec test docker-as-drupal behat [options]\n\n  --skip-db-reset          # Do not reset database (to use only if database was reset just before)\n  --skip-default-content   # Do not load default content (maybe break the tests, ignored when db is reset)\n  --with-dependencies      # Run composer and yarn install\n  --help                   # Display behat help\n  -- \u003c...\u003e                 # any behat valid args\n```\n\n*nightwatch* setup database and settings properly then run nightwatch command. `--group` is required\nas Drupal nightwatch tests doesn't pass without more config.\n\nAvailable options are:\n\n```bash\ndocker-compose exec test docker-as-drupal nightwatch [options]\n\n  --skip-db-reset          # Do not reset database (to use only if database was reset just before)\n  --skip-default-content   # Do not load default content (maybe break the tests, ignored when db is reset)\n  --with-dependencies      # Run composer and yarn install\n  --group=\u003cgroup\u003e          # Only runs tests from the specified group(s)\n  --help                   # Display behat help\n  -- \u003c...\u003e                 # any behat valid args\n```\n\n*phpunit* setup database and settings properly then run phpunit command including any options\nlike file path, _--stop-on-failure_ or more.\n\nAvailable options are:\n\n```bash\ndocker-compose exec test docker-as-drupal phpunit [options]\n\n  --skip-db-reset          # Do not reset database (to use only if database was reset just before),\n                           # only valid with --skip-db-empty or --with-defaut-content\n  --skip-default-stops     # Do not stop on error and failure (remove --stop-on-error --stop-on-failure)\n  --with-default-content   # Load default content (force reset database if --skip-db-reset is not used)\n  --skip-default-stops     # Do not stop on error and failure (remove --stop-on-error --stop-on-failure)\n  --with-default-content   # Load default content (force reset database if --skip-db-reset is not used)\n  --with-dependencies      # Run composer and yarn install\n  --group=\u003cgroup\u003e          # Only runs tests from the specified group(s)\n  --exclude-group=\u003cgroup\u003e  # Exclude tests from the specified group(s)\n  --tests-only             # Same as --skip-db-empty\n  --help                   # Display phpunit help\n  -- \u003c...\u003e                 # any phpunit valid args\n```\n\n*quality-check* run tools like _phpcs_, _phpmd_ and _phpcpd_ and print a report about code issues. This\naction don't fail if any of theses commands reporting errors.\n\nAvailable options are:\n\n```bash\ndocker-compose exec test docker-as-drupal quality-check [options]\n\n  --skip-phpcs             # Do not run phpcs\n  --skip-phpmd             # Do not run phpmd\n  --skip-phpcpd            # Do not run phpcpd\n  --fail-on-phpcs          # Command fail if phpcs fail too\n  --fail-on-phpmd          # Command fail if phpmd fail too\n  --fail-on-phpcpd         # Command fail if phpcpd fail too\n```\n\n## Work on the docker image\nA [Github Action Workflow](.github/workflows/ci.yml) is responsible to test, build and publish docker image.\n\nYou can also locally build all images or a specific one:\n\n```bash\n./tools.sh --build=\u003c7.2-node9|all|latest\u003e\n```\n\nRun tests (you will need first to install [container-structure-test](https://github.com/GoogleContainerTools/container-structure-test)):\n\n```bash\n./tools.sh --test=\u003c7.2-node9|all|latest\u003e\n```\n\nBut all of this is automated with Github.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantistatique%2Fdocker-php-dev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantistatique%2Fdocker-php-dev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantistatique%2Fdocker-php-dev/lists"}