├── workspace ├── .composer │ └── .gitkeep └── test │ └── project │ └── htdocs │ ├── index.html │ └── info.php ├── conf └── .gitignore ├── bin ├── dev_command │ ├── changephp │ ├── status │ ├── npm │ ├── downup │ ├── php │ ├── restart │ ├── yarn │ ├── magerun │ ├── trap │ ├── magerun2 │ ├── workspace │ ├── varnishadm │ ├── compose │ ├── start │ ├── ps │ ├── config │ ├── down │ ├── stop │ ├── logs │ ├── rm │ ├── custom │ ├── profile │ ├── exec │ ├── composer1 │ ├── xdebug-console │ ├── composer2 │ ├── run │ ├── top │ ├── git │ ├── node │ ├── php-ext-disable │ ├── varnish-vcl-disable │ ├── open-url │ ├── php-ext-enable │ ├── rebuild │ ├── mytop │ ├── web-url │ ├── update │ ├── console │ ├── expose │ ├── mysql │ ├── mysqldump │ ├── cp │ ├── varnish-vcl-import │ ├── myroot │ ├── ngrok │ ├── usage │ ├── images │ ├── build │ ├── php-change │ ├── blackfire │ ├── up │ ├── setup-mysql │ ├── volume │ └── setup ├── composer ├── composer2 ├── mysql ├── php ├── blackfire ├── magerun ├── magerun2 ├── mysqldump └── dev ├── .gitignore ├── conf.d └── mysql │ └── my.cnf ├── docker-sync.yml ├── docs ├── ufw-firewall.md ├── configure-blackfire.md ├── sharing-with-the-world-via-ngrok.md ├── customize-docker-containers.md ├── used-base-images.md ├── how-to-use-different-php-versions.md ├── mysql-mailhog-redis-cronjobs.md ├── hosts-and-file-structure.md ├── elasticsearch.md ├── install-other-php-versions.md ├── mongodb.md ├── ftp.md ├── opensearch-dashboard.md ├── rabbitmq.md ├── opensearch.md ├── expose.md ├── development-commands.md ├── node-npm-yarn.md ├── xdebug.md ├── varnish.md ├── code-of-conduct.md ├── environment-configuration.md ├── mysql8.md ├── docker-volumes.md ├── search-ui-tools.md ├── php-extensions.md ├── monitoring-tools.md ├── faq.md ├── custom-compose-files.md ├── git-ssh-integration.md ├── port-reference.md ├── advanced-docker-configuration.md ├── backup-restore.md └── performance-tuning.md ├── LICENSE ├── docker-compose.yml └── README.md /workspace/.composer/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workspace/test/project/htdocs/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /conf/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !/.gitignore 3 | !mysql 4 | -------------------------------------------------------------------------------- /bin/dev_command/changephp: -------------------------------------------------------------------------------- 1 | 2 | . ./php-change "$@"; 3 | 4 | -------------------------------------------------------------------------------- /bin/dev_command/status: -------------------------------------------------------------------------------- 1 | 2 | # Just an alias 3 | . ./ps 4 | 5 | -------------------------------------------------------------------------------- /workspace/test/project/htdocs/info.php: -------------------------------------------------------------------------------- 1 | /dev/null; then 9 | dc yml build/dist/docker-compose-db8client.yml; 10 | dc cmd mysql "-h db8 -u ${USER}"; 11 | else 12 | dc yml build/dist/docker-compose-dbclient.yml; 13 | dc cmd mysql "-h db -u ${USER}"; 14 | fi 15 | 16 | dc run "$@"; 17 | return $?; 18 | 19 | -------------------------------------------------------------------------------- /bin/dev_command/mysqldump: -------------------------------------------------------------------------------- 1 | 2 | dc service 'dbclient'; 3 | 4 | dc nodeps; 5 | dc interactive; 6 | dc ignore_orphans; 7 | 8 | if dc stopfile mysql8 >/dev/null; then 9 | dc yml build/dist/docker-compose-db8client.yml; 10 | dc cmd mysqldump "-h db8 -u ${USER}"; 11 | else 12 | dc yml build/dist/docker-compose-dbclient.yml; 13 | dc cmd mysqldump "-h db -u ${USER}"; 14 | fi 15 | 16 | dc run "$@"; 17 | return $?; 18 | 19 | -------------------------------------------------------------------------------- /bin/dev_command/cp: -------------------------------------------------------------------------------- 1 | 2 | replace_container() { 3 | local a="$1"; 4 | 5 | if [ "${a/://}" == "$a" ]; then 6 | echo $a; 7 | return 0; 8 | fi 9 | 10 | local container=${a%:*}; 11 | echo "${DEV_PROJECT}_${container}_1:${a#*:}"; 12 | return 0; 13 | } 14 | 15 | from=`replace_container $1`; 16 | to=`replace_container $2`; 17 | 18 | cd ${DEV_USERDIR}; 19 | 20 | docker cp "${from}" "${to}"; 21 | return $?; 22 | 23 | -------------------------------------------------------------------------------- /bin/dev_command/varnish-vcl-import: -------------------------------------------------------------------------------- 1 | local outfile=${DEV_WORKPATH}/conf/varnish.vcl; 2 | local infile=${DEV_USERDIR}/$1; 3 | 4 | if [ -n "$1" ]; then 5 | cd ${DEV_PATH}; 6 | ./${DEV_SELF} rm web varnish ssl; 7 | 8 | cat ${infile} | sed '/.probe = {/,/}/d' > ${outfile}; 9 | ./${DEV_SELF} up web varnish ssl; 10 | return 0; 11 | else 12 | echo "usage: ${DEV_SELF} ${DEV_COMMAND} path/to/file.vcl"; 13 | return 1; 14 | fi 15 | 16 | -------------------------------------------------------------------------------- /bin/dev_command/myroot: -------------------------------------------------------------------------------- 1 | 2 | dc service dbclient; 3 | 4 | dc nodeps; 5 | dc interactive; 6 | dc ignore_orphans; 7 | 8 | if dc stopfile mysql8 >/dev/null; then 9 | dc yml build/dist/docker-compose-db8client.yml; 10 | dc cmd mysql "-hdb8 -uroot -p${MYSQL_ROOT_PASSWORD}"; 11 | else 12 | dc yml build/dist/docker-compose-dbclient.yml; 13 | dc cmd mysql "-hdb -uroot -p${MYSQL_ROOT_PASSWORD}"; 14 | fi 15 | 16 | dc run "$@"; 17 | return $?; 18 | 19 | -------------------------------------------------------------------------------- /bin/dev_command/ngrok: -------------------------------------------------------------------------------- 1 | 2 | if [ -n "$1" ]; then 3 | DEV_HOSTNAME="$1"; 4 | fi 5 | 6 | if [ -z "${DEV_HOSTNAME}" ]; then 7 | return 1; 8 | fi 9 | 10 | WEB_IP=`. ./exec ssl ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'`; 11 | 12 | dc yml build/dist/docker-compose-ngrok.yml; 13 | dc nodeps; 14 | 15 | dc opt '--entrypoint=/bin/ngrok'; 16 | dc service ngrok; 17 | 18 | dc cmd 'http --host-header='${DEV_HOSTNAME}' '${WEB_IP}':80'; 19 | 20 | dc run "$@"; 21 | return $?; 22 | 23 | -------------------------------------------------------------------------------- /bin/dev_command/usage: -------------------------------------------------------------------------------- 1 | 2 | echo "Usage ${DEV_SELF} [COMMAND]" 3 | echo ''; 4 | echo 'COMMAND:' 5 | for command in `ls`; do 6 | echo " - $command"; 7 | done 8 | 9 | if [ ! -e ${DEV_WORKSPACE_PATH}/bin ]; then 10 | return 1; 11 | fi 12 | 13 | echo ''; 14 | echo 'COMMAND: (custom)'; 15 | 16 | cd ${DEV_WORKSPACE_PATH}/bin; 17 | for command in `ls`; do 18 | if [ ! -x `realpath ${command}` ]; then 19 | continue; 20 | fi 21 | 22 | echo " - $command"; 23 | done 24 | 25 | return 1; 26 | 27 | -------------------------------------------------------------------------------- /bin/dev_command/images: -------------------------------------------------------------------------------- 1 | 2 | dc yml_local; 3 | dc yml_all; 4 | dc mode config; 5 | 6 | { dc run; cat ${DEV_WORKPATH}/build/*/*/Dockerfile; } | \ 7 | grep -hE '(image:|FROM |FROM_TAG:)' | \ 8 | grep -v FROM_IMAGE | \ 9 | sed \ 10 | -e 's#FROM_TAG: #srcoder/development-php:#' \ 11 | -e 's#image:##' \ 12 | -e 's#FROM ##' \ 13 | -e 's/$/:latest/' \ 14 | -e 's/\(:[^:]*\):latest$/\1/' | \ 15 | awk '{print $1}' | \ 16 | sort | \ 17 | uniq; 18 | 19 | return 0; 20 | 21 | -------------------------------------------------------------------------------- /bin/dev_command/build: -------------------------------------------------------------------------------- 1 | 2 | dc yml_all; 3 | dc yml_local; 4 | 5 | services=$(. ./config --services); 6 | if [ -n "$*" ]; then 7 | services="$@"; 8 | fi 9 | 10 | user_id=`id -u`; 11 | group_id=`id -g`; 12 | 13 | args=''; 14 | if [ -n "${user_id}" ]; then 15 | args=${args}' --build-arg=UID='${user_id}; 16 | fi 17 | if [ -n "${group_id}" ]; then 18 | args=${args}' --build-arg=GID='${group_id}; 19 | fi 20 | 21 | dc mode build; 22 | dc cmd "${args}"; 23 | 24 | for a in ${services}; do 25 | dc run "${a}"; 26 | done 27 | return 0; 28 | 29 | -------------------------------------------------------------------------------- /docs/configure-blackfire.md: -------------------------------------------------------------------------------- 1 | # Configure Blackfire 2 | The Blackfire library is already available in PHP, but not loaded by default. 3 | To load blackfire, simply add a `conf/blackfire` file with content from the [Blackfire website][1]. 4 | Copy/paste the contents from the env vars including their names in the configuration file `conf/blackfire` (make sure you are logged in). 5 | `./bin/dev/down` and `./bin/dev/up` to load Blackfire. 6 | 7 | Make sure to list all 4 env variables; 8 | 9 | ``` 10 | BLACKFIRE_CLIENT_ID= 11 | BLACKFIRE_CLIENT_TOKEN= 12 | BLACKFIRE_SERVER_ID= 13 | BLACKFIRE_SERVER_TOKEN= 14 | ``` 15 | 16 | [1]: https://blackfire.io/docs/integrations/docker#documentation 17 | 18 | -------------------------------------------------------------------------------- /docs/sharing-with-the-world-via-ngrok.md: -------------------------------------------------------------------------------- 1 | # Sharing with the world via Ngrok.io 2 | ## Ngrok service 3 | This is a service lets you share your progress with the world via a generated URL. 4 | 5 | ## Using this service 6 | From within you project directory(let's say workspace/test/project) invoke `dev ngrok` 7 | This will display a generated URL inside the command line which you can share with the world. Following that URL will take you to your project. 8 | 9 | You can also run `dev ngrok test.project.localhost` (or the subdomain you've chosen in your configuration) from anywhere and this will generate a URL which forwards to the given domain. This is also useful when using a custom service like Magento, Silex or Symfony. 10 | -------------------------------------------------------------------------------- /docs/customize-docker-containers.md: -------------------------------------------------------------------------------- 1 | # Customize Docker Containers 2 | Of course you would love day-to-day updates and still have room to add your own changes. 3 | Just add a `docker-custom.yml`, add `version: '2'` to the top and override whatever you want. 4 | 5 | `docker-custom.yml` and the `./custom` directory are excluded from git. 6 | 7 | For example: to add a custom components to the default PHP, add the following `docker-custom.yml` file: 8 | 9 | ```yaml 10 | version: '2' 11 | 12 | services: 13 | php: 14 | build: custom/php7 15 | ``` 16 | 17 | This won't build the regular php7 directory, instead it will run build in the custom directory. 18 | So, next up you copy the php/Dockerfile and add your own additions which will be build everytime updates are available. 19 | -------------------------------------------------------------------------------- /bin/dev_command/php-change: -------------------------------------------------------------------------------- 1 | 2 | echo 'PHP configured version '${DEV_PHP}; 3 | 4 | local versions="`dc php_versions`" v='' version='' dir=${DEV_WORKSPACE_PATH}; 5 | 6 | if [ -z "$1" ]; then 7 | return 0; 8 | fi 9 | 10 | for v in ${versions}; do 11 | if [ "$1" == "${v}" ]; then 12 | version=${v}; 13 | fi 14 | done 15 | 16 | if [ -z "${version}" ]; then 17 | echo 'Provide valid PHP version `dev php-change {VERSION}`'; 18 | echo ${versions}; 19 | return 1; 20 | fi 21 | 22 | if [ "${version}" == "${DEV_PHP}" ]; then 23 | return 2; 24 | fi 25 | 26 | if [ -n "${DEV_PROJECTPATH}" ]; then 27 | dir=${DEV_WORKSPACE_PATH}/${DEV_PROJECTPATH}; 28 | fi 29 | 30 | echo 'Update to '${version}; 31 | 32 | rm ${dir}/.php[1-9][0-9] >/dev/null 2>&1; 33 | touch ${dir}/.${version}; 34 | return 0; 35 | 36 | -------------------------------------------------------------------------------- /bin/dev_command/blackfire: -------------------------------------------------------------------------------- 1 | 2 | dc yml_if 'build/dist/docker-compose-blackfireclient.yml' 'conf/blackfire'; 3 | if [ $? -ne 0 ]; then 4 | echo 'Blackfire not initialized'; 5 | return 1; 6 | fi 7 | 8 | if [ "$1" != "run" ]; then 9 | dc service blackfireclient; 10 | dc cmd blackfire; 11 | 12 | dc interactive; 13 | dc ignore_orphans; 14 | dc opt "--no-deps"; 15 | dc run "$@"; 16 | return $?; 17 | else 18 | dc service blackfire; 19 | bf_q=$(dc run blackfire run /usr/local/bin/dev 2>&1 | grep BLACKFIRE_QUERY); 20 | 21 | bf_r=$(echo $bf_q | sed -e 's#^.*request-id-\([^&]*\)&.*$#\1#'); 22 | echo 'Profile will be uploaded to: http://blackfire.io/profiles/'${bf_r}'/graph'; 23 | 24 | dc opt "-e ${bf_q}"; 25 | shift; 26 | 27 | . ./console "$@"; 28 | return $?; 29 | fi 30 | 31 | -------------------------------------------------------------------------------- /bin/dev_command/up: -------------------------------------------------------------------------------- 1 | 2 | if [ -z "`${DEV_SUDO} docker volume ls -q -f 'name=dockerdev-mysql-volume'`" ]; then 3 | echo 'No MySQL volume found, first time here? Run `bin/dev setup` to setup the important stuff'; 4 | return 1; 5 | fi 6 | if [ -z "`${DEV_SUDO} docker volume ls -q -f 'name=dockerdev-workspace-volume'`" ]; then 7 | echo 'No Workspace volume found, first time here? Run `bin/dev setup` to setup the important stuff'; 8 | echo 'If you see this message after upgrading, we have implemented a way to choose the location'; 9 | echo 'for workspace instead of the default inside this repository, just run `bin/dev setup` and you will be ready to go'; 10 | return 1; 11 | fi 12 | 13 | if [ -z "${DOMAINSUFFIX}" ]; then 14 | dc yml build/dist/docker-compose-suffix.yml; 15 | fi 16 | 17 | dc yml_local; 18 | dc opt '-d --no-recreate'; 19 | dc mode 'up'; 20 | dc run "$@"; 21 | return $?; 22 | 23 | -------------------------------------------------------------------------------- /docs/used-base-images.md: -------------------------------------------------------------------------------- 1 | # Base images 2 | Currently the following base images are used. Trying to rely on official images as much as possible. 3 | - blackfire -> [blackfire/blackfire:latest](https://hub.docker.com/r/blackfire/blackfire/) 4 | - nginx -> [nginx:alpine](https://hub.docker.com/r/_/nginx/) 5 | - percona -> [percona:latest](https://hub.docker.com/r/_/percona/) 6 | - php -> [srcoder/development-php:7.0-fpm](https://hub.docker.com/r/srcoder/development-php/) 7 | - php5 -> [srcoder/development-php:5.6-fpm](https://hub.docker.com/r/srcoder/development-php/) 8 | - php71 -> [srcoder/development-php:7.1-fpm](https://hub.docker.com/r/srcoder/development-php/) 9 | - redis -> [redis:alpine](https://hub.docker.com/r/_/redis/) 10 | - mailhog -> [mailhog/mailhog:latest](https://hub.docker.com/r/mailhog/mailhog/) 11 | - mytop -> [srcoder/mytop:latest](https://hub.docker.com/r/srcoder/mytop/) 12 | - ctop -> [wrfly/ctop](https://hub.docker.com/r/wrfly/ctop/) 13 | -------------------------------------------------------------------------------- /docs/how-to-use-different-php-versions.md: -------------------------------------------------------------------------------- 1 | # How to use different PHP versions 2 | 3 | We run PHP 7.1 as the default PHP version, but we also support PHP 5.6.x, 7.0.x, 7.2.x and 7.3.x 4 | Running different PHP version is as simple as adding a .php{version} file. 5 | 6 | To change all to default PHP 7.2, goto your workspace directory and create a file named `.php72` 7 | This will make all webrequest and console request default to PHP 7.2. 8 | 9 | You can set PHP versions for a customer/project namespace. It'll look up from the deepest path. 10 | 11 | - `workspace/customer/project/.php56` 12 | - `workspace/customer/.php71` 13 | - `workspace/.php72` 14 | 15 | Using the example above; 16 | 17 | - Default for is PHP 7.2 18 | - Customer scope is PHP 7.1 19 | - Project runs PHP 5.6 20 | 21 | ## PHP-CLI version 22 | 23 | You do'nt need to add a suffix anymore(for older versions) for cli commands, it'll take the same version as above. 24 | You need to make sure you change your workpath before running commands. 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Jeroen Boersma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/mysql-mailhog-redis-cronjobs.md: -------------------------------------------------------------------------------- 1 | # Database 2 | Make sure you have configured your desired root password in `conf/mysql`. 3 | To manage your databases, run `./bin/dev myroot` 4 | 5 | You can access the database in your app using `db` as hostname. 6 | 7 | # MailHog 8 | 9 | We use [Mailhog][1] to catch all outgoing e-mail (as long as you aren't using an external API). 10 | You can even release the e-mail to a real mailserver, just click the release button in Mailhog you can setup and presto. 11 | Goto [http://mail.localhost/][2] to see all catched mail. 12 | 13 | # Redis 14 | 15 | To access redis you can use `redis` as hostname in the config of your app. 16 | 17 | # Cron 18 | 19 | If you use cronjobs in your app, you can add them on your host machine. 20 | It is recommend to add `./bin/dev` to the path before you implement this, as described in [1). Configure your environment.](../README.md#1-first-things-first) 21 | 22 | E.g.: `*/5 * * * * dev ps | grep php | grep Up && dev console [YOURCOMMANDHERE]` 23 | 24 | For instance, if you wish to run a Magento cronjob, then add the following to your local cronjob: 25 | `*/5 * * * * dev ps | grep php | grep Up && dev console customer/project/htdocs/cron.sh` 26 | 27 | 28 | [1]: https://github.com/mailhog/MailHog 29 | [2]: http://mail.localhost/ 30 | -------------------------------------------------------------------------------- /bin/dev_command/setup-mysql: -------------------------------------------------------------------------------- 1 | 2 | mysql-setup() { 3 | 4 | local host=$1; 5 | 6 | if [ -z "${MYSQL_ROOT_PASSWORD}" ]; then 7 | export MYSQL_ROOT_PASSWORD="`< /dev/urandom LC_CTYPE=C tr -dc _A-Z-a-z-0-9 | head -c32;echo;`"; 8 | echo 'MYSQL_ROOT_PASSWORD='${MYSQL_ROOT_PASSWORD} >> ${DEV_WORKPATH}/.env; 9 | echo 'Created a random root password for MySQL stored in '${DEV_WORKPATH}'/.env, to login as root use `dev myroot`'; 10 | fi; 11 | 12 | echo 'Starting regular database user, waiting for db to become ready'; 13 | ${DEV_PATH}/${DEV_SELF} up "${host}"; 14 | while true; do 15 | ${DEV_PATH}/${DEV_SELF} logs "${host}" 2>&1 | grep 'port: 3306 Percona' > /dev/null && break; 16 | echo -n '.'; 17 | sleep 1; 18 | done 19 | echo ''; 20 | 21 | local user=${USER}; 22 | 23 | # Check if already exists 24 | echo "select * from mysql.user where user='${user}';" | dev myroot -h "${host}" 2>/dev/null| grep "${user}" >/dev/null && return 1; 25 | 26 | echo 'Database user has access to databases "'${user}'_*"'; 27 | echo ''; 28 | echo "\ 29 | create user '${user}';\ 30 | grant all on ${user}.* to '${user}';\ 31 | update mysql.db set db = '${user}\_%' where user = '${user}';\ 32 | flush privileges;" | ${DEV_PATH}/${DEV_SELF} myroot -h "${host}" 2>/dev/null; 33 | 34 | return 0; 35 | } 36 | 37 | mysql-setup "$@"; 38 | return $?; 39 | 40 | -------------------------------------------------------------------------------- /docs/hosts-and-file-structure.md: -------------------------------------------------------------------------------- 1 | # Hosts and file structure 2 | 3 | As stated before, we included a few different webroots. These webroots can be used with different hostnames: 4 | 5 | - `htdocs` 6 | - `httpdocs` 7 | - `public` 8 | - `pub` 9 | 10 | ## Magento 1 11 | Magento 1 projects in both PHP7 and PHP5 are supported. 12 | 13 | Hostname `customer.project.magento.locahost` => PHP7. 14 | Hostname `customer.project.magento.php5.locahost` => PHP5. 15 | All webroots supported. 16 | 17 | E.g.: `http://iwant.coffee.magento.locahost`. 18 | You can also identify a MAGE_RUN_CODE, `customer.project.MAGE_RUN_CODE.magento.locahost`. 19 | 20 | ## Magento 2 21 | Magento 2 projects are only supported in PHP7. 22 | 23 | Hostname `customer.project.magento2.locahost` => PHP7 24 | Only supports `pub` as webroot. 25 | 26 | E.g.: `http://iwant.coffee.magento2.locahost`. 27 | 28 | ## Symfony 2 / 3 29 | Symfony projects in both PHP7 and PHP5 are supported. 30 | 31 | Hostname `*.symfony.locahost` => PHP7. 32 | Hostname `*.symfony.php5.locahost` => PHP5. 33 | All webroots + `web` are supported. 34 | 35 | E.g.: `http://iwant.coffee.symfony.locahost`. 36 | 37 | ## Silex 38 | Silex projects in both PHP7 and PHP5 are supported. 39 | 40 | Hostname `*.symfony.locahost` => PHP7. 41 | Hostname `*.symfony.php5.locahost` => PHP5. 42 | All webroots + `web` are supported. 43 | 44 | E.g.: `http://iwant.coffee.silex.locahost`. 45 | -------------------------------------------------------------------------------- /docs/elasticsearch.md: -------------------------------------------------------------------------------- 1 | # ElasticSearch 2 | 3 | Make sure that you enable ElasticSearch during the setup of the docker containers. If you already setup your 4 | environment, you can still enable it by rebuilding your containers using `dev rebuild` and `dev setup`. 5 | 6 | ## Location 7 | 8 | ElasticSearch is available via `elasticsearch:9200` and can be used in any application you want without any HTTP 9 | authentication. 10 | 11 | ### Health Check 12 | 13 | To make sure the ElasticSearch environment is running as expected, run this command in your terminal: 14 | ```bash 15 | dev console curl -X GET "elasticsearch:9200/_cluster/health?pretty" 16 | ``` 17 | 18 | ## Smile ElasticSuite 19 | 20 | When you're working with Magento 2 and you use [Smile ElasticSuite](https://github.com/Smile-SA/elasticsuite), you need to 21 | install two additional plugins for ElasticSearch that aren't installed by default. To do that make sure you follow the 22 | next steps: 23 | 24 | Create a new file in `~/development/build/dist/elasticsearch/Dockerfile` 25 | Copy this content to the file: 26 | ```bash 27 | FROM elasticsearch:6.5.4 28 | 29 | RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-phonetic && \ 30 | /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-icu 31 | ``` 32 | 33 | Make sure that the version mentioned after `FROM` is the same as the version of ElasticSearch that you installed. 34 | 35 | Now make sure you rerun `dev down` and `dev rebuild` to install these plugins. You're now ready to use Smile 36 | ElasticSuite. 37 | -------------------------------------------------------------------------------- /docs/install-other-php-versions.md: -------------------------------------------------------------------------------- 1 | # If you need to use a different PHP version other than the out-of-the-box supported versions than follow instructions below. 2 | 3 | Example written for PHP5.4 4 | 5 | - copy `https://github.com/JeroenBoersma/docker-php/tree/master/php5/fpm` to `build/custom/php54` 6 | - change the `FROM` section to `php:5.4-fpm` in the dockerfile 7 | - build in manually to see what works or if you need to adapt some things, 8 | I could imagine that some xdebug need to be adapted or removed if you don't use them 9 | I removed most extra things like opcache/blackfire/xdebug/redis 10 | - create a `docker-custom.yml` and add a new service(see `docker-compose.yml` for some copy/paste contents: 11 | ``` 12 | php54: 13 | build: build/custom/php54 14 | volumes: 15 | - ./workspace:/data 16 | links: 17 | - db 18 | - mailcatch 19 | ``` 20 | - copy `build/dist/web` to `build/custom/web` 21 | - change `docker-custom.yml` to build your custom web service 22 | ``` 23 | web: 24 | build: build/custom/web 25 | links: 26 | - php54:fpm54 27 | ``` 28 | - edit `build/custom/web/nginx/content/backends.conf` 29 | copy/paste section `56` and change to `54` 30 | - edit `build/custom/web/nginx/content/php` 31 | copy/paste all `56` sections and change them to `54` 32 | 33 | Configuration finished, whoop 34 | 35 | - `dev rebuild` 36 | - goto your project root `cdw; cd myawesome/project` 37 | - `dev changephp php54` 38 | 39 | If you have a succesful build for a new PHP version 7.3 for instance. 40 | Tell us and create a PR on https://github.com/JeroenBoersma/docker-php 41 | And a PR here to update the `docker-compose.yml`/`docs`/`nginx` 42 | 43 | -------------------------------------------------------------------------------- /docs/mongodb.md: -------------------------------------------------------------------------------- 1 | # MongoDB 2 | 3 | MongoDB is a NoSQL document database that can be enabled in your development environment. It comes with mongo-express, a web-based MongoDB admin interface. 4 | 5 | ## Setup 6 | 7 | Enable MongoDB during the initial setup by running: 8 | ```bash 9 | dev setup 10 | ``` 11 | 12 | If you've already set up your environment, you can enable MongoDB by creating a configuration marker: 13 | ```bash 14 | mkdir -p conf/mongo 15 | dev rebuild 16 | ``` 17 | 18 | ## Configuration 19 | 20 | MongoDB runs with default credentials: 21 | - **Username**: `root` 22 | - **Password**: `example` 23 | 24 | To connect to MongoDB from your applications, use: 25 | - **Host**: `mongo` 26 | - **Port**: `27017` 27 | - **Connection string**: `mongodb://root:example@mongo:27017` 28 | 29 | ## mongo-express Web Interface 30 | 31 | MongoDB includes mongo-express, a web-based admin interface for managing your databases. 32 | 33 | Access it at: [http://localhost:8081](http://localhost:8081) 34 | 35 | ## Usage Examples 36 | 37 | ### Connect from PHP 38 | 39 | ```bash 40 | dev console 41 | ``` 42 | 43 | Then in your application: 44 | ```php 45 | $client = new MongoDB\Client("mongodb://root:example@mongo:27017"); 46 | $database = $client->mydatabase; 47 | $collection = $database->mycollection; 48 | ``` 49 | 50 | ### Using MongoDB Shell 51 | 52 | Access the MongoDB shell: 53 | ```bash 54 | dev exec mongo mongosh -u root -p example 55 | ``` 56 | 57 | ## Troubleshooting 58 | 59 | If MongoDB isn't starting, make sure the configuration marker exists: 60 | ```bash 61 | ls conf/mongo 62 | ``` 63 | 64 | If the directory doesn't exist, create it and rebuild: 65 | ```bash 66 | mkdir -p conf/mongo 67 | dev down 68 | dev up 69 | ``` 70 | -------------------------------------------------------------------------------- /docs/ftp.md: -------------------------------------------------------------------------------- 1 | # FTP Server 2 | 3 | An FTP server can be enabled to provide FTP access to your workspace directory. This is useful for legacy applications or tools that require FTP connectivity. 4 | 5 | ## Setup 6 | 7 | Enable the FTP server during setup: 8 | ```bash 9 | dev setup 10 | ``` 11 | 12 | If you've already set up your environment: 13 | ```bash 14 | mkdir -p conf/ftp 15 | dev rebuild 16 | ``` 17 | 18 | ## Configuration 19 | 20 | The FTP server provides access to your workspace directory at `/data`. 21 | 22 | ### Connection Details 23 | 24 | - **Host**: `localhost` 25 | - **Port**: `21` (default FTP port) 26 | - **Protocol**: FTP (not SFTP) 27 | 28 | ### Credentials 29 | 30 | FTP credentials depend on the FTP server configuration. Check the FTP container build for specific authentication settings: 31 | ```bash 32 | cat build/dist/ftp/Dockerfile 33 | ``` 34 | 35 | ## Usage 36 | 37 | ### FTP Clients 38 | 39 | You can connect using any FTP client: 40 | - FileZilla 41 | - WinSCP 42 | - Command-line FTP 43 | - Your IDE's built-in FTP 44 | 45 | ### Command-Line FTP 46 | 47 | Connect via command line: 48 | ```bash 49 | ftp localhost 50 | ``` 51 | 52 | ## Security Note 53 | 54 | FTP transmits data in plain text, including credentials. This FTP server is intended for development environments only. 55 | 56 | For production-like workflows, consider using: 57 | - SFTP instead of FTP 58 | - Direct file mounting 59 | - rsync over SSH 60 | 61 | ## Troubleshooting 62 | 63 | Check if the FTP server is running: 64 | ```bash 65 | dev ps | grep ftp 66 | ``` 67 | 68 | View FTP server logs: 69 | ```bash 70 | dev logs ftp 71 | ``` 72 | 73 | Test FTP connectivity: 74 | ```bash 75 | ftp localhost 76 | ``` 77 | 78 | If you cannot connect, ensure the FTP configuration marker exists: 79 | ```bash 80 | ls conf/ftp 81 | ``` 82 | -------------------------------------------------------------------------------- /docs/opensearch-dashboard.md: -------------------------------------------------------------------------------- 1 | # OpenSearch Dashboard 2 | 3 | OpenSearch Dashboard is a web-based visualization tool for OpenSearch, similar to Kibana for Elasticsearch. It provides an interface to explore, visualize, and analyze your data. 4 | 5 | ## Setup 6 | 7 | First, make sure OpenSearch is enabled (see [opensearch.md](opensearch.md)). Then enable OpenSearch Dashboard: 8 | 9 | ```bash 10 | dev setup 11 | ``` 12 | 13 | If you've already set up your environment: 14 | ```bash 15 | mkdir -p conf/opensearch-dashboard 16 | dev rebuild 17 | ``` 18 | 19 | ## Access 20 | 21 | OpenSearch Dashboard is available at: [http://localhost:5601](http://localhost:5601) 22 | 23 | ## Features 24 | 25 | OpenSearch Dashboard provides: 26 | - **Discover**: Explore your data with powerful search 27 | - **Visualize**: Create charts, graphs, and maps 28 | - **Dashboard**: Combine visualizations into dashboards 29 | - **Dev Tools**: Execute queries and API calls 30 | - **Management**: Configure indices, mappings, and settings 31 | 32 | ## Using Dev Tools 33 | 34 | The Dev Tools console is useful for testing queries: 35 | 36 | 1. Navigate to [http://localhost:5601](http://localhost:5601) 37 | 2. Click "Dev Tools" in the left menu 38 | 3. Execute queries directly: 39 | 40 | ``` 41 | GET /_cluster/health 42 | 43 | GET /my-index/_search 44 | { 45 | "query": { 46 | "match_all": {} 47 | } 48 | } 49 | ``` 50 | 51 | ## Troubleshooting 52 | 53 | Ensure both OpenSearch and OpenSearch Dashboard are running: 54 | ```bash 55 | dev ps | grep opensearch 56 | ``` 57 | 58 | Check OpenSearch Dashboard logs: 59 | ```bash 60 | dev logs opensearch-dashboard 61 | ``` 62 | 63 | If the dashboard shows "OpenSearch Dashboards server is not ready yet": 64 | - Wait a moment for OpenSearch to fully start 65 | - Verify OpenSearch is accessible: `dev console curl opensearch:9200` 66 | -------------------------------------------------------------------------------- /docs/rabbitmq.md: -------------------------------------------------------------------------------- 1 | # RabbitMQ 2 | 3 | RabbitMQ is a message broker that enables applications to communicate through message queues. It comes with a web-based management interface. 4 | 5 | ## Setup 6 | 7 | Enable RabbitMQ during the initial setup: 8 | ```bash 9 | dev setup 10 | ``` 11 | 12 | If you've already set up your environment, enable RabbitMQ by creating a configuration marker: 13 | ```bash 14 | mkdir -p conf/rabbitmq 15 | dev rebuild 16 | ``` 17 | 18 | ## Configuration 19 | 20 | To connect to RabbitMQ from your applications, use: 21 | - **Host**: `rabbitmq` 22 | - **Port**: `5672` (AMQP protocol) 23 | - **Management Port**: `15672` (Web interface) 24 | - **Default credentials**: `guest` / `guest` 25 | 26 | ## Management Interface 27 | 28 | Access the RabbitMQ management web interface at: [http://localhost:15672](http://localhost:15672) 29 | 30 | Login with: 31 | - **Username**: `guest` 32 | - **Password**: `guest` 33 | 34 | The management interface allows you to: 35 | - Monitor queues and exchanges 36 | - View message rates 37 | - Manage connections and channels 38 | - Create and configure queues 39 | - Send test messages 40 | 41 | ## Usage Examples 42 | 43 | ### PHP with AMQP Extension 44 | 45 | ```bash 46 | dev console 47 | ``` 48 | 49 | In your application: 50 | ```php 51 | $connection = new AMQPConnection([ 52 | 'host' => 'rabbitmq', 53 | 'port' => 5672, 54 | 'vhost' => '/', 55 | 'login' => 'guest', 56 | 'password' => 'guest' 57 | ]); 58 | $connection->connect(); 59 | ``` 60 | 61 | ### Magento 2 Configuration 62 | 63 | In your `env.php`: 64 | ```php 65 | 'queue' => [ 66 | 'amqp' => [ 67 | 'host' => 'rabbitmq', 68 | 'port' => '5672', 69 | 'user' => 'guest', 70 | 'password' => 'guest', 71 | 'virtualhost' => '/' 72 | ] 73 | ] 74 | ``` 75 | 76 | ## Troubleshooting 77 | 78 | Verify RabbitMQ is running: 79 | ```bash 80 | dev ps | grep rabbitmq 81 | ``` 82 | 83 | Check RabbitMQ logs: 84 | ```bash 85 | dev logs rabbitmq 86 | ``` 87 | -------------------------------------------------------------------------------- /bin/dev_command/volume: -------------------------------------------------------------------------------- 1 | 2 | usage() { 3 | echo "Usage:"; 4 | echo "- ${DEV_SELF} ${DEV_COMMAND} {workspace|mysql} localpath"; 5 | echo " create a volume pointing to the localpath"; 6 | echo "- ${DEV_SELF} ${DEV_COMMAND} rm {workspace|mysql}"; 7 | echo " remove a volume"; 8 | echo "- ${DEV_SELF} ${DEV_COMMAND} ls"; 9 | echo " list current volume mapping" 10 | return 1; 11 | } 12 | 13 | current() { 14 | echo 'Current volumes:'; 15 | 16 | echo -n "- mysql: "; 17 | ${DEV_SUDO} docker volume inspect -f '{{ .Options.device }}' dockerdev-mysql-volume 2>/dev/null; 18 | echo -n "- workspace: "; 19 | ${DEV_SUDO} docker volume inspect -f '{{ .Options.device }}' dockerdev-workspace-volume 2>/dev/null; 20 | return 0; 21 | } 22 | 23 | create() { 24 | if [ "$1" == 'mysql' ]; then 25 | local VOLUME_TYPE='mysql'; 26 | elif [ "$1" == 'workspace' ]; then 27 | local VOLUME_TYPE='workspace'; 28 | else 29 | usage; 30 | return $?; 31 | fi 32 | 33 | local LOCAL_PATH=${2:-$1}; 34 | local DOCKER_VOLUME="dockerdev-${VOLUME_TYPE}-volume"; 35 | 36 | if [ "${LOCAL_PATH:0:1}" != '/' ]; then 37 | LOCAL_PATH=`realpath ${DEV_USERDIR}/${LOCAL_PATH}`; 38 | fi 39 | 40 | ${DEV_SUDO} docker volume inspect ${DOCKER_VOLUME} 1>/dev/null 2>&1; 41 | if [ $? == 0 ]; then 42 | echo "The volume '${DOCKER_VOLUME}' is already initialized, remove it first"; 43 | echo ''; 44 | 45 | usage; 46 | return $?; 47 | fi 48 | 49 | ${DEV_SUDO} docker volume create -o 'type=none' -o 'device='${LOCAL_PATH} -o 'o=bind' ${DOCKER_VOLUME} 50 | return $?; 51 | } 52 | 53 | remove() { 54 | if [ "$1" == 'mysql' ]; then 55 | local VOLUME_TYPE='mysql'; 56 | elif [ "$1" == 'workspace' ]; then 57 | local VOLUME_TYPE='workspace'; 58 | else 59 | usage; 60 | return $?; 61 | fi 62 | 63 | local DOCKER_VOLUME="dockerdev-${VOLUME_TYPE}-volume"; 64 | 65 | ${DEV_SUDO} docker volume inspect ${DOCKER_VOLUME} 1>/dev/null 2>&1; 66 | if [ $? -gt 0 ]; then 67 | echo "The volume '${DOCKER_VOLUME}' does not exist"; 68 | echo ''; 69 | usage; 70 | return $?; 71 | fi 72 | 73 | ${DEV_SUDO} docker volume rm ${DOCKER_VOLUME} 74 | return $?; 75 | } 76 | 77 | if [ $# -lt 1 ]; then 78 | usage; 79 | elif [ "$1" == "rm" ]; then 80 | remove $2; 81 | elif [ "$1" == "ls" ]; then 82 | current; 83 | else 84 | create "$@"; 85 | fi 86 | 87 | return $?; 88 | 89 | -------------------------------------------------------------------------------- /docs/opensearch.md: -------------------------------------------------------------------------------- 1 | # OpenSearch 2 | 3 | OpenSearch is an open-source search and analytics engine forked from Elasticsearch. It's compatible with Elasticsearch APIs and can be used as an alternative. 4 | 5 | ## Setup 6 | 7 | Enable OpenSearch during the initial setup: 8 | ```bash 9 | dev setup 10 | ``` 11 | 12 | If you've already set up your environment, enable OpenSearch by creating a configuration marker: 13 | ```bash 14 | mkdir -p conf/opensearch 15 | dev rebuild 16 | ``` 17 | 18 | ## Configuration 19 | 20 | OpenSearch is available at: 21 | - **Host**: `opensearch` 22 | - **Port**: `9200` 23 | - **Security**: Disabled by default (development environment) 24 | 25 | ## OpenSearch vs Elasticsearch 26 | 27 | OpenSearch is API-compatible with Elasticsearch and can be used as a drop-in replacement. Key differences: 28 | - Open-source license (Apache 2.0) 29 | - Active community development 30 | - Compatible with existing Elasticsearch clients 31 | - Security plugins available 32 | 33 | ## Usage 34 | 35 | ### Health Check 36 | 37 | Verify OpenSearch is running: 38 | ```bash 39 | dev console curl -X GET "opensearch:9200/_cluster/health?pretty" 40 | ``` 41 | 42 | ### Basic Operations 43 | 44 | Create an index: 45 | ```bash 46 | dev console curl -X PUT "opensearch:9200/my-index" 47 | ``` 48 | 49 | Index a document: 50 | ```bash 51 | dev console curl -X POST "opensearch:9200/my-index/_doc" -H 'Content-Type: application/json' -d '{"field": "value"}' 52 | ``` 53 | 54 | Search: 55 | ```bash 56 | dev console curl -X GET "opensearch:9200/my-index/_search?q=field:value" 57 | ``` 58 | 59 | ## Application Configuration 60 | 61 | ### PHP Applications 62 | 63 | Use the hostname `opensearch` and port `9200`: 64 | ```php 65 | $client = new OpenSearch\Client([ 66 | 'hosts' => ['opensearch:9200'] 67 | ]); 68 | ``` 69 | 70 | ### Magento 2 71 | 72 | In your `env.php`: 73 | ```php 74 | 'system' => [ 75 | 'default' => [ 76 | 'catalog' => [ 77 | 'search' => [ 78 | 'engine' => 'opensearch', 79 | 'opensearch_server_hostname' => 'opensearch', 80 | 'opensearch_server_port' => '9200' 81 | ] 82 | ] 83 | ] 84 | ] 85 | ``` 86 | 87 | ## OpenSearch Dashboard 88 | 89 | For a web-based interface, see [opensearch-dashboard.md](opensearch-dashboard.md). 90 | 91 | ## Troubleshooting 92 | 93 | Check if OpenSearch is running: 94 | ```bash 95 | dev ps | grep opensearch 96 | ``` 97 | 98 | View OpenSearch logs: 99 | ```bash 100 | dev logs opensearch 101 | ``` 102 | 103 | If you need both OpenSearch and Elasticsearch, you cannot run them simultaneously on the same port. Choose one for your project. 104 | -------------------------------------------------------------------------------- /docs/expose.md: -------------------------------------------------------------------------------- 1 | # BeyondCode Expose 2 | 3 | BeyondCode Expose is an open-source alternative to ngrok for sharing your local development environment with the outside world. It's useful for webhooks, external testing, and client demos. 4 | 5 | ## Setup 6 | 7 | Enable Expose during the initial setup: 8 | ```bash 9 | dev setup 10 | ``` 11 | 12 | If you've already set up your environment: 13 | ```bash 14 | mkdir -p conf/expose 15 | dev rebuild 16 | ``` 17 | 18 | ## Usage 19 | 20 | Share a specific hostname: 21 | ```bash 22 | dev expose your-project.localhost 23 | ``` 24 | 25 | Expose will: 26 | 1. Create a tunnel to your local environment 27 | 2. Provide a public URL 28 | 3. Forward all traffic to your local hostname 29 | 30 | ## Expose vs ngrok 31 | 32 | Both Expose and ngrok provide similar functionality. Key differences: 33 | 34 | **Expose:** 35 | - Open-source 36 | - Self-hosted option available 37 | - Free tier with fewer restrictions 38 | - Integrated into dev environment 39 | 40 | **ngrok:** 41 | - More established 42 | - Better documentation 43 | - More features in paid tiers 44 | - See [sharing-with-the-world-via-ngrok.md](sharing-with-the-world-via-ngrok.md) 45 | 46 | ## Configuration 47 | 48 | Expose runs in host network mode, allowing it to access your local services directly. 49 | 50 | ## Common Use Cases 51 | 52 | ### Webhook Testing 53 | 54 | Test webhooks from external services: 55 | ```bash 56 | dev expose shop.localhost 57 | ``` 58 | 59 | Share the provided URL with the webhook provider (e.g., payment gateway, Shopify, etc.) 60 | 61 | ### Client Demos 62 | 63 | Show work-in-progress to clients: 64 | ```bash 65 | dev expose demo.localhost 66 | ``` 67 | 68 | Send the public URL to your client for review. 69 | 70 | ### Mobile Testing 71 | 72 | Test your site on mobile devices without network configuration: 73 | ```bash 74 | dev expose mysite.localhost 75 | ``` 76 | 77 | Access the public URL from your mobile device. 78 | 79 | ## Security Considerations 80 | 81 | When exposing your local environment: 82 | - Don't expose production credentials or real customer data 83 | - Use temporary database dumps for demos 84 | - Be aware that anyone with the URL can access your site 85 | - Close the tunnel when done 86 | 87 | ## Troubleshooting 88 | 89 | Check if Expose is running: 90 | ```bash 91 | dev ps | grep expose 92 | ``` 93 | 94 | View Expose logs: 95 | ```bash 96 | dev logs expose 97 | ``` 98 | 99 | If the tunnel fails: 100 | - Verify your hostname is accessible locally 101 | - Check that the SSL proxy is running: `dev ps | grep ssl` 102 | - Ensure no firewall is blocking outbound connections 103 | 104 | ## Alternative: ngrok 105 | 106 | If you prefer ngrok, see [sharing-with-the-world-via-ngrok.md](sharing-with-the-world-via-ngrok.md) for setup instructions. 107 | -------------------------------------------------------------------------------- /docs/development-commands.md: -------------------------------------------------------------------------------- 1 | # Dev commands 2 | 3 | We supply several helpful commands to get of easily. `./bin/dev COMMAND` or just `dev COMMAND` if you've added the development to your $PATH. 4 | 5 | To control your docker environment. 6 | 7 | - `build [IMAGE]` 8 | re-build a image 9 | - `changephp` 10 | change current php version 11 | - `config` 12 | show docker-compose configuration 13 | - `down` 14 | destroy your local development environment, will not remove project/mysql files, only containers. 15 | - `exec [CONTAINER] [OPTIONS]` 16 | execute commands in a specific container, for instance php or nginx 17 | - `images` 18 | display used images 19 | - ngrok [HOSTNAME] 20 | share your environment with the outside world via ngrok.io 21 | - `logs [CONTAINER]` 22 | show logs for a specific container 23 | - `profile` 24 | show some useful commands to add to your SHELL 25 | - `ps` 26 | show all running processes 27 | - `rebuild` 28 | alias for `dev update && dev build && dev down && dev up` 29 | - `restart [CONTAINER]` 30 | restart all or a specific container 31 | - `run` 32 | run one-off commands in new container 33 | - `setup` 34 | Run setup for defaults 35 | - `start` 36 | start all exising container, will not create them if they don't exist(use `up` instead) 37 | - `status` 38 | alias for ps 39 | - `stop` 40 | stop all running containers 41 | - `up` 42 | create/build/run all containers, bring your development to live 43 | - `update` 44 | update/pull all used images from the web 45 | 46 | There are also useful tools. 47 | 48 | - `blackfire curl [URL]` 49 | The blackfire command to curl pages. Be sure you've setup blackfire correctly 50 | - `composer [COMMANDS]` `composer5 [COMMANDS]` 51 | composer docker implementation, also runs in own container. 52 | - `console` `console5` 53 | open a console inside your PHP containers. 54 | - `magerun [COMMANDS]` 55 | run magerun commands on your Magento projects 56 | - `magerun2 [COMMANDS]` 57 | run magerun2 commands on your Magento projects 58 | - `myroot [OPTIONS]` 59 | run mysql as root. 60 | - `mysql [OPTIONS]` 61 | run mysql as you, current user 62 | - `mysqldump [OPTIONS]` 63 | run mysqldump as you, current user 64 | - `mytop` 65 | run mytop as you, current user to monitor MySQL processes 66 | - `top` 67 | monitor your running containers and see how much resources they are eating 68 | - `php [OPTIONS]` 69 | run php commands 70 | - `php-ext-enable [EXTENSION]` 71 | temporarily enable module for running container, use with `dev exec php php -v` 72 | - `php-ext-disable [EXTENSION]` 73 | temporarily diable module for running container, use with `dev exec php php -v` 74 | 75 | You can run these commands from within your workspace directories. 76 | For example: `cd workspace/test/project/htdocs` `../../../../bin/dev php info.php` (or `dev php info.php` if you've added the bin directory to your path) 77 | 78 | So you can also import data to mysql with `./bin/dev mysql database < dump.sql` or dump `./bin/mysqldump database > dump.sql`. 79 | -------------------------------------------------------------------------------- /docs/node-npm-yarn.md: -------------------------------------------------------------------------------- 1 | # Node.js, NPM, and Yarn 2 | 3 | Node.js is available in the development environment for running JavaScript tools, build processes, and applications. Both NPM and Yarn package managers are supported. 4 | 5 | ## Setup 6 | 7 | Node.js is enabled by default during setup. If needed, you can enable it manually: 8 | ```bash 9 | mkdir -p conf/node 10 | dev rebuild 11 | ``` 12 | 13 | ## Available Commands 14 | 15 | ### Node.js 16 | 17 | Run Node.js scripts: 18 | ```bash 19 | dev node script.js 20 | ``` 21 | 22 | Check Node.js version: 23 | ```bash 24 | dev node --version 25 | ``` 26 | 27 | ### NPM 28 | 29 | Install dependencies from package.json: 30 | ```bash 31 | dev npm install 32 | ``` 33 | 34 | Install a specific package: 35 | ```bash 36 | dev npm install package-name 37 | ``` 38 | 39 | Run npm scripts: 40 | ```bash 41 | dev npm run build 42 | dev npm run watch 43 | dev npm run dev 44 | ``` 45 | 46 | ### Yarn 47 | 48 | Install dependencies: 49 | ```bash 50 | dev yarn install 51 | ``` 52 | 53 | Add a package: 54 | ```bash 55 | dev yarn add package-name 56 | ``` 57 | 58 | Run yarn scripts: 59 | ```bash 60 | dev yarn build 61 | dev yarn watch 62 | ``` 63 | 64 | ## Working Directory 65 | 66 | All Node.js, NPM, and Yarn commands run in your current directory context. Make sure you're in your project directory before running commands: 67 | 68 | ```bash 69 | cd workspace/customer/project 70 | dev npm install 71 | ``` 72 | 73 | ## Common Use Cases 74 | 75 | ### Frontend Build Tools 76 | 77 | For projects using Webpack, Gulp, Grunt, or similar: 78 | ```bash 79 | cd workspace/customer/project 80 | dev npm install 81 | dev npm run build 82 | ``` 83 | 84 | ### Magento 2 Theme Compilation 85 | 86 | For Magento 2 themes using Gulp or similar: 87 | ```bash 88 | cd workspace/customer/project/htdocs 89 | dev npm install 90 | dev npm run build 91 | ``` 92 | 93 | ### Watch Mode 94 | 95 | For development with file watching: 96 | ```bash 97 | dev npm run watch 98 | ``` 99 | 100 | Or with Yarn: 101 | ```bash 102 | dev yarn watch 103 | ``` 104 | 105 | ## Node.js Version 106 | 107 | The environment uses the Node.js version defined in the build configuration. To check which version is available: 108 | ```bash 109 | dev node --version 110 | ``` 111 | 112 | ## Package Management 113 | 114 | Both NPM and Yarn are available. Choose based on your project: 115 | - If `package-lock.json` exists, use `dev npm` 116 | - If `yarn.lock` exists, use `dev yarn` 117 | 118 | ## Troubleshooting 119 | 120 | ### Permission Issues 121 | 122 | If you encounter permission errors, the Node.js container runs as your user, so permissions should match your local files. 123 | 124 | ### Module Not Found 125 | 126 | Ensure you've installed dependencies: 127 | ```bash 128 | dev npm install 129 | ``` 130 | 131 | Or: 132 | ```bash 133 | dev yarn install 134 | ``` 135 | 136 | ### Cache Issues 137 | 138 | Clear NPM cache: 139 | ```bash 140 | dev npm cache clean --force 141 | ``` 142 | 143 | Clear Yarn cache: 144 | ```bash 145 | dev yarn cache clean 146 | ``` 147 | -------------------------------------------------------------------------------- /docs/xdebug.md: -------------------------------------------------------------------------------- 1 | # XDebug 2 | 3 | XDebug is a debugging and profiling extension for PHP. This guide covers how to use XDebug in your development environment. 4 | 5 | ## XDebug Console 6 | 7 | The quickest way to run PHP with XDebug enabled is using the `xdebug-console` command: 8 | 9 | ```bash 10 | dev xdebug-console 11 | ``` 12 | 13 | This starts a PHP console with XDebug pre-configured and ready to connect to your IDE. 14 | 15 | ## IDE Configuration 16 | 17 | ### PhpStorm 18 | 19 | 1. Go to **Settings** > **PHP** > **Debug** 20 | 2. Set XDebug port to `9003` (XDebug 3.x) or `9000` (XDebug 2.x) 21 | 3. Enable "Can accept external connections" 22 | 4. Go to **Settings** > **PHP** > **Servers** 23 | 5. Add a server: 24 | - **Name**: `docker` 25 | - **Host**: Your project hostname (e.g., `project.localhost`) 26 | - **Port**: `80` 27 | - **Debugger**: `Xdebug` 28 | - Enable "Use path mappings" 29 | - Map your local project directory to `/data/workspace/customer/project` 30 | 31 | ### VS Code 32 | 33 | Install the "PHP Debug" extension and add to `.vscode/launch.json`: 34 | 35 | ```json 36 | { 37 | "version": "0.2.0", 38 | "configurations": [ 39 | { 40 | "name": "Listen for XDebug", 41 | "type": "php", 42 | "request": "launch", 43 | "port": 9003, 44 | "pathMappings": { 45 | "/data/workspace/customer/project": "${workspaceFolder}" 46 | } 47 | } 48 | ] 49 | } 50 | ``` 51 | 52 | ## Running Scripts with XDebug 53 | 54 | Execute any PHP script with XDebug: 55 | ```bash 56 | dev xdebug-console php myscript.php 57 | ``` 58 | 59 | For Magento: 60 | ```bash 61 | dev xdebug-console bin/magento cache:flush 62 | ``` 63 | 64 | For Composer: 65 | ```bash 66 | dev xdebug-console composer install 67 | ``` 68 | 69 | ## Web Request Debugging 70 | 71 | XDebug is available in the PHP containers but not enabled by default for performance reasons. To debug web requests: 72 | 73 | 1. Set the XDebug trigger in your browser: 74 | - Install a browser extension (XDebug helper for Chrome/Firefox) 75 | - Or add `?XDEBUG_SESSION_START=PHPSTORM` to your URL 76 | 77 | 2. Start listening for connections in your IDE 78 | 79 | 3. Access your application in the browser 80 | 81 | 4. Your IDE should break on the first line or your breakpoints 82 | 83 | ## Profiling 84 | 85 | XDebug can also profile your application to identify performance bottlenecks: 86 | 87 | ```bash 88 | dev xdebug-console php -d xdebug.mode=profile myscript.php 89 | ``` 90 | 91 | Profile files are generated in `/tmp` inside the container. 92 | 93 | ## Troubleshooting 94 | 95 | ### IDE Not Connecting 96 | 97 | Verify XDebug is loaded: 98 | ```bash 99 | dev xdebug-console php -v 100 | ``` 101 | 102 | You should see "with Xdebug" in the output. 103 | 104 | ### Port Conflicts 105 | 106 | Ensure port 9003 isn't blocked by your firewall and your IDE is listening on the correct port. 107 | 108 | ### Path Mapping Issues 109 | 110 | Make sure your IDE's path mappings match your workspace structure. The container path is always `/data/workspace/...` 111 | -------------------------------------------------------------------------------- /docs/varnish.md: -------------------------------------------------------------------------------- 1 | # Varnish 2 | 3 | Varnish is an HTTP accelerator and caching layer that sits in front of your web server to dramatically improve performance. 4 | 5 | ## Setup 6 | 7 | Enable Varnish during the initial setup: 8 | ```bash 9 | dev setup 10 | ``` 11 | 12 | If you've already set up your environment, enable Varnish by creating the VCL configuration file: 13 | ```bash 14 | cp build/dist/varnish/default.vcl conf/varnish.vcl 15 | dev rebuild 16 | ``` 17 | 18 | ## Configuration 19 | 20 | Varnish uses VCL (Varnish Configuration Language) to define caching behavior. The default configuration file is located at `conf/varnish.vcl`. 21 | 22 | ### Cache Size 23 | 24 | Set the cache size via environment variable in your `.env` file: 25 | ```bash 26 | CACHE_SIZE=256M 27 | ``` 28 | 29 | Default cache size is typically 256MB. 30 | 31 | ## VCL Customization 32 | 33 | ### Import Custom VCL 34 | 35 | To use a custom VCL file: 36 | ```bash 37 | dev varnish-vcl-import /path/to/your/custom.vcl 38 | ``` 39 | 40 | ### Disable VCL 41 | 42 | To disable Varnish VCL: 43 | ```bash 44 | dev varnish-vcl-disable 45 | ``` 46 | 47 | ### Edit VCL 48 | 49 | Edit the VCL configuration: 50 | ```bash 51 | nano conf/varnish.vcl 52 | ``` 53 | 54 | After making changes, reload Varnish: 55 | ```bash 56 | dev restart varnish 57 | ``` 58 | 59 | ## Varnish Administration 60 | 61 | Access Varnish admin commands: 62 | ```bash 63 | dev varnishadm 64 | ``` 65 | 66 | Common varnishadm commands: 67 | ```bash 68 | dev exec varnish varnishadm ban req.url '~' '.' # Ban all cached content 69 | dev exec varnish varnishadm param.show # Show all parameters 70 | dev exec varnish varnishadm ban.list # List active bans 71 | ``` 72 | 73 | Note: Based on the user's CLAUDE.md, you can run varnishadm locally with: 74 | ```bash 75 | dev exec varnish varnishadm 76 | ``` 77 | 78 | ## Usage with Magento 2 79 | 80 | For Magento 2, you'll need a Magento-specific VCL. Example configuration in `conf/varnish.vcl`: 81 | 82 | 1. Generate Magento's VCL: 83 | ```bash 84 | dev console bin/magento varnish:vcl:generate > conf/varnish.vcl 85 | ``` 86 | 87 | 2. Restart Varnish: 88 | ```bash 89 | dev restart varnish 90 | ``` 91 | 92 | 3. Configure Magento to use Varnish: 93 | - **Stores** > **Configuration** > **Advanced** > **System** > **Full Page Cache** 94 | - Set **Caching Application** to "Varnish Cache" 95 | - Set Varnish host to `varnish` 96 | 97 | ## Testing Varnish 98 | 99 | Check if Varnish is caching: 100 | ```bash 101 | curl -I http://your-project.localhost 102 | ``` 103 | 104 | Look for the `X-Varnish` header in the response. If present, Varnish is working. 105 | 106 | To see if a response is cached: 107 | - `X-Cache: HIT` = Served from cache 108 | - `X-Cache: MISS` = Not in cache, fetching from backend 109 | 110 | ## Troubleshooting 111 | 112 | Check Varnish status: 113 | ```bash 114 | dev ps | grep varnish 115 | ``` 116 | 117 | View Varnish logs: 118 | ```bash 119 | dev logs varnish 120 | ``` 121 | 122 | Verify VCL syntax before restarting: 123 | ```bash 124 | dev exec varnish varnishadm vcl.load test /etc/varnish/default.vcl 125 | ``` 126 | -------------------------------------------------------------------------------- /docs/code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jeroen@srcode.nl. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /docs/environment-configuration.md: -------------------------------------------------------------------------------- 1 | # Environment Configuration 2 | 3 | The development environment can be configured using environment variables, configuration files, and marker files. 4 | 5 | ## .env File 6 | 7 | Create a `.env` file in the root of your development directory to set environment variables: 8 | 9 | ```bash 10 | cd ~/development 11 | nano .env 12 | ``` 13 | 14 | ### Common Environment Variables 15 | 16 | ```bash 17 | # MySQL root password 18 | MYSQL_ROOT_PASSWORD=secret 19 | 20 | # Varnish cache size 21 | CACHE_SIZE=256M 22 | 23 | # Composer memory limit 24 | COMPOSER_MEMORY_LIMIT=-1 25 | 26 | # Domain suffix (default: .localhost) 27 | DOMAIN_SUFFIX=.localhost 28 | ``` 29 | 30 | The `.env` file is gitignored by default, so your local settings won't be committed. 31 | 32 | ## Configuration Markers 33 | 34 | Many services are enabled by creating marker directories in `conf/`: 35 | 36 | ```bash 37 | mkdir -p conf/elasticsearch # Enable Elasticsearch 38 | mkdir -p conf/rabbitmq # Enable RabbitMQ 39 | mkdir -p conf/mongo # Enable MongoDB 40 | mkdir -p conf/opensearch # Enable OpenSearch 41 | mkdir -p conf/varnish # Enable Varnish 42 | mkdir -p conf/blackfire # Enable Blackfire 43 | ``` 44 | 45 | After creating markers, rebuild: 46 | ```bash 47 | dev rebuild 48 | ``` 49 | 50 | ## Service-Specific Configuration 51 | 52 | ### MySQL 53 | 54 | MySQL configuration is in `conf/mysql/my.cnf`: 55 | ```bash 56 | mkdir -p conf/mysql 57 | nano conf/mysql/my.cnf 58 | ``` 59 | 60 | Example configuration: 61 | ```ini 62 | [mysqld] 63 | max_connections = 200 64 | innodb_buffer_pool_size = 1G 65 | ``` 66 | 67 | ### Blackfire 68 | 69 | Blackfire credentials in `conf/blackfire`: 70 | ```bash 71 | BLACKFIRE_CLIENT_ID=your-client-id 72 | BLACKFIRE_CLIENT_TOKEN=your-client-token 73 | BLACKFIRE_SERVER_ID=your-server-id 74 | BLACKFIRE_SERVER_TOKEN=your-server-token 75 | ``` 76 | 77 | See [configure-blackfire.md](configure-blackfire.md) for details. 78 | 79 | ### Varnish 80 | 81 | Varnish VCL configuration in `conf/varnish.vcl`. See [varnish.md](varnish.md) for details. 82 | 83 | ## Setup Wizard 84 | 85 | Run the setup wizard to configure your environment interactively: 86 | ```bash 87 | dev setup 88 | ``` 89 | 90 | The wizard will: 91 | - Set your domain suffix 92 | - Choose default PHP version 93 | - Enable optional services 94 | - Configure workspace and database volumes 95 | 96 | You can run `dev setup` multiple times to reconfigure. 97 | 98 | ## PHP Version Configuration 99 | 100 | PHP versions are set using marker files in your workspace. See [how-to-use-different-php-versions.md](how-to-use-different-php-versions.md) for details. 101 | 102 | ## Docker Compose Overrides 103 | 104 | For advanced configuration, use custom compose files. See [custom-compose-files.md](custom-compose-files.md). 105 | 106 | ## Troubleshooting 107 | 108 | ### Changes Not Taking Effect 109 | 110 | After modifying configuration files, restart the affected service: 111 | ```bash 112 | dev restart servicename 113 | ``` 114 | 115 | Or rebuild entirely: 116 | ```bash 117 | dev rebuild 118 | ``` 119 | 120 | ### Finding Configuration Files 121 | 122 | List all configuration: 123 | ```bash 124 | ls -la conf/ 125 | ``` 126 | 127 | View current environment variables: 128 | ```bash 129 | cat .env 130 | ``` 131 | -------------------------------------------------------------------------------- /docs/mysql8.md: -------------------------------------------------------------------------------- 1 | # MySQL 8 2 | 3 | MySQL 8 is available as an optional secondary database server running alongside the default MySQL 5.7/Percona instance. This allows you to test applications against MySQL 8 or run multiple database versions simultaneously. 4 | 5 | ## Setup 6 | 7 | Enable MySQL 8 during the initial setup: 8 | ```bash 9 | dev setup 10 | ``` 11 | 12 | If you've already set up your environment: 13 | ```bash 14 | mkdir -p conf/mysql8 15 | dev rebuild 16 | ``` 17 | 18 | ## Configuration 19 | 20 | MySQL 8 runs on a different port to avoid conflicts with the default database: 21 | 22 | - **Host**: `localhost` (from your machine) or `db8` (from containers) 23 | - **Port**: `3308` (note: different from default 3306) 24 | - **Root password**: Same as your main MySQL instance (set in conf/mysql) 25 | 26 | ## Connecting to MySQL 8 27 | 28 | ### From Your Host Machine 29 | 30 | ```bash 31 | mysql -h 127.0.0.1 -P 3308 -u root -p 32 | ``` 33 | 34 | ### From PHP Containers 35 | 36 | Use the hostname `db8` and standard port `3306`: 37 | ```php 38 | $connection = new PDO('mysql:host=db8;port=3306;dbname=mydb', 'root', 'password'); 39 | ``` 40 | 41 | ### Using Dev Commands 42 | 43 | The standard `dev mysql` command connects to the default database. For MySQL 8, use the direct connection method above. 44 | 45 | ## MySQL 8 vs MySQL 5.7 46 | 47 | Key differences in MySQL 8: 48 | - **Authentication**: Default authentication plugin changed to `caching_sha2_password` 49 | - **Performance**: Improved query optimizer and performance 50 | - **JSON**: Enhanced JSON functionality 51 | - **Window Functions**: Support for window functions 52 | - **CTEs**: Common Table Expressions (WITH clause) 53 | - **Roles**: Better role-based access control 54 | 55 | ## Application Configuration 56 | 57 | ### Magento 2 58 | 59 | Magento 2.4.4+ officially supports MySQL 8. In `env.php`: 60 | ```php 61 | 'db' => [ 62 | 'connection' => [ 63 | 'default' => [ 64 | 'host' => 'db8', 65 | 'dbname' => 'magento', 66 | 'username' => 'root', 67 | 'password' => 'yourpassword', 68 | 'port' => '3306' 69 | ] 70 | ] 71 | ] 72 | ``` 73 | 74 | ### Laravel 75 | 76 | In `.env`: 77 | ``` 78 | DB_CONNECTION=mysql 79 | DB_HOST=db8 80 | DB_PORT=3306 81 | DB_DATABASE=laravel 82 | DB_USERNAME=root 83 | DB_PASSWORD=yourpassword 84 | ``` 85 | 86 | ## Running Both MySQL Versions 87 | 88 | You can run both MySQL 5.7 and MySQL 8 simultaneously: 89 | - **MySQL 5.7/Percona**: `db` on port 3306 90 | - **MySQL 8**: `db8` on port 3308 91 | 92 | This allows you to: 93 | - Test compatibility before upgrading 94 | - Run different projects on different MySQL versions 95 | - Migrate data between versions 96 | 97 | ## Data Persistence 98 | 99 | MySQL 8 uses a separate Docker volume for data persistence. To make it persistent in your development directory: 100 | 101 | ```bash 102 | cd ~/development 103 | dev down --remove-orphans 104 | dev volume rm mysql8 105 | mkdir mysql8 106 | dev volume mysql8 mysql8 107 | dev setup 108 | ``` 109 | 110 | ## Troubleshooting 111 | 112 | Check if MySQL 8 is running: 113 | ```bash 114 | dev ps | grep db8 115 | ``` 116 | 117 | View MySQL 8 logs: 118 | ```bash 119 | dev logs db8 120 | ``` 121 | 122 | Test connectivity: 123 | ```bash 124 | mysql -h 127.0.0.1 -P 3308 -u root -p -e "SELECT VERSION();" 125 | ``` 126 | 127 | ### Authentication Plugin Issues 128 | 129 | If you get "Authentication plugin 'caching_sha2_password' cannot be loaded", your MySQL client may be outdated. Either: 130 | 1. Update your MySQL client 131 | 2. Create users with the older authentication method in MySQL 8 132 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | volumes: 2 | dockerdev-mysql-volume: 3 | external: true 4 | dockerdev-workspace-volume: 5 | external: true 6 | 7 | services: 8 | db: 9 | container_name: dockerdev-db 10 | image: percona 11 | volumes: 12 | - ./conf.d/mysql/my.cnf:/etc/my.cnf.d/development.cnf:ro 13 | - dockerdev-mysql-volume:/var/lib/mysql:rw 14 | environment: 15 | - MYSQL_ROOT_PASSWORD 16 | ports: 17 | - 127.0.0.1:3306:3306 18 | 19 | mailcatch: 20 | image: mailhog/mailhog 21 | 22 | # php56: 23 | # build: 24 | # context: build/dist/php 25 | # args: 26 | # - FROM_TAG=php5-fpm 27 | # volumes: 28 | # - dockerdev-workspace-volume:/data 29 | # php70: 30 | # build: 31 | # context: build/dist/php 32 | # args: 33 | # - FROM_TAG=php7-fpm 34 | # volumes: 35 | # - dockerdev-workspace-volume:/data 36 | # php71: 37 | # build: 38 | # context: build/dist/php 39 | # args: 40 | # - FROM_TAG=php71-fpm 41 | # volumes: 42 | # - dockerdev-workspace-volume:/data 43 | # php72: 44 | # build: 45 | # context: build/dist/php 46 | # args: 47 | # - FROM_TAG=php72-fpm 48 | # environment: 49 | # - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 50 | # volumes: 51 | # - dockerdev-workspace-volume:/data 52 | # php73: 53 | # build: 54 | # context: build/dist/php 55 | # args: 56 | # - FROM_TAG=php73-fpm 57 | # environment: 58 | # - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 59 | # volumes: 60 | # - dockerdev-workspace-volume:/data 61 | php74: 62 | build: 63 | context: build/dist/php 64 | args: 65 | - FROM_TAG=php74-fpm 66 | environment: 67 | - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 68 | volumes: 69 | - dockerdev-workspace-volume:/data 70 | php80: 71 | build: 72 | context: build/dist/php 73 | args: 74 | - FROM_TAG=php80-fpm 75 | environment: 76 | - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 77 | volumes: 78 | - dockerdev-workspace-volume:/data 79 | php81: 80 | build: 81 | context: build/dist/php 82 | args: 83 | - FROM_TAG=php81-fpm 84 | environment: 85 | - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 86 | volumes: 87 | - dockerdev-workspace-volume:/data 88 | php82: 89 | build: 90 | context: build/dist/php 91 | args: 92 | - FROM_TAG=php82-fpm 93 | environment: 94 | - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 95 | volumes: 96 | - dockerdev-workspace-volume:/data 97 | php83: 98 | build: 99 | context: build/dist/php 100 | args: 101 | - FROM_TAG=php83-fpm 102 | environment: 103 | - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 104 | volumes: 105 | - dockerdev-workspace-volume:/data 106 | php84: 107 | build: 108 | context: build/dist/php 109 | args: 110 | - FROM_TAG=php84-fpm 111 | environment: 112 | - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 113 | volumes: 114 | - dockerdev-workspace-volume:/data 115 | php85: 116 | build: 117 | context: build/dist/php 118 | args: 119 | - FROM_TAG=php85-fpm 120 | environment: 121 | - "BLACKFIRE_AGENT_SOCKET=unix:///dev/null" 122 | volumes: 123 | - dockerdev-workspace-volume:/data 124 | 125 | redis: 126 | image: redis:alpine 127 | 128 | web: 129 | build: 130 | context: build/dist/web 131 | volumes: 132 | - dockerdev-workspace-volume:/data:ro 133 | environment: 134 | - DOMAINSUFFIX 135 | ssl: 136 | depends_on: 137 | - web 138 | build: 139 | context: build/dist/ssl 140 | ports: 141 | - "80:80" 142 | - "443:443" 143 | -------------------------------------------------------------------------------- /docs/docker-volumes.md: -------------------------------------------------------------------------------- 1 | # Docker Volumes 2 | 3 | Docker volumes provide persistent storage for your workspace, databases, and other data. This guide covers volume management in the development environment. 4 | 5 | ## Volume Command 6 | 7 | Manage volumes with the `dev volume` command: 8 | ```bash 9 | dev volume [VOLUME_NAME] [HOST_PATH] 10 | ``` 11 | 12 | ## Workspace Volume 13 | 14 | By default, the workspace is stored in a Docker volume. To use a local directory instead: 15 | 16 | ```bash 17 | cd ~/development 18 | dev down --remove-orphans 19 | dev volume rm workspace 20 | mkdir workspace 21 | dev volume workspace workspace 22 | dev up 23 | ``` 24 | 25 | Now `~/development/workspace` contains your projects and is directly accessible. 26 | 27 | ## MySQL Volume 28 | 29 | Make MySQL data persistent in your development directory: 30 | 31 | ```bash 32 | cd ~/development 33 | dev down --remove-orphans 34 | dev volume rm mysql 35 | mkdir mysql 36 | dev volume mysql mysql 37 | dev setup 38 | ``` 39 | 40 | Warning: This destroys existing databases. Export data first if needed. 41 | 42 | ## MySQL 8 Volume 43 | 44 | For MySQL 8 persistence: 45 | ```bash 46 | cd ~/development 47 | dev down --remove-orphans 48 | dev volume rm mysql8 49 | mkdir mysql8 50 | dev volume mysql8 mysql8 51 | dev setup 52 | ``` 53 | 54 | ## Benefits of Local Volumes 55 | 56 | Using local directories instead of Docker volumes: 57 | - **Easier backups**: Standard file system backups work 58 | - **Direct access**: Edit files with any tool 59 | - **Version control**: Can add to git if desired (workspace not recommended) 60 | - **Visibility**: See exactly what's stored 61 | 62 | ## Benefits of Docker Volumes 63 | 64 | Using Docker volumes: 65 | - **Performance**: Better I/O performance, especially on macOS 66 | - **Automatic management**: Docker handles cleanup 67 | - **Isolation**: No conflicts with host filesystem 68 | 69 | ## Listing Volumes 70 | 71 | List all volumes: 72 | ```bash 73 | docker volume ls | grep dockerdev 74 | ``` 75 | 76 | ## Volume Inspection 77 | 78 | Inspect a volume: 79 | ```bash 80 | docker volume inspect dockerdev-workspace-volume 81 | ``` 82 | 83 | ## Removing Volumes 84 | 85 | Remove a specific volume: 86 | ```bash 87 | dev down 88 | dev volume rm volumename 89 | ``` 90 | 91 | Warning: This permanently deletes data. Backup first. 92 | 93 | Remove all unused volumes: 94 | ```bash 95 | docker volume prune 96 | ``` 97 | 98 | ## Volume Permissions 99 | 100 | Volumes inherit the UID/GID from the container processes, which match your user. If you encounter permission issues: 101 | 102 | Check current permissions: 103 | ```bash 104 | ls -la workspace/ 105 | ``` 106 | 107 | Fix permissions: 108 | ```bash 109 | sudo chown -R $USER:$USER workspace/ 110 | ``` 111 | 112 | ## Backup Strategies 113 | 114 | ### Workspace Backup 115 | 116 | If using local workspace: 117 | ```bash 118 | tar -czf workspace-backup.tar.gz workspace/ 119 | ``` 120 | 121 | If using Docker volume: 122 | ```bash 123 | docker run --rm -v dockerdev-workspace-volume:/data -v $(pwd):/backup ubuntu tar czf /backup/workspace-backup.tar.gz /data 124 | ``` 125 | 126 | ### Database Backup 127 | 128 | Export databases: 129 | ```bash 130 | dev mysqldump database > database-backup.sql 131 | ``` 132 | 133 | Or backup the entire MySQL directory if using local volumes: 134 | ```bash 135 | tar -czf mysql-backup.tar.gz mysql/ 136 | ``` 137 | 138 | ## Restore from Backup 139 | 140 | ### Workspace Restore 141 | 142 | ```bash 143 | tar -xzf workspace-backup.tar.gz 144 | ``` 145 | 146 | ### Database Restore 147 | 148 | ```bash 149 | dev mysql database < database-backup.sql 150 | ``` 151 | 152 | ## Troubleshooting 153 | 154 | ### Volume Not Found 155 | 156 | If a volume is missing, recreate it: 157 | ```bash 158 | dev volume workspace workspace 159 | ``` 160 | 161 | ### Disk Space Issues 162 | 163 | Check volume sizes: 164 | ```bash 165 | docker system df -v 166 | ``` 167 | 168 | Clean up unused volumes: 169 | ```bash 170 | docker volume prune 171 | ``` 172 | -------------------------------------------------------------------------------- /bin/dev_command/setup: -------------------------------------------------------------------------------- 1 | 2 | cd $DEV_PATH; 3 | 4 | echo 'Development setup'; 5 | echo ''; 6 | 7 | setup() { 8 | 9 | mysql() { 10 | if [ -z "`${DEV_SUDO} docker volume ls -q -f 'name=dockerdev-mysql-volume'`" ]; then 11 | echo 'Create a persistant database volume'; 12 | ${DEV_SUDO} docker volume create dockerdev-mysql-volume; 13 | fi 14 | 15 | ./${DEV_SELF} setup-mysql db; 16 | return $?; 17 | } 18 | 19 | workspace() { 20 | if [ -z "`${DEV_SUDO} docker volume ls -q -f 'name=dockerdev-workspace-volume'`" ]; then 21 | echo 'Create workspace volume in location '${DEV_WORKSPACE_PATH}; 22 | ${DEV_SUDO} docker volume create -o 'type=none' -o 'device='${DEV_WORKSPACE_PATH} -o 'o=bind' dockerdev-workspace-volume 23 | fi 24 | } 25 | 26 | php() { 27 | dc php && echo 'PHP configured with version '${DEV_PHP} && return 1; 28 | 29 | local versions="`dc php_versions`" version=''; 30 | echo "Which default PHP version should we enable"; 31 | for v in ${versions}; do 32 | echo "- ${v}"; 33 | done 34 | 35 | read -p'? ' version; 36 | [ -z "${version}" ] && return 1; 37 | 38 | touch ${DEV_WORKSPACE_PATH}/.${version}; 39 | 40 | echo 'COMPOSER_MEMORY_LIMIT=-1' >> ${DEV_WORKPATH}/.env; 41 | 42 | return 0; 43 | } 44 | 45 | suffix() { 46 | if [ -n "${DOMAINSUFFIX}" ]; then 47 | echo 'Listening on "*'${DOMAINSUFFIX}'"'; 48 | return 1; 49 | fi 50 | 51 | local suffix='' default='.localhost'; 52 | echo 'Which domain suffix do you want to listen to - default: '${default}''; 53 | read -p' ' suffix; 54 | if [ -z "${suffix}" ]; then 55 | suffix=${default}; 56 | fi 57 | 58 | echo 'DOMAINSUFFIX='${suffix} >> ${DEV_WORKPATH}/.env; 59 | export DOMAINSUFFIX=${suffix}; 60 | 61 | return 0; 62 | } 63 | 64 | feature() { 65 | local name="$1" file="${DEV_WORKPATH}/conf/$2" 66 | local endis="$3" a=""; 67 | 68 | if [ -z "${endis}" ]; then 69 | if [ -e ${file} ]; then 70 | endis='n' 71 | else 72 | endis='y' 73 | fi 74 | fi 75 | 76 | if [ "${endis}" == 'y' ]; then 77 | echo "The service '${name}' is currently DISABLED, type Y to ENABLE the service '${name}'? (press enter to skip)"; 78 | else 79 | echo "The service '${name}' is currently ENABLED, typing Y will DISABLE the service '${name}'? (press enter to leave unchanged)"; 80 | fi 81 | 82 | while read -p'? (N/y)' -n1 a; do 83 | echo ''; 84 | if [ "${a}" == 'Y' ] || [ "${a}" == 'y' ]; then 85 | break; 86 | elif [ -z "${a}" ] || [ "${a}" == 'N' ] || [ "${a}" == 'n' ]; then 87 | return 0; 88 | fi 89 | done 90 | 91 | if [ "${endis}" == 'y' ]; then 92 | touch ${file}; 93 | else 94 | rm -f ${file} 2>&1 >/dev/null; 95 | fi 96 | } 97 | 98 | start() { 99 | ./${DEV_SELF} up; 100 | } 101 | 102 | shell() { 103 | echo ''; 104 | echo 'Add next lines to your shell to implement `cdw`(to workspace) and `dev` to PATH'; 105 | echo ''; 106 | ./${DEV_SELF} profile; 107 | } 108 | 109 | suffix; 110 | php; 111 | workspace; 112 | mysql; 113 | 114 | feature RabbitMQ rabbitmq; 115 | feature "Percona 8" mysql8; 116 | feature "ElasticSearch 6.5.4" elasticsearch; 117 | feature "ElasticSearch 7.9.1" elasticsearch7; 118 | feature "ElasticSearch HQ" elasticsearchhq; 119 | feature "ElasticSearch VUE" elasticvue; 120 | feature "Opensearch" opensearch; 121 | feature "Opensearch dashboard" opensearch-dashboard; 122 | feature MongoDB mongo; 123 | feature FTP ftp; 124 | 125 | start; 126 | shell; 127 | } 128 | 129 | setup; 130 | return 0; 131 | 132 | -------------------------------------------------------------------------------- /docs/search-ui-tools.md: -------------------------------------------------------------------------------- 1 | # Search UI Tools 2 | 3 | Several web-based user interfaces are available for managing and monitoring Elasticsearch and OpenSearch clusters. 4 | 5 | ## ElasticVue 6 | 7 | ElasticVue is a modern, feature-rich web UI for Elasticsearch and OpenSearch with a clean interface and powerful features. 8 | 9 | ### Setup 10 | 11 | Enable ElasticVue during setup or manually: 12 | ```bash 13 | mkdir -p conf/elasticvue 14 | dev rebuild 15 | ``` 16 | 17 | ### Access 18 | 19 | ElasticVue is available at: [http://localhost:8080](http://localhost:8080) 20 | 21 | ### Connecting to Elasticsearch/OpenSearch 22 | 23 | When you first access ElasticVue, add your cluster: 24 | - **URI**: `http://elasticsearch:9200` (for Elasticsearch) or `http://opensearch:9200` (for OpenSearch) 25 | - **Name**: Any name you prefer 26 | - **Username/Password**: Leave empty (no auth in development) 27 | 28 | ### Features 29 | 30 | ElasticVue provides: 31 | - **Cluster Overview**: Health, nodes, shards 32 | - **Index Management**: Create, delete, configure indices 33 | - **Document Browser**: View and edit documents 34 | - **Query Interface**: Run search queries with syntax highlighting 35 | - **Snapshots**: Manage backups 36 | - **Index Templates**: Configure templates 37 | - **REST Client**: Execute arbitrary REST API calls 38 | 39 | ### ElasticVue CORS Variants 40 | 41 | For older Elasticsearch versions that don't support CORS properly, CORS-enabled variants are available: 42 | 43 | **For Elasticsearch 6.x:** 44 | ```bash 45 | mkdir -p conf/elasticvue-cors 46 | dev rebuild 47 | ``` 48 | 49 | **For Elasticsearch 7.x:** 50 | ```bash 51 | mkdir -p conf/elasticvue-cors7 52 | dev rebuild 53 | ``` 54 | 55 | These run a proxy that adds CORS headers. 56 | 57 | ## Elasticsearch HQ 58 | 59 | Elasticsearch HQ is a lighter-weight monitoring tool focused on cluster health and management. 60 | 61 | ### Setup 62 | 63 | Enable Elasticsearch HQ: 64 | ```bash 65 | mkdir -p conf/elasticsearchhq 66 | dev rebuild 67 | ``` 68 | 69 | ### Access 70 | 71 | Elasticsearch HQ is available at: [http://localhost:5000](http://localhost:5000) 72 | 73 | ### Features 74 | 75 | Elasticsearch HQ provides: 76 | - **Cluster Health Monitoring**: Real-time cluster status 77 | - **Node Statistics**: CPU, memory, disk usage per node 78 | - **Index Information**: Index stats and settings 79 | - **Query Metrics**: Query performance data 80 | - **Shard Allocation**: Visual shard distribution 81 | 82 | Elasticsearch HQ is read-only and focuses on monitoring rather than management. 83 | 84 | ## Choosing a UI Tool 85 | 86 | **Use ElasticVue if you:** 87 | - Need full cluster management capabilities 88 | - Want to edit documents and indices 89 | - Prefer a modern, feature-rich interface 90 | - Work with both Elasticsearch and OpenSearch 91 | 92 | **Use Elasticsearch HQ if you:** 93 | - Only need monitoring (not management) 94 | - Prefer a simpler, lightweight tool 95 | - Focus on cluster health and performance 96 | 97 | ## OpenSearch Dashboard 98 | 99 | For OpenSearch specifically, OpenSearch Dashboard (similar to Kibana) is available. See [opensearch-dashboard.md](opensearch-dashboard.md). 100 | 101 | OpenSearch Dashboard is more comprehensive than ElasticVue or Elasticsearch HQ, offering: 102 | - Visualizations and dashboards 103 | - Dev Tools console 104 | - Full index management 105 | - Advanced analytics 106 | 107 | ## Troubleshooting 108 | 109 | ### Cannot Connect to Cluster 110 | 111 | Verify Elasticsearch/OpenSearch is running: 112 | ```bash 113 | dev ps | grep -E 'elasticsearch|opensearch' 114 | ``` 115 | 116 | Test connectivity from within the network: 117 | ```bash 118 | dev console curl -X GET "elasticsearch:9200" 119 | ``` 120 | 121 | ### CORS Errors 122 | 123 | If you see CORS errors with ElasticVue, use the CORS-enabled variant: 124 | - Elasticsearch 6.x: Use `elasticvue-cors` 125 | - Elasticsearch 7.x: Use `elasticvue-cors7` 126 | 127 | ### UI Tool Not Starting 128 | 129 | Check logs: 130 | ```bash 131 | dev logs elasticvue 132 | # or 133 | dev logs elasticsearchhq 134 | ``` 135 | 136 | Ensure the configuration marker exists: 137 | ```bash 138 | ls conf/elasticvue 139 | ls conf/elasticsearchhq 140 | ``` 141 | -------------------------------------------------------------------------------- /docs/php-extensions.md: -------------------------------------------------------------------------------- 1 | # PHP Extensions 2 | 3 | PHP extensions can be enabled or disabled on-demand in your development environment. This guide covers managing PHP extensions. 4 | 5 | ## Available Commands 6 | 7 | ### Enable Extension 8 | 9 | Temporarily enable a PHP extension for a running container: 10 | ```bash 11 | dev php-ext-enable extensionname 12 | ``` 13 | 14 | ### Disable Extension 15 | 16 | Temporarily disable a PHP extension: 17 | ```bash 18 | dev php-ext-disable extensionname 19 | ``` 20 | 21 | ### Verify Extension 22 | 23 | Check if an extension is loaded: 24 | ```bash 25 | dev exec php php -m | grep extensionname 26 | ``` 27 | 28 | Or check PHP info: 29 | ```bash 30 | dev php -i | grep extensionname 31 | ``` 32 | 33 | ## Common Extensions 34 | 35 | Most common PHP extensions are pre-installed: 36 | - **mbstring** - Multibyte string functions 37 | - **pdo_mysql** - MySQL database support 38 | - **gd** - Image manipulation 39 | - **curl** - HTTP requests 40 | - **xml** - XML parsing 41 | - **zip** - ZIP archive handling 42 | - **intl** - Internationalization 43 | - **soap** - SOAP client/server 44 | - **bcmath** - Arbitrary precision math 45 | - **redis** - Redis support 46 | - **xdebug** - Debugging (see [xdebug.md](xdebug.md)) 47 | - **blackfire** - Profiling (see [configure-blackfire.md](configure-blackfire.md)) 48 | 49 | ## List All Extensions 50 | 51 | See all loaded extensions: 52 | ```bash 53 | dev php -m 54 | ``` 55 | 56 | See PHP configuration: 57 | ```bash 58 | dev php -i 59 | ``` 60 | 61 | ## Temporary vs Permanent Changes 62 | 63 | ### Temporary (Until Container Restart) 64 | 65 | The `php-ext-enable` and `php-ext-disable` commands make temporary changes: 66 | ```bash 67 | dev php-ext-enable xdebug 68 | dev exec php php -v # XDebug is loaded 69 | dev restart php 70 | dev exec php php -v # XDebug is gone 71 | ``` 72 | 73 | This is useful for: 74 | - Testing extensions 75 | - Temporarily enabling debugging 76 | - Performance testing with/without extensions 77 | 78 | ### Permanent Configuration 79 | 80 | For permanent changes, customize the PHP container. See [customize-docker-containers.md](customize-docker-containers.md). 81 | 82 | Create `custom/php/Dockerfile`: 83 | ```dockerfile 84 | FROM php:8.2-fpm 85 | 86 | RUN docker-php-ext-install extensionname 87 | ``` 88 | 89 | Then use a `docker-custom.yml` to build from your custom Dockerfile. 90 | 91 | ## XDebug Special Case 92 | 93 | XDebug is available but not enabled by default for performance. Use the dedicated command: 94 | ```bash 95 | dev xdebug-console 96 | ``` 97 | 98 | See [xdebug.md](xdebug.md) for complete XDebug setup. 99 | 100 | ## Blackfire Special Case 101 | 102 | Blackfire requires configuration before use. See [configure-blackfire.md](configure-blackfire.md). 103 | 104 | ## Installing Additional Extensions 105 | 106 | If an extension isn't available, you have two options: 107 | 108 | ### Option 1: Custom Container 109 | 110 | Create a custom PHP container with the extension. See [customize-docker-containers.md](customize-docker-containers.md). 111 | 112 | ### Option 2: Runtime Installation 113 | 114 | Install temporarily in a running container: 115 | ```bash 116 | dev exec php docker-php-ext-install extensionname 117 | ``` 118 | 119 | Note: This persists only until container rebuild. 120 | 121 | ## Extension Configuration 122 | 123 | Some extensions require configuration files. These go in the PHP configuration directory inside the container. 124 | 125 | Example for custom extension config: 126 | ```bash 127 | dev exec php bash -c 'echo "extension=myext.so" > /usr/local/etc/php/conf.d/myext.ini' 128 | ``` 129 | 130 | ## Troubleshooting 131 | 132 | ### Extension Not Found 133 | 134 | List available extensions in the container: 135 | ```bash 136 | dev exec php ls /usr/local/lib/php/extensions/ 137 | ``` 138 | 139 | ### Extension Won't Load 140 | 141 | Check PHP error log: 142 | ```bash 143 | dev logs php 144 | ``` 145 | 146 | Verify extension file exists: 147 | ```bash 148 | dev exec php php --ri extensionname 149 | ``` 150 | 151 | ### Version-Specific Extensions 152 | 153 | Different PHP versions may have different extensions available. Switch PHP versions and check: 154 | ```bash 155 | dev php-change php83 156 | dev php -m 157 | ``` 158 | -------------------------------------------------------------------------------- /docs/monitoring-tools.md: -------------------------------------------------------------------------------- 1 | # Monitoring Tools 2 | 3 | Several monitoring tools are available to help you track resource usage, monitor processes, and inspect your development environment. 4 | 5 | ## Container Resource Monitoring 6 | 7 | ### dev top 8 | 9 | Monitor all running containers and their resource usage: 10 | ```bash 11 | dev top 12 | ``` 13 | 14 | This shows: 15 | - CPU usage per container 16 | - Memory consumption 17 | - Network I/O 18 | - Block I/O 19 | - Process counts 20 | 21 | Press `Ctrl+C` to exit. 22 | 23 | ### ctop 24 | 25 | ctop is an enhanced container monitoring tool with a more detailed interface. Enable it during setup: 26 | ```bash 27 | mkdir -p conf/ctop 28 | dev rebuild 29 | ``` 30 | 31 | Then run: 32 | ```bash 33 | dev exec ctop ctop 34 | ``` 35 | 36 | ctop provides: 37 | - Real-time container metrics 38 | - Interactive container management 39 | - Resource usage graphs 40 | - Container logs access 41 | 42 | ## MySQL Monitoring 43 | 44 | ### mytop 45 | 46 | mytop monitors MySQL queries and processes in real-time. It's similar to `top` but for MySQL. 47 | 48 | Enable mytop: 49 | ```bash 50 | mkdir -p conf/mytop 51 | dev rebuild 52 | ``` 53 | 54 | Run mytop: 55 | ```bash 56 | dev mytop 57 | ``` 58 | 59 | mytop shows: 60 | - Currently running queries 61 | - Query execution time 62 | - Database connections 63 | - Slow queries 64 | - Server status 65 | 66 | Press `q` to quit. 67 | 68 | ### MySQL Process List 69 | 70 | View current MySQL processes: 71 | ```bash 72 | dev mysql -e "SHOW PROCESSLIST;" 73 | ``` 74 | 75 | For full query text: 76 | ```bash 77 | dev mysql -e "SHOW FULL PROCESSLIST;" 78 | ``` 79 | 80 | ## Docker System Monitoring 81 | 82 | ### System Info 83 | 84 | View Docker system information: 85 | ```bash 86 | docker system info 87 | ``` 88 | 89 | ### Disk Usage 90 | 91 | Check Docker disk usage: 92 | ```bash 93 | docker system df 94 | ``` 95 | 96 | For detailed breakdown: 97 | ```bash 98 | docker system df -v 99 | ``` 100 | 101 | ### Container Stats 102 | 103 | Real-time stats for all containers: 104 | ```bash 105 | docker stats 106 | ``` 107 | 108 | Stats for specific container: 109 | ```bash 110 | docker stats php 111 | ``` 112 | 113 | ## Service-Specific Monitoring 114 | 115 | ### RabbitMQ Management Interface 116 | 117 | Monitor RabbitMQ queues and messages at: [http://localhost:15672](http://localhost:15672) 118 | 119 | See [rabbitmq.md](rabbitmq.md) for details. 120 | 121 | ### Elasticsearch/OpenSearch 122 | 123 | Check cluster health: 124 | ```bash 125 | dev console curl -X GET "elasticsearch:9200/_cluster/health?pretty" 126 | ``` 127 | 128 | Or for OpenSearch: 129 | ```bash 130 | dev console curl -X GET "opensearch:9200/_cluster/health?pretty" 131 | ``` 132 | 133 | ### Elasticsearch HQ 134 | 135 | Web-based Elasticsearch monitoring. Enable it: 136 | ```bash 137 | mkdir -p conf/elasticsearchhq 138 | dev rebuild 139 | ``` 140 | 141 | Access at: [http://localhost:5000](http://localhost:5000) 142 | 143 | See [search-ui-tools.md](search-ui-tools.md) for more details. 144 | 145 | ### ElasticVue 146 | 147 | Modern Elasticsearch/OpenSearch web UI. Enable it: 148 | ```bash 149 | mkdir -p conf/elasticvue 150 | dev rebuild 151 | ``` 152 | 153 | Access at: [http://localhost:8080](http://localhost:8080) 154 | 155 | See [search-ui-tools.md](search-ui-tools.md) for more details. 156 | 157 | ## Log Monitoring 158 | 159 | ### Container Logs 160 | 161 | View logs for any container: 162 | ```bash 163 | dev logs containername 164 | ``` 165 | 166 | Follow logs in real-time: 167 | ```bash 168 | dev logs -f containername 169 | ``` 170 | 171 | View last 100 lines: 172 | ```bash 173 | dev logs --tail=100 containername 174 | ``` 175 | 176 | ### Multiple Container Logs 177 | 178 | View logs from multiple containers: 179 | ```bash 180 | dev logs php nginx 181 | ``` 182 | 183 | ## Performance Profiling 184 | 185 | For application performance profiling: 186 | - **XDebug**: See [xdebug.md](xdebug.md) 187 | - **Blackfire**: See [configure-blackfire.md](configure-blackfire.md) 188 | 189 | ## Troubleshooting Performance Issues 190 | 191 | ### High CPU Usage 192 | 193 | Identify which container is using CPU: 194 | ```bash 195 | dev top 196 | ``` 197 | 198 | Check processes inside that container: 199 | ```bash 200 | dev exec containername top 201 | ``` 202 | 203 | ### High Memory Usage 204 | 205 | Check memory usage: 206 | ```bash 207 | docker stats --no-stream 208 | ``` 209 | 210 | Inspect specific container: 211 | ```bash 212 | docker inspect containername | grep -i memory 213 | ``` 214 | 215 | ### Slow Database Queries 216 | 217 | Use mytop to identify slow queries: 218 | ```bash 219 | dev mytop 220 | ``` 221 | 222 | Or check the slow query log (if enabled in MySQL configuration). 223 | 224 | ### Network Issues 225 | 226 | Monitor network I/O: 227 | ```bash 228 | dev top 229 | ``` 230 | 231 | Check container networking: 232 | ```bash 233 | docker network inspect dockerdev_default 234 | ``` 235 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # F.A.Q. 2 | 3 | ## Where is my mail going? / I am not receiving my mail? 4 | No e-mail is send externally, everything is catched by MailHog. 5 | Be aware if you are using sendgrid, mailchimp or similar mail API's, we do not catch those. 6 | 7 | Access MailHog at [http://mail.localhost](http://mail.localhost) to see all caught emails. 8 | 9 | ## How to configure MySQL 10 | 11 | MySQL configuration can be customized in `conf/mysql/my.cnf`: 12 | ```bash 13 | mkdir -p conf/mysql 14 | nano conf/mysql/my.cnf 15 | ``` 16 | 17 | Set the root password in your `.env` file or during `dev setup`. 18 | 19 | For more details, see [mysql-mailhog-redis-cronjobs.md](mysql-mailhog-redis-cronjobs.md). 20 | 21 | ## How to configure Blackfire 22 | 23 | Create a `conf/blackfire` file with your Blackfire credentials from [blackfire.io](https://blackfire.io): 24 | ```bash 25 | BLACKFIRE_CLIENT_ID=your-id 26 | BLACKFIRE_CLIENT_TOKEN=your-token 27 | BLACKFIRE_SERVER_ID=your-server-id 28 | BLACKFIRE_SERVER_TOKEN=your-server-token 29 | ``` 30 | 31 | Then restart: `dev down && dev up` 32 | 33 | For complete setup instructions, see [configure-blackfire.md](configure-blackfire.md). 34 | 35 | ## What PHP versions are supported? 36 | 37 | The environment supports PHP 7.4, 8.0, 8.1, 8.2, 8.3, 8.4, and 8.5. The default is PHP 8.2. 38 | 39 | Switch PHP versions using marker files: 40 | ```bash 41 | cd workspace/customer/project 42 | touch .php83 # Use PHP 8.3 for this project 43 | ``` 44 | 45 | See [how-to-use-different-php-versions.md](how-to-use-different-php-versions.md) for details. 46 | 47 | ## How do I enable optional services? 48 | 49 | Enable services during setup with `dev setup`, or manually: 50 | ```bash 51 | mkdir -p conf/servicename # e.g., conf/elasticsearch, conf/rabbitmq 52 | dev rebuild 53 | ``` 54 | 55 | Available optional services include: Elasticsearch, OpenSearch, RabbitMQ, MongoDB, Varnish, MySQL 8, and more. 56 | 57 | ## Where are my files stored? 58 | 59 | By default, your projects are in the `workspace/` directory. The exact location depends on your setup: 60 | - **Local directory**: `~/development/workspace/` 61 | - **Docker volume**: Use `docker volume inspect dockerdev-workspace-volume` 62 | 63 | Database files are similarly in `mysql/` or a Docker volume. 64 | 65 | See [docker-volumes.md](docker-volumes.md) for volume management. 66 | 67 | ## How do I debug with XDebug? 68 | 69 | Use the XDebug console command: 70 | ```bash 71 | dev xdebug-console 72 | ``` 73 | 74 | Then configure your IDE to listen on port 9003 and set up path mappings from your local project to `/data/workspace/customer/project`. 75 | 76 | See [xdebug.md](xdebug.md) for complete setup instructions. 77 | 78 | ## Can I use multiple MySQL versions? 79 | 80 | Yes. The default MySQL 5.7/Percona runs on port 3306. You can also enable MySQL 8 on port 3308: 81 | ```bash 82 | mkdir -p conf/mysql8 83 | dev rebuild 84 | ``` 85 | 86 | Connect to MySQL 8 using `127.0.0.1:3308` from your host or `db8:3306` from containers. 87 | 88 | See [mysql8.md](mysql8.md) for details. 89 | 90 | ## What monitoring tools are available? 91 | 92 | Several monitoring tools are available: 93 | - `dev top` - Container resource monitoring 94 | - `dev mytop` - MySQL process monitoring 95 | - ctop - Enhanced container monitoring 96 | - Elasticsearch HQ - Elasticsearch monitoring UI (localhost:5000) 97 | - ElasticVue - Modern search engine UI (localhost:8080) 98 | - RabbitMQ Management - Queue management (localhost:15672) 99 | 100 | See [monitoring-tools.md](monitoring-tools.md) for more details. 101 | 102 | ## How do I share my environment externally? 103 | 104 | Use ngrok or BeyondCode Expose to create a tunnel: 105 | ```bash 106 | dev ngrok your-project.localhost 107 | ``` 108 | 109 | Or: 110 | ```bash 111 | dev expose your-project.localhost 112 | ``` 113 | 114 | This provides a public URL that forwards to your local environment. 115 | 116 | See [sharing-with-the-world-via-ngrok.md](sharing-with-the-world-via-ngrok.md) and [expose.md](expose.md). 117 | 118 | ## How do I backup my databases? 119 | 120 | Use mysqldump: 121 | ```bash 122 | dev mysqldump database_name > backup.sql 123 | ``` 124 | 125 | Restore with: 126 | ```bash 127 | dev mysql database_name < backup.sql 128 | ``` 129 | 130 | For complete backup strategies, see [backup-restore.md](backup-restore.md). 131 | 132 | ## How do I improve performance? 133 | 134 | Key optimizations: 135 | - Use Composer 2: `dev composer2` 136 | - Use Docker volumes instead of bind mounts (macOS/Windows) 137 | - Increase Docker Desktop resources (CPUs, memory) 138 | - Enable production mode in Magento 2 139 | - Configure MySQL memory settings 140 | 141 | See [performance-tuning.md](performance-tuning.md) for comprehensive optimization techniques. 142 | 143 | ## Where can I find documentation? 144 | 145 | All documentation is in the `docs/` directory. Key documents: 146 | - [README.md](../README.md) - Getting started 147 | - [development-commands.md](development-commands.md) - Command reference 148 | - [hosts-and-file-structure.md](hosts-and-file-structure.md) - Project structure 149 | 150 | For a complete list, see the Documentation section in [README.md](../README.md). 151 | -------------------------------------------------------------------------------- /docs/custom-compose-files.md: -------------------------------------------------------------------------------- 1 | # Custom Docker Compose Files 2 | 3 | You can customize and extend the Docker Compose configuration without modifying the core files. This allows you to receive updates while maintaining your custom configuration. 4 | 5 | ## docker-custom.yml 6 | 7 | The `docker-custom.yml` file is gitignored and allows you to override or extend any service configuration. 8 | 9 | ### Creating docker-custom.yml 10 | 11 | Create the file in your development root: 12 | ```bash 13 | cd ~/development 14 | nano docker-custom.yml 15 | ``` 16 | 17 | ### Basic Structure 18 | 19 | ```yaml 20 | version: '2' 21 | 22 | services: 23 | servicename: 24 | # Your customizations here 25 | ``` 26 | 27 | ### Example: Custom PHP Container 28 | 29 | To add custom components to the PHP container: 30 | 31 | **1. Create docker-custom.yml:** 32 | ```yaml 33 | version: '2' 34 | 35 | services: 36 | php: 37 | build: custom/php 38 | ``` 39 | 40 | **2. Create custom Dockerfile:** 41 | ```bash 42 | mkdir -p custom/php 43 | nano custom/php/Dockerfile 44 | ``` 45 | 46 | **3. Extend the base PHP image:** 47 | ```dockerfile 48 | FROM ghcr.io/jeroenboersma/php-development:8.2-fpm 49 | 50 | # Install additional packages 51 | RUN apt-get update && apt-get install -y \ 52 | your-package-here \ 53 | && rm -rf /var/lib/apt/lists/* 54 | 55 | # Install additional PHP extensions 56 | RUN docker-php-ext-install extensionname 57 | 58 | # Copy custom configuration 59 | COPY custom-config.ini /usr/local/etc/php/conf.d/ 60 | ``` 61 | 62 | **4. Rebuild:** 63 | ```bash 64 | dev rebuild 65 | ``` 66 | 67 | ### Example: Override Environment Variables 68 | 69 | ```yaml 70 | version: '2' 71 | 72 | services: 73 | db: 74 | environment: 75 | MYSQL_ROOT_PASSWORD: mycustompassword 76 | 77 | php82: 78 | environment: 79 | PHP_MEMORY_LIMIT: 512M 80 | ``` 81 | 82 | ### Example: Add Custom Volumes 83 | 84 | ```yaml 85 | version: '2' 86 | 87 | services: 88 | php: 89 | volumes: 90 | - /path/on/host:/path/in/container 91 | ``` 92 | 93 | ### Example: Expose Additional Ports 94 | 95 | ```yaml 96 | version: '2' 97 | 98 | services: 99 | web: 100 | ports: 101 | - "8080:80" 102 | ``` 103 | 104 | ## docker-compose-dev.yml 105 | 106 | For project-specific overrides, use `docker-compose-dev.yml`. This can be committed to your project repository. 107 | 108 | Place it in your project directory: 109 | ```bash 110 | cd workspace/customer/project 111 | nano docker-compose-dev.yml 112 | ``` 113 | 114 | ## Custom Build Directory 115 | 116 | The `./custom` directory is gitignored and meant for your customizations: 117 | 118 | ``` 119 | custom/ 120 | ├── php/ 121 | │ ├── Dockerfile 122 | │ └── config.ini 123 | ├── nginx/ 124 | │ └── custom-site.conf 125 | └── mysql/ 126 | └── custom.cnf 127 | ``` 128 | 129 | ## Combining Multiple Compose Files 130 | 131 | Docker Compose automatically merges configurations in this order: 132 | 1. `docker-compose.yml` (base) 133 | 2. `build/dist/docker-compose-*.yml` (enabled services) 134 | 3. `docker-custom.yml` (your customizations) 135 | 4. `docker-compose-dev.yml` (project-specific) 136 | 137 | Later files override earlier ones. 138 | 139 | ## Best Practices 140 | 141 | ### Do: 142 | - Use `docker-custom.yml` for personal/environment-specific changes 143 | - Use `docker-compose-dev.yml` for project-specific changes 144 | - Document your customizations 145 | - Keep custom Dockerfiles simple 146 | 147 | ### Don't: 148 | - Modify core `docker-compose.yml` directly (you'll lose changes on update) 149 | - Commit `docker-custom.yml` to version control 150 | - Override critical service dependencies 151 | - Make breaking changes to service names/networks 152 | 153 | ## Advanced Customizations 154 | 155 | ### Adding a New Service 156 | 157 | ```yaml 158 | version: '2' 159 | 160 | services: 161 | myservice: 162 | image: myimage:latest 163 | networks: 164 | - default 165 | volumes: 166 | - dockerdev-workspace-volume:/data 167 | ``` 168 | 169 | ### Changing PHP Version Default 170 | 171 | ```yaml 172 | version: '2' 173 | 174 | services: 175 | php: 176 | build: 177 | context: build/dist/php 178 | args: 179 | PHP_VERSION: 8.3 180 | ``` 181 | 182 | ### Custom Network Configuration 183 | 184 | ```yaml 185 | version: '2' 186 | 187 | services: 188 | myservice: 189 | networks: 190 | mynetwork: 191 | ipv4_address: 172.25.0.100 192 | 193 | networks: 194 | mynetwork: 195 | driver: bridge 196 | ipam: 197 | config: 198 | - subnet: 172.25.0.0/16 199 | ``` 200 | 201 | ## Troubleshooting 202 | 203 | ### Rebuild After Changes 204 | 205 | Always rebuild after modifying compose files: 206 | ```bash 207 | dev rebuild 208 | ``` 209 | 210 | ### Verify Configuration 211 | 212 | Check the merged configuration: 213 | ```bash 214 | dev config 215 | ``` 216 | 217 | This shows the final composed configuration. 218 | 219 | ### Syntax Errors 220 | 221 | Validate your YAML: 222 | ```bash 223 | docker-compose -f docker-custom.yml config 224 | ``` 225 | 226 | ### Changes Not Applied 227 | 228 | Ensure you're using the correct file name: 229 | - `docker-custom.yml` (not `docker-custom.yaml`) 230 | - Place it in the development root directory 231 | 232 | Force recreation: 233 | ```bash 234 | dev down 235 | dev up --force-recreate 236 | ``` 237 | 238 | ## See Also 239 | 240 | - [customize-docker-containers.md](customize-docker-containers.md) - Basic customization guide 241 | - [environment-configuration.md](environment-configuration.md) - Environment variables 242 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | ## Prerequisites 3 | Install docker engine and docker compose plugin, for more info check: https://docs.docker.com/engine/install/ 4 | 5 | ```bash 6 | sudo apt-get remove docker docker-engine docker.io containerd runc 7 | sudo apt-get update 8 | sudo apt-get install \ 9 | ca-certificates \ 10 | curl \ 11 | gnupg \ 12 | lsb-release 13 | 14 | sudo mkdir -p /etc/apt/keyrings 15 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg 16 | 17 | echo \ 18 | "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 19 | $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 20 | 21 | sudo apt-get update 22 | 23 | sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin 24 | ``` 25 | 26 | ### Add user to the docker group and reboot 27 | ```bash 28 | sudo usermod -aG docker ${USER} 29 | reboot 30 | ``` 31 | 32 | ## Cloning 33 | https://github.com/JeroenBoersma/docker-compose-development/tree/development-docker-compose-2/ 34 | 35 | ```bash 36 | git clone -b development-docker-compose-2 https://github.com/JeroenBoersma/docker-compose-development.git development 37 | 38 | cd development 39 | bin/dev setup 40 | # press enter a few times and read instructions 41 | # default php81 42 | # setup your needs (elasticsearch/rabbitmq/etcetera) 43 | # you can always run this again 44 | 45 | # adding to your profile to use `dev` commands 46 | bin/dev profile >> ~/.zshrc # or ~/.bashrc if you use bash 47 | ``` 48 | 49 | If you just installed zsh and your shell isn't changing to zsh, try logging in and out. 50 | 51 | ## Move the workspace directory to home 52 | To avoid having the .git from the clone in your workspace, you can optionally move your workspace to your home directory. 53 | 54 | ```bash 55 | cd 56 | 57 | dev down --remove-orphans 58 | 59 | dev volume rm workspace 60 | mkdir workspace 61 | dev volume workspace workspace 62 | 63 | cdw 64 | dev php-change php81 # if that's the default 65 | 66 | dev up 67 | ``` 68 | 69 | ## Make MySQL persistent in your development directory (optional) 70 | This will destroy all current databases 71 | 72 | ```bash 73 | cd 74 | cd development 75 | 76 | dev down --remove-orphans 77 | 78 | dev volume rm mysql 79 | mkdir mysql 80 | dev volume mysql mysql 81 | 82 | dev setup # this will add your user and correct settings (press enter to everything) 83 | ``` 84 | 85 | ## Documentation 86 | 87 | Comprehensive documentation is available in the `docs/` directory. 88 | 89 | ### Getting Started 90 | - [Development Commands](docs/development-commands.md) - All available `dev` commands 91 | - [Hosts and File Structure](docs/hosts-and-file-structure.md) - Project structure and hostname conventions 92 | - [How to Use Different PHP Versions](docs/how-to-use-different-php-versions.md) - PHP version switching 93 | - [F.A.Q.](docs/faq.md) - Frequently asked questions 94 | 95 | ### Core Services 96 | - [MySQL, MailHog, Redis, and Cronjobs](docs/mysql-mailhog-redis-cronjobs.md) - Core service configuration 97 | - [MySQL 8](docs/mysql8.md) - MySQL 8 setup and usage 98 | - [Elasticsearch](docs/elasticsearch.md) - Elasticsearch 6.5.4 and 7.9.1 setup 99 | - [OpenSearch](docs/opensearch.md) - OpenSearch setup and configuration 100 | - [OpenSearch Dashboard](docs/opensearch-dashboard.md) - OpenSearch Dashboard UI 101 | - [MongoDB](docs/mongodb.md) - MongoDB and mongo-express setup 102 | - [RabbitMQ](docs/rabbitmq.md) - RabbitMQ message broker setup 103 | 104 | ### Development Tools 105 | - [Node.js, NPM, and Yarn](docs/node-npm-yarn.md) - Frontend tooling and package managers 106 | - [XDebug](docs/xdebug.md) - PHP debugging with XDebug 107 | - [Varnish](docs/varnish.md) - HTTP caching with Varnish 108 | - [FTP Server](docs/ftp.md) - FTP access to workspace 109 | - [Git and SSH Integration](docs/git-ssh-integration.md) - Git commands and SSH key forwarding 110 | 111 | ### Configuration 112 | - [Environment Configuration](docs/environment-configuration.md) - .env file and configuration markers 113 | - [Docker Volumes](docs/docker-volumes.md) - Volume management and persistence 114 | - [PHP Extensions](docs/php-extensions.md) - Managing PHP extensions 115 | - [Custom Docker Compose Files](docs/custom-compose-files.md) - Customization with docker-custom.yml 116 | - [Customize Docker Containers](docs/customize-docker-containers.md) - Container customization basics 117 | 118 | ### Monitoring & Tools 119 | - [Monitoring Tools](docs/monitoring-tools.md) - Container and database monitoring 120 | - [Search UI Tools](docs/search-ui-tools.md) - ElasticVue and Elasticsearch HQ 121 | - [Port Reference](docs/port-reference.md) - Complete port assignments 122 | 123 | ### Performance & Optimization 124 | - [Performance Tuning](docs/performance-tuning.md) - Optimization techniques 125 | - [Backup and Restore](docs/backup-restore.md) - Backup strategies and restore procedures 126 | 127 | ### Profiling & Debugging 128 | - [Configure Blackfire](docs/configure-blackfire.md) - Blackfire profiler setup 129 | 130 | ### Sharing & Networking 131 | - [Sharing with the World via ngrok](docs/sharing-with-the-world-via-ngrok.md) - ngrok tunneling 132 | - [BeyondCode Expose](docs/expose.md) - Expose server for sharing 133 | - [UFW Firewall](docs/ufw-firewall.md) - Firewall configuration 134 | 135 | ### Advanced Topics 136 | - [Advanced Docker Configuration](docs/advanced-docker-configuration.md) - UID/GID, build arguments, networks 137 | - [Install Other PHP Versions](docs/install-other-php-versions.md) - Installing older PHP versions 138 | - [Used Base Images](docs/used-base-images.md) - Docker image references 139 | 140 | ### Contributing 141 | - [Code of Conduct](docs/code-of-conduct.md) - Contributor guidelines 142 | 143 | 144 | -------------------------------------------------------------------------------- /docs/git-ssh-integration.md: -------------------------------------------------------------------------------- 1 | # Git and SSH Integration 2 | 3 | The development environment includes Git support and automatic SSH key forwarding, allowing you to use Git and authenticate with remote services from within containers. 4 | 5 | ## Git Command 6 | 7 | Run Git commands from your project directory: 8 | ```bash 9 | dev git status 10 | dev git add . 11 | dev git commit -m "message" 12 | dev git push 13 | ``` 14 | 15 | The `dev git` command: 16 | - Runs Git inside the PHP container 17 | - Uses your workspace directory as the working directory 18 | - Forwards your SSH agent for authentication 19 | - Preserves your user context 20 | 21 | ## SSH Key Forwarding 22 | 23 | SSH keys are automatically forwarded from your host to the containers when available. 24 | 25 | ### How It Works 26 | 27 | If the `SSH_AUTH_SOCK` environment variable is set on your host, the environment automatically: 28 | 1. Detects your SSH agent 29 | 2. Mounts the SSH auth socket into containers 30 | 3. Sets up SSH agent forwarding 31 | 32 | ### Prerequisites 33 | 34 | Start your SSH agent and add your key: 35 | ```bash 36 | eval $(ssh-agent) 37 | ssh-add ~/.ssh/id_rsa 38 | ``` 39 | 40 | Or add to your shell profile (`~/.bashrc` or `~/.zshrc`): 41 | ```bash 42 | if [ -z "$SSH_AUTH_SOCK" ]; then 43 | eval $(ssh-agent -s) 44 | ssh-add ~/.ssh/id_rsa 45 | fi 46 | ``` 47 | 48 | ### Verify SSH Forwarding 49 | 50 | Check if SSH agent is available in container: 51 | ```bash 52 | dev console 53 | echo $SSH_AUTH_SOCK 54 | ssh-add -l 55 | ``` 56 | 57 | You should see your SSH keys listed. 58 | 59 | ### Using SSH in Containers 60 | 61 | Clone repositories: 62 | ```bash 63 | dev console 64 | cd /data/workspace/customer/project 65 | git clone git@github.com:user/repo.git 66 | ``` 67 | 68 | Access remote servers: 69 | ```bash 70 | dev console 71 | ssh user@remote-server 72 | ``` 73 | 74 | ## Git Configuration 75 | 76 | ### Global Git Config 77 | 78 | Your Git configuration from the host is not automatically available in containers. Set it up: 79 | 80 | ```bash 81 | dev git config --global user.name "Your Name" 82 | dev git config --global user.email "your@email.com" 83 | ``` 84 | 85 | ### Per-Project Git Config 86 | 87 | In your project: 88 | ```bash 89 | cd workspace/customer/project 90 | dev git config user.name "Your Name" 91 | dev git config user.email "your@email.com" 92 | ``` 93 | 94 | ### Git Aliases 95 | 96 | Create helpful aliases: 97 | ```bash 98 | dev git config --global alias.co checkout 99 | dev git config --global alias.br branch 100 | dev git config --global alias.ci commit 101 | dev git config --global alias.st status 102 | ``` 103 | 104 | ## Common Git Workflows 105 | 106 | ### Clone a Repository 107 | 108 | ```bash 109 | cd workspace 110 | dev git clone git@github.com:user/repo.git customer/project 111 | ``` 112 | 113 | ### Daily Workflow 114 | 115 | ```bash 116 | cd workspace/customer/project 117 | dev git pull 118 | # make changes 119 | dev git add . 120 | dev git commit -m "Description of changes" 121 | dev git push 122 | ``` 123 | 124 | ### Branch Management 125 | 126 | ```bash 127 | dev git checkout -b feature-branch 128 | dev git push -u origin feature-branch 129 | dev git checkout main 130 | dev git branch -d feature-branch 131 | ``` 132 | 133 | ## Composer with Private Repositories 134 | 135 | When using Composer with private Git repositories, SSH forwarding allows authentication: 136 | 137 | ```bash 138 | dev console 139 | composer require organization/private-package 140 | ``` 141 | 142 | Composer will use your forwarded SSH keys to authenticate. 143 | 144 | ### GitHub/GitLab Tokens 145 | 146 | Alternatively, configure Composer with access tokens: 147 | ```bash 148 | dev console 149 | composer config --global github-oauth.github.com YOUR_TOKEN 150 | ``` 151 | 152 | ## SSH Config Files 153 | 154 | To use custom SSH configurations, mount your SSH config: 155 | 156 | In `docker-custom.yml`: 157 | ```yaml 158 | version: '2' 159 | 160 | services: 161 | php: 162 | volumes: 163 | - ~/.ssh/config:/root/.ssh/config:ro 164 | ``` 165 | 166 | ## Troubleshooting 167 | 168 | ### SSH Authentication Failed 169 | 170 | Verify SSH agent is running: 171 | ```bash 172 | echo $SSH_AUTH_SOCK 173 | ssh-add -l 174 | ``` 175 | 176 | Add your key if needed: 177 | ```bash 178 | ssh-add ~/.ssh/id_rsa 179 | ``` 180 | 181 | Restart containers: 182 | ```bash 183 | dev restart 184 | ``` 185 | 186 | ### Git Command Not Found 187 | 188 | Ensure you're using `dev git`, not just `git`: 189 | ```bash 190 | dev git status # Correct 191 | ``` 192 | 193 | ### Permission Denied (publickey) 194 | 195 | Test SSH connection: 196 | ```bash 197 | dev console 198 | ssh -T git@github.com 199 | ``` 200 | 201 | Verify your key is in the agent: 202 | ```bash 203 | dev console 204 | ssh-add -l 205 | ``` 206 | 207 | ### Git Asking for Username/Password 208 | 209 | You're using HTTPS instead of SSH. Clone with SSH: 210 | ```bash 211 | # Not this: 212 | dev git clone https://github.com/user/repo.git 213 | 214 | # Use this: 215 | dev git clone git@github.com:user/repo.git 216 | ``` 217 | 218 | Or convert existing repository: 219 | ```bash 220 | dev git remote set-url origin git@github.com:user/repo.git 221 | ``` 222 | 223 | ## Advanced: Multiple SSH Keys 224 | 225 | If you use different SSH keys for different services: 226 | 227 | Create `~/.ssh/config`: 228 | ``` 229 | Host github.com 230 | HostName github.com 231 | User git 232 | IdentityFile ~/.ssh/id_rsa_github 233 | 234 | Host gitlab.com 235 | HostName gitlab.com 236 | User git 237 | IdentityFile ~/.ssh/id_rsa_gitlab 238 | ``` 239 | 240 | Add all keys to agent: 241 | ```bash 242 | ssh-add ~/.ssh/id_rsa_github 243 | ssh-add ~/.ssh/id_rsa_gitlab 244 | ``` 245 | 246 | ## See Also 247 | 248 | - [advanced-docker-configuration.md](advanced-docker-configuration.md) - UID/GID and build arguments 249 | - [custom-compose-files.md](custom-compose-files.md) - Mounting custom volumes 250 | -------------------------------------------------------------------------------- /docs/port-reference.md: -------------------------------------------------------------------------------- 1 | # Port Reference 2 | 3 | This reference lists all ports used by services in the development environment. 4 | 5 | ## Core Services 6 | 7 | | Service | Port(s) | Protocol | Access | Description | 8 | |---------|---------|----------|--------|-------------| 9 | | **nginx/ssl** | 80, 443 | HTTP/HTTPS | localhost | Web server and SSL proxy | 10 | | **MySQL (db)** | 3306 | TCP | 127.0.0.1:3306 | Default MySQL/Percona database | 11 | | **Redis** | 6379 | TCP | redis:6379 | Redis cache server (internal) | 12 | | **MailHog SMTP** | 1025 | SMTP | mailcatch:1025 | Email testing SMTP (internal) | 13 | | **MailHog Web** | 8025 | HTTP | localhost:8025 | MailHog web interface | 14 | 15 | Access MailHog at: [http://mail.localhost](http://mail.localhost) 16 | 17 | ## PHP-FPM Services 18 | 19 | | Service | Port | Protocol | Description | 20 | |---------|------|----------|-------------| 21 | | **php74** | 9000 | FastCGI | PHP 7.4 FPM | 22 | | **php80** | 9000 | FastCGI | PHP 8.0 FPM | 23 | | **php81** | 9000 | FastCGI | PHP 8.1 FPM | 24 | | **php82** | 9000 | FastCGI | PHP 8.2 FPM | 25 | | **php83** | 9000 | FastCGI | PHP 8.3 FPM | 26 | | **php84** | 9000 | FastCGI | PHP 8.4 FPM | 27 | | **php85** | 9000 | FastCGI | PHP 8.5 FPM | 28 | 29 | Note: PHP containers are accessed internally via FastCGI, not directly exposed. 30 | 31 | ## Optional Services - Databases 32 | 33 | | Service | Port(s) | Protocol | Access | Description | 34 | |---------|---------|----------|--------|-------------| 35 | | **MySQL 8 (db8)** | 3308 | TCP | 127.0.0.1:3308 | MySQL 8 database (alternative instance) | 36 | | **MongoDB** | 27017 | TCP | mongo:27017 | MongoDB NoSQL database (internal) | 37 | | **OpenSearch** | 9200 | HTTP | opensearch:9200 | OpenSearch search engine (internal) | 38 | 39 | ## Optional Services - Search & Monitoring 40 | 41 | | Service | Port | Protocol | Access | Description | 42 | |---------|------|----------|--------|-------------| 43 | | **Elasticsearch** | 9200 | HTTP | elasticsearch:9200 | Elasticsearch 6.5.4 (internal) | 44 | | **Elasticsearch 7** | 9200 | HTTP | elasticsearch:9200 | Elasticsearch 7.9.1 (internal) | 45 | | **Elasticsearch HQ** | 5000 | HTTP | localhost:5000 | Elasticsearch monitoring UI | 46 | | **ElasticVue** | 8080 | HTTP | localhost:8080 | Elasticsearch/OpenSearch web UI | 47 | | **OpenSearch Dashboard** | 5601 | HTTP | localhost:5601 | OpenSearch Dashboard (Kibana alternative) | 48 | 49 | ## Optional Services - Message Queues 50 | 51 | | Service | Port(s) | Protocol | Access | Description | 52 | |---------|----------|----------|--------|-------------| 53 | | **RabbitMQ AMQP** | 5672 | AMQP | rabbitmq:5672 | RabbitMQ message broker (internal) | 54 | | **RabbitMQ Management** | 15672 | HTTP | localhost:15672 | RabbitMQ web management UI | 55 | 56 | Access RabbitMQ at: [http://localhost:15672](http://localhost:15672) 57 | 58 | ## Optional Services - Development Tools 59 | 60 | | Service | Port | Protocol | Access | Description | 61 | |---------|------|----------|--------|-------------| 62 | | **mongo-express** | 8081 | HTTP | localhost:8081 | MongoDB web interface | 63 | | **FTP** | 21 | FTP | localhost:21 | FTP server for workspace access | 64 | 65 | ## Optional Services - Other 66 | 67 | | Service | Port | Protocol | Access | Description | 68 | |---------|------|----------|--------|-------------| 69 | | **Varnish** | 80, 6081 | HTTP | varnish:80 | HTTP cache layer (internal) | 70 | | **ngrok** | varies | HTTP/HTTPS | varies | Tunneling service (dynamic ports) | 71 | | **Expose** | varies | HTTP/HTTPS | varies | Expose server (dynamic ports) | 72 | 73 | ## Debugging & Profiling Ports 74 | 75 | | Service | Port | Protocol | Description | 76 | |---------|------|----------|-------------| 77 | | **XDebug** | 9003 | TCP | XDebug 3.x debugging protocol | 78 | | **XDebug (legacy)** | 9000 | TCP | XDebug 2.x debugging protocol | 79 | | **Blackfire** | 8707 | TCP | Blackfire profiling agent | 80 | 81 | ## Port Binding Notes 82 | 83 | ### External Binding (127.0.0.1) 84 | 85 | Services bound to `127.0.0.1` are accessible only from the host machine: 86 | - MySQL (3306, 3308) 87 | - Web services (80, 443 via ssl proxy) 88 | - Management UIs (8081, 15672, 5000, 8080) 89 | 90 | ### Internal Only 91 | 92 | Services without published ports are accessible only from other containers: 93 | - Redis (6379) 94 | - MongoDB internal (27017) 95 | - Elasticsearch/OpenSearch (9200) 96 | - RabbitMQ AMQP (5672) 97 | - MailHog SMTP (1025) 98 | 99 | ### Host Network Mode 100 | 101 | Some services use host network mode and don't have fixed ports: 102 | - ngrok 103 | - expose 104 | 105 | ## Port Conflicts 106 | 107 | ### Common Conflicts 108 | 109 | **Port 80/443:** 110 | - **Conflict:** System web server (Apache, nginx) 111 | - **Solution:** Stop system web server or change dev environment ports 112 | 113 | **Port 3306:** 114 | - **Conflict:** System MySQL/MariaDB 115 | - **Solution:** Stop system MySQL or use MySQL 8 on port 3308 116 | 117 | **Port 5672:** 118 | - **Conflict:** System RabbitMQ 119 | - **Solution:** Stop system RabbitMQ 120 | 121 | ### Checking Port Usage 122 | 123 | See what's using a port: 124 | ```bash 125 | sudo lsof -i :3306 126 | sudo netstat -tlnp | grep :3306 127 | ``` 128 | 129 | ### Changing Ports 130 | 131 | To change ports, use `docker-custom.yml`: 132 | ```yaml 133 | services: 134 | db: 135 | ports: 136 | - "127.0.0.1:3307:3306" # Use 3307 instead of 3306 137 | ``` 138 | 139 | ## Firewall Configuration 140 | 141 | If using UFW firewall, allow necessary ports. See [ufw-firewall.md](ufw-firewall.md). 142 | 143 | ## Security Notes 144 | 145 | ### Localhost Binding 146 | 147 | Most services are bound to `127.0.0.1`, making them accessible only from the local machine, not from the network. This is secure for development. 148 | 149 | ### Network Accessible Services 150 | 151 | If you need network access (from other devices): 152 | ```yaml 153 | services: 154 | db: 155 | ports: 156 | - "0.0.0.0:3306:3306" # WARNING: Exposes to network 157 | ``` 158 | 159 | Only do this in trusted networks. 160 | 161 | ## Quick Reference 162 | 163 | ### Most Common Ports 164 | - **Web**: http://localhost or http://*.localhost 165 | - **MailHog**: http://mail.localhost 166 | - **MySQL**: 127.0.0.1:3306 167 | - **RabbitMQ**: http://localhost:15672 168 | 169 | ### From Application Code 170 | - **MySQL**: host=`db`, port=`3306` 171 | - **MySQL 8**: host=`db8`, port=`3306` (internal) or `127.0.0.1:3308` (external) 172 | - **Redis**: host=`redis`, port=`6379` 173 | - **Elasticsearch**: host=`elasticsearch`, port=`9200` 174 | - **OpenSearch**: host=`opensearch`, port=`9200` 175 | - **MongoDB**: host=`mongo`, port=`27017` 176 | - **RabbitMQ**: host=`rabbitmq`, port=`5672` 177 | - **Mail**: host=`mailcatch`, port=`1025` 178 | 179 | ## See Also 180 | 181 | - [mysql-mailhog-redis-cronjobs.md](mysql-mailhog-redis-cronjobs.md) - Core service details 182 | - [ufw-firewall.md](ufw-firewall.md) - Firewall configuration 183 | - [environment-configuration.md](environment-configuration.md) - Service configuration 184 | -------------------------------------------------------------------------------- /docs/advanced-docker-configuration.md: -------------------------------------------------------------------------------- 1 | # Advanced Docker Configuration 2 | 3 | This guide covers advanced Docker configuration topics including user ID mapping, build arguments, network modes, and performance optimization. 4 | 5 | ## UID/GID Mapping 6 | 7 | The environment automatically maps your user ID and group ID into containers to avoid permission issues. 8 | 9 | ### How It Works 10 | 11 | When building containers, your UID and GID are passed as build arguments: 12 | ```bash 13 | docker-compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) 14 | ``` 15 | 16 | This ensures: 17 | - Files created in containers have your ownership 18 | - You can edit files created by containers 19 | - No `sudo` needed for file operations 20 | 21 | ### Verifying UID/GID 22 | 23 | Check your IDs: 24 | ```bash 25 | id -u # Your UID 26 | id -g # Your GID 27 | ``` 28 | 29 | Check container user: 30 | ```bash 31 | dev console 32 | id 33 | ``` 34 | 35 | Should match your host user. 36 | 37 | ### Custom UID/GID 38 | 39 | To override the automatic detection, set in `.env`: 40 | ```bash 41 | UID=1000 42 | GID=1000 43 | ``` 44 | 45 | ## Docker Build Arguments 46 | 47 | Build arguments customize container builds without modifying Dockerfiles. 48 | 49 | ### Common Build Arguments 50 | 51 | The environment supports: 52 | - `UID` - User ID 53 | - `GID` - Group ID 54 | - `PHP_VERSION` - PHP version for builds 55 | - `COMPOSER_MEMORY_LIMIT` - Composer memory limit 56 | 57 | ### Setting Build Arguments 58 | 59 | In `docker-custom.yml`: 60 | ```yaml 61 | version: '2' 62 | 63 | services: 64 | php: 65 | build: 66 | context: custom/php 67 | args: 68 | PHP_VERSION: 8.3 69 | CUSTOM_ARG: value 70 | ``` 71 | 72 | ### Using Build Arguments in Dockerfile 73 | 74 | In your custom Dockerfile: 75 | ```dockerfile 76 | ARG PHP_VERSION=8.2 77 | FROM php:${PHP_VERSION}-fpm 78 | 79 | ARG CUSTOM_ARG 80 | RUN echo "Custom arg: ${CUSTOM_ARG}" 81 | ``` 82 | 83 | ## Network Modes 84 | 85 | ### Default Bridge Network 86 | 87 | Most services use the default bridge network, allowing container-to-container communication. 88 | 89 | Services can reference each other by name: 90 | ```php 91 | // From PHP container 92 | $redis = new Redis(); 93 | $redis->connect('redis', 6379); 94 | 95 | $db = new PDO('mysql:host=db;dbname=mydb', 'user', 'pass'); 96 | ``` 97 | 98 | ### Host Network Mode 99 | 100 | Some services use host network mode for direct access to host networking: 101 | - **ngrok** - For tunneling 102 | - **expose** - For sharing 103 | 104 | In `docker-custom.yml`: 105 | ```yaml 106 | services: 107 | myservice: 108 | network_mode: host 109 | ``` 110 | 111 | ### Custom Networks 112 | 113 | Create isolated networks for specific services: 114 | 115 | ```yaml 116 | version: '2' 117 | 118 | services: 119 | myapp: 120 | networks: 121 | - frontend 122 | - backend 123 | 124 | mydb: 125 | networks: 126 | - backend 127 | 128 | networks: 129 | frontend: 130 | backend: 131 | internal: true # No external access 132 | ``` 133 | 134 | ## Volume Performance 135 | 136 | ### Linux 137 | 138 | On Linux, volumes have native performance. Use bind mounts freely: 139 | ```yaml 140 | volumes: 141 | - ./workspace:/data/workspace 142 | ``` 143 | 144 | ### macOS Performance 145 | 146 | On macOS, use Docker volumes instead of bind mounts for better performance: 147 | ```bash 148 | dev volume workspace workspace 149 | ``` 150 | 151 | Or use delegated/cached modes: 152 | ```yaml 153 | volumes: 154 | - ./workspace:/data/workspace:delegated 155 | ``` 156 | 157 | ### Windows 158 | 159 | Similar to macOS, Docker volumes offer better performance than bind mounts. 160 | 161 | ## Resource Limits 162 | 163 | Limit container resources to prevent one service from consuming all resources. 164 | 165 | ### Memory Limits 166 | 167 | In `docker-custom.yml`: 168 | ```yaml 169 | services: 170 | db: 171 | mem_limit: 2g 172 | memswap_limit: 2g 173 | 174 | elasticsearch: 175 | mem_limit: 1g 176 | environment: 177 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 178 | ``` 179 | 180 | ### CPU Limits 181 | 182 | ```yaml 183 | services: 184 | php: 185 | cpus: '2.0' # Use up to 2 CPU cores 186 | cpu_shares: 1024 # Relative weight 187 | ``` 188 | 189 | ## Container Restart Policies 190 | 191 | Control what happens when containers exit: 192 | 193 | ```yaml 194 | services: 195 | critical-service: 196 | restart: always 197 | 198 | optional-service: 199 | restart: unless-stopped 200 | 201 | dev-tool: 202 | restart: "no" 203 | ``` 204 | 205 | ## Docker Compose Version 206 | 207 | The environment uses Compose file version 2 for compatibility: 208 | ```yaml 209 | version: '2' 210 | ``` 211 | 212 | Version 2 provides: 213 | - Wide compatibility 214 | - Named volumes 215 | - Network support 216 | - Stable feature set 217 | 218 | ## BuildKit 219 | 220 | Enable Docker BuildKit for faster, more efficient builds: 221 | 222 | ```bash 223 | export DOCKER_BUILDKIT=1 224 | dev rebuild 225 | ``` 226 | 227 | Or permanently in `~/.bashrc` or `~/.zshrc`: 228 | ```bash 229 | export DOCKER_BUILDKIT=1 230 | ``` 231 | 232 | Benefits: 233 | - Parallel build stages 234 | - Better layer caching 235 | - Reduced build time 236 | - Lower disk usage 237 | 238 | ## Health Checks 239 | 240 | Add health checks to services: 241 | 242 | ```yaml 243 | services: 244 | db: 245 | healthcheck: 246 | test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] 247 | interval: 10s 248 | timeout: 5s 249 | retries: 3 250 | start_period: 30s 251 | ``` 252 | 253 | Check health status: 254 | ```bash 255 | dev ps 256 | ``` 257 | 258 | ## Logging Configuration 259 | 260 | Control container log output: 261 | 262 | ```yaml 263 | services: 264 | php: 265 | logging: 266 | driver: "json-file" 267 | options: 268 | max-size: "10m" 269 | max-file: "3" 270 | ``` 271 | 272 | This prevents logs from consuming excessive disk space. 273 | 274 | ## Security Considerations 275 | 276 | ### Read-Only Filesystems 277 | 278 | Make containers more secure with read-only filesystems: 279 | ```yaml 280 | services: 281 | web: 282 | read_only: true 283 | tmpfs: 284 | - /tmp 285 | - /var/run 286 | ``` 287 | 288 | ### Drop Capabilities 289 | 290 | Remove unnecessary Linux capabilities: 291 | ```yaml 292 | services: 293 | app: 294 | cap_drop: 295 | - ALL 296 | cap_add: 297 | - NET_BIND_SERVICE 298 | ``` 299 | 300 | ### User Namespace Remapping 301 | 302 | For additional security, enable Docker user namespace remapping. See Docker documentation. 303 | 304 | ## Troubleshooting 305 | 306 | ### Permission Errors 307 | 308 | Rebuild with correct UID/GID: 309 | ```bash 310 | dev rebuild 311 | ``` 312 | 313 | Or fix permissions on host: 314 | ```bash 315 | sudo chown -R $USER:$USER workspace/ 316 | ``` 317 | 318 | ### Network Issues 319 | 320 | Inspect networks: 321 | ```bash 322 | docker network ls 323 | docker network inspect dockerdev_default 324 | ``` 325 | 326 | ### Build Cache Issues 327 | 328 | Clear build cache: 329 | ```bash 330 | docker builder prune 331 | dev rebuild --no-cache 332 | ``` 333 | 334 | ### Resource Exhaustion 335 | 336 | Check resource usage: 337 | ```bash 338 | dev top 339 | docker system df 340 | ``` 341 | 342 | Clean up: 343 | ```bash 344 | docker system prune -a 345 | docker volume prune 346 | ``` 347 | 348 | ## See Also 349 | 350 | - [custom-compose-files.md](custom-compose-files.md) - Custom configurations 351 | - [docker-volumes.md](docker-volumes.md) - Volume management 352 | - [performance-tuning.md](performance-tuning.md) - Optimization techniques 353 | -------------------------------------------------------------------------------- /docs/backup-restore.md: -------------------------------------------------------------------------------- 1 | # Backup and Restore 2 | 3 | This guide covers backup and restore strategies for databases, files, and volumes in your development environment. 4 | 5 | ## Database Backups 6 | 7 | ### Single Database 8 | 9 | Export a specific database: 10 | ```bash 11 | dev mysqldump database_name > backup.sql 12 | ``` 13 | 14 | With compression: 15 | ```bash 16 | dev mysqldump database_name | gzip > backup.sql.gz 17 | ``` 18 | 19 | ### All Databases 20 | 21 | Backup all databases: 22 | ```bash 23 | dev mysqldump --all-databases > all_databases.sql 24 | ``` 25 | 26 | ### Specific Tables 27 | 28 | Backup specific tables: 29 | ```bash 30 | dev mysqldump database_name table1 table2 > tables_backup.sql 31 | ``` 32 | 33 | ### Schema Only 34 | 35 | Backup structure without data: 36 | ```bash 37 | dev mysqldump --no-data database_name > schema.sql 38 | ``` 39 | 40 | ### Data Only 41 | 42 | Backup data without structure: 43 | ```bash 44 | dev mysqldump --no-create-info database_name > data.sql 45 | ``` 46 | 47 | ## Database Restore 48 | 49 | ### Restore Single Database 50 | 51 | ```bash 52 | dev mysql database_name < backup.sql 53 | ``` 54 | 55 | From compressed backup: 56 | ```bash 57 | gunzip < backup.sql.gz | dev mysql database_name 58 | ``` 59 | 60 | ### Create Database First 61 | 62 | If the database doesn't exist: 63 | ```bash 64 | dev mysql -e "CREATE DATABASE database_name;" 65 | dev mysql database_name < backup.sql 66 | ``` 67 | 68 | ### Restore All Databases 69 | 70 | ```bash 71 | dev myroot < all_databases.sql 72 | ``` 73 | 74 | Note: Use `myroot` for restoring all databases as it requires root privileges. 75 | 76 | ## MySQL 8 Backups 77 | 78 | For MySQL 8 databases, use direct connection: 79 | 80 | ### Backup 81 | ```bash 82 | mysqldump -h 127.0.0.1 -P 3308 -u root -p database_name > backup.sql 83 | ``` 84 | 85 | ### Restore 86 | ```bash 87 | mysql -h 127.0.0.1 -P 3308 -u root -p database_name < backup.sql 88 | ``` 89 | 90 | ## Workspace Backups 91 | 92 | ### Entire Workspace 93 | 94 | If using local workspace directory: 95 | ```bash 96 | cd ~/development 97 | tar -czf workspace-backup-$(date +%Y%m%d).tar.gz workspace/ 98 | ``` 99 | 100 | ### Specific Project 101 | 102 | Backup a single project: 103 | ```bash 104 | cd ~/development/workspace 105 | tar -czf project-backup-$(date +%Y%m%d).tar.gz customer/project/ 106 | ``` 107 | 108 | ### Exclude Dependencies 109 | 110 | Exclude vendor and node_modules: 111 | ```bash 112 | tar -czf project-backup.tar.gz \ 113 | --exclude='vendor' \ 114 | --exclude='node_modules' \ 115 | --exclude='.git' \ 116 | customer/project/ 117 | ``` 118 | 119 | ## Docker Volume Backups 120 | 121 | ### Workspace Volume 122 | 123 | If using Docker volumes instead of local directories: 124 | ```bash 125 | docker run --rm \ 126 | -v dockerdev-workspace-volume:/data \ 127 | -v $(pwd):/backup \ 128 | ubuntu tar czf /backup/workspace-backup-$(date +%Y%m%d).tar.gz /data 129 | ``` 130 | 131 | ### MySQL Volume 132 | 133 | Backup MySQL data directory: 134 | ```bash 135 | docker run --rm \ 136 | -v dockerdev-mysql-volume:/data \ 137 | -v $(pwd):/backup \ 138 | ubuntu tar czf /backup/mysql-backup-$(date +%Y%m%d).tar.gz /data 139 | ``` 140 | 141 | ## Restore from Backups 142 | 143 | ### Workspace Restore 144 | 145 | ```bash 146 | cd ~/development 147 | tar -xzf workspace-backup-20241126.tar.gz 148 | ``` 149 | 150 | ### Volume Restore 151 | 152 | ```bash 153 | docker run --rm \ 154 | -v dockerdev-workspace-volume:/data \ 155 | -v $(pwd):/backup \ 156 | ubuntu bash -c "cd /data && tar xzf /backup/workspace-backup.tar.gz --strip 1" 157 | ``` 158 | 159 | ## Automated Backups 160 | 161 | ### Daily Database Backup Script 162 | 163 | Create `~/bin/dev-backup.sh`: 164 | ```bash 165 | #!/bin/bash 166 | BACKUP_DIR=~/backups 167 | DATE=$(date +%Y%m%d) 168 | 169 | mkdir -p $BACKUP_DIR 170 | 171 | cd ~/development 172 | 173 | # Backup all databases 174 | ./bin/dev mysqldump --all-databases | gzip > $BACKUP_DIR/databases-$DATE.sql.gz 175 | 176 | # Backup workspace 177 | tar -czf $BACKUP_DIR/workspace-$DATE.tar.gz \ 178 | --exclude='workspace/*/vendor' \ 179 | --exclude='workspace/*/node_modules' \ 180 | workspace/ 181 | 182 | # Keep only last 7 days 183 | find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete 184 | find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete 185 | ``` 186 | 187 | Make it executable: 188 | ```bash 189 | chmod +x ~/bin/dev-backup.sh 190 | ``` 191 | 192 | ### Cron Job 193 | 194 | Add to crontab (`crontab -e`): 195 | ```bash 196 | # Daily backup at 2 AM 197 | 0 2 * * * ~/bin/dev-backup.sh 198 | ``` 199 | 200 | ## Magento-Specific Backups 201 | 202 | ### Magento 2 Full Backup 203 | 204 | ```bash 205 | cd workspace/customer/project/htdocs 206 | 207 | # Database 208 | dev mysqldump magento2 | gzip > ../backups/db-$(date +%Y%m%d).sql.gz 209 | 210 | # Media files 211 | tar -czf ../backups/media-$(date +%Y%m%d).tar.gz pub/media/ 212 | 213 | # Configuration 214 | cp app/etc/env.php ../backups/env.php.backup 215 | ``` 216 | 217 | ### Magento 2 Restore 218 | 219 | ```bash 220 | cd workspace/customer/project/htdocs 221 | 222 | # Database 223 | gunzip < ../backups/db-20241126.sql.gz | dev mysql magento2 224 | 225 | # Media 226 | tar -xzf ../backups/media-20241126.tar.gz 227 | 228 | # Configuration 229 | cp ../backups/env.php.backup app/etc/env.php 230 | 231 | # Clear cache 232 | dev console bin/magento cache:flush 233 | ``` 234 | 235 | ## Best Practices 236 | 237 | ### Before Updates 238 | 239 | Always backup before: 240 | - Upgrading PHP versions 241 | - Updating major dependencies 242 | - Significant code changes 243 | - Docker environment updates 244 | 245 | ### What to Backup 246 | 247 | **Essential:** 248 | - Databases 249 | - Custom code 250 | - Configuration files 251 | - User-uploaded content 252 | 253 | **Optional:** 254 | - Vendor dependencies (can be reinstalled) 255 | - Generated files (can be regenerated) 256 | - Cache (not needed) 257 | 258 | ### Storage 259 | 260 | Store backups: 261 | - On a different disk/partition 262 | - In cloud storage (S3, Dropbox, etc.) 263 | - On external drives 264 | - Multiple locations for critical data 265 | 266 | ### Testing Restores 267 | 268 | Periodically test your backups: 269 | ```bash 270 | # Test database restore 271 | dev mysql test_db < backup.sql 272 | dev mysql -e "SHOW TABLES FROM test_db;" 273 | dev mysql -e "DROP DATABASE test_db;" 274 | ``` 275 | 276 | ## Quick Backup Commands 277 | 278 | ### Before Risky Operation 279 | 280 | ```bash 281 | # Quick database backup 282 | dev mysqldump mydb > quick-backup-$(date +%H%M).sql 283 | 284 | # Quick file snapshot 285 | tar -czf quick-backup-$(date +%H%M).tar.gz workspace/customer/project/ 286 | ``` 287 | 288 | ### After Successful Changes 289 | 290 | Delete quick backups: 291 | ```bash 292 | rm quick-backup-*.sql 293 | rm quick-backup-*.tar.gz 294 | ``` 295 | 296 | ## Troubleshooting 297 | 298 | ### mysqldump: Command not found 299 | 300 | Use the full dev command: 301 | ```bash 302 | ./bin/dev mysqldump database > backup.sql 303 | ``` 304 | 305 | ### Permission Denied 306 | 307 | Ensure you have write permissions: 308 | ```bash 309 | ls -la 310 | chmod +w . 311 | ``` 312 | 313 | ### Out of Disk Space 314 | 315 | Check available space: 316 | ```bash 317 | df -h 318 | ``` 319 | 320 | Clean up old backups or compress existing ones. 321 | 322 | ### Corrupt Backup 323 | 324 | Verify backup integrity: 325 | ```bash 326 | gunzip -t backup.sql.gz 327 | tar -tzf backup.tar.gz 328 | ``` 329 | 330 | ## See Also 331 | 332 | - [mysql-mailhog-redis-cronjobs.md](mysql-mailhog-redis-cronjobs.md) - Database basics 333 | - [mysql8.md](mysql8.md) - MySQL 8 specifics 334 | - [docker-volumes.md](docker-volumes.md) - Volume management 335 | -------------------------------------------------------------------------------- /docs/performance-tuning.md: -------------------------------------------------------------------------------- 1 | # Performance Tuning 2 | 3 | This guide covers performance optimization techniques for your Docker development environment. 4 | 5 | ## Composer Performance 6 | 7 | ### Memory Limit 8 | 9 | Composer can consume significant memory. Increase the limit: 10 | 11 | In `.env`: 12 | ```bash 13 | COMPOSER_MEMORY_LIMIT=-1 14 | ``` 15 | 16 | This is the default in the environment (unlimited memory). 17 | 18 | ### Composer Version 19 | 20 | Use Composer 2 for better performance: 21 | ```bash 22 | dev composer2 install 23 | ``` 24 | 25 | Composer 2 is significantly faster than Composer 1. 26 | 27 | ### Platform Check 28 | 29 | Disable platform requirements check for faster installs: 30 | ```bash 31 | dev composer2 install --no-plugins --no-scripts 32 | ``` 33 | 34 | Or configure globally: 35 | ```bash 36 | dev composer2 config platform-check false 37 | ``` 38 | 39 | ### Parallel Downloads 40 | 41 | Composer 2 automatically downloads packages in parallel. For Composer 1: 42 | ```bash 43 | dev composer1 global require hirak/prestissimo 44 | ``` 45 | 46 | ## PHP Performance 47 | 48 | ### OPcache 49 | 50 | OPcache is enabled by default in PHP containers. Verify: 51 | ```bash 52 | dev php -i | grep opcache 53 | ``` 54 | 55 | ### Memory Limit 56 | 57 | Increase PHP memory limit for resource-intensive scripts: 58 | ```bash 59 | dev php -d memory_limit=512M script.php 60 | ``` 61 | 62 | Or set globally in `docker-custom.yml`: 63 | ```yaml 64 | services: 65 | php82: 66 | environment: 67 | PHP_MEMORY_LIMIT: 512M 68 | ``` 69 | 70 | ### Execution Time 71 | 72 | For long-running scripts: 73 | ```bash 74 | dev php -d max_execution_time=300 script.php 75 | ``` 76 | 77 | ## MySQL Performance 78 | 79 | ### Configuration 80 | 81 | Optimize MySQL in `conf/mysql/my.cnf`: 82 | ```ini 83 | [mysqld] 84 | # Memory 85 | innodb_buffer_pool_size = 2G 86 | key_buffer_size = 256M 87 | max_allowed_packet = 64M 88 | 89 | # Connections 90 | max_connections = 200 91 | 92 | # Query cache (MySQL 5.7 only) 93 | query_cache_type = 1 94 | query_cache_size = 64M 95 | 96 | # InnoDB 97 | innodb_flush_log_at_trx_commit = 2 98 | innodb_log_file_size = 256M 99 | 100 | # Temporary tables 101 | tmp_table_size = 64M 102 | max_heap_table_size = 64M 103 | ``` 104 | 105 | After changes: 106 | ```bash 107 | dev restart db 108 | ``` 109 | 110 | ### Slow Query Log 111 | 112 | Enable slow query logging: 113 | ```ini 114 | [mysqld] 115 | slow_query_log = 1 116 | slow_query_log_file = /var/log/mysql/slow.log 117 | long_query_time = 2 118 | ``` 119 | 120 | View slow queries: 121 | ```bash 122 | dev exec db tail -f /var/log/mysql/slow.log 123 | ``` 124 | 125 | ### Index Optimization 126 | 127 | Find tables without indexes: 128 | ```sql 129 | SELECT DISTINCT 130 | tables.table_schema, 131 | tables.table_name 132 | FROM information_schema.tables 133 | LEFT JOIN information_schema.statistics 134 | ON tables.table_schema = statistics.table_schema 135 | AND tables.table_name = statistics.table_name 136 | WHERE statistics.index_name IS NULL 137 | AND tables.table_schema NOT IN ('mysql', 'information_schema', 'performance_schema') 138 | AND tables.table_type = 'BASE TABLE'; 139 | ``` 140 | 141 | ## Docker Performance 142 | 143 | ### Volume Performance 144 | 145 | **Linux:** Native performance, no optimization needed. 146 | 147 | **macOS/Windows:** Use Docker volumes instead of bind mounts: 148 | ```bash 149 | dev volume workspace workspace 150 | ``` 151 | 152 | This significantly improves I/O performance. 153 | 154 | ### Resource Allocation 155 | 156 | Allocate more resources to Docker: 157 | 158 | **Docker Desktop Settings:** 159 | - CPUs: 4+ cores recommended 160 | - Memory: 8+ GB recommended 161 | - Swap: 2+ GB 162 | - Disk image size: 100+ GB 163 | 164 | ### BuildKit 165 | 166 | Enable Docker BuildKit for faster builds: 167 | ```bash 168 | export DOCKER_BUILDKIT=1 169 | ``` 170 | 171 | Add to `~/.bashrc` or `~/.zshrc` for persistence. 172 | 173 | ### Layer Caching 174 | 175 | Optimize Dockerfile layer caching by ordering commands from least to most frequently changed: 176 | 177 | ```dockerfile 178 | # Rarely changes - good for caching 179 | FROM php:8.2-fpm 180 | 181 | # System packages - changes occasionally 182 | RUN apt-get update && apt-get install -y \ 183 | package1 package2 184 | 185 | # PHP extensions - changes occasionally 186 | RUN docker-php-ext-install pdo_mysql 187 | 188 | # Application dependencies - changes more frequently 189 | COPY composer.json composer.lock ./ 190 | RUN composer install --no-dev 191 | 192 | # Application code - changes most frequently 193 | COPY . . 194 | ``` 195 | 196 | ## Elasticsearch/OpenSearch Performance 197 | 198 | ### Memory Settings 199 | 200 | Set JVM heap size (should be 50% of available RAM, max 32GB): 201 | ```yaml 202 | services: 203 | elasticsearch: 204 | environment: 205 | - "ES_JAVA_OPTS=-Xms1g -Xmx1g" 206 | ``` 207 | 208 | ### Disable Swapping 209 | 210 | In `docker-custom.yml`: 211 | ```yaml 212 | services: 213 | elasticsearch: 214 | environment: 215 | - bootstrap.memory_lock=true 216 | ulimits: 217 | memlock: 218 | soft: -1 219 | hard: -1 220 | ``` 221 | 222 | ## Varnish Performance 223 | 224 | ### Cache Size 225 | 226 | Increase Varnish cache size in `.env`: 227 | ```bash 228 | CACHE_SIZE=1G 229 | ``` 230 | 231 | ### Monitoring 232 | 233 | Check Varnish hit rate: 234 | ```bash 235 | dev exec varnish varnishadm stats 236 | ``` 237 | 238 | Look for `cache_hit` vs `cache_miss` ratio. 239 | 240 | ## Redis Performance 241 | 242 | ### Persistent Storage 243 | 244 | For development, disable persistence for better performance: 245 | ```yaml 246 | services: 247 | redis: 248 | command: redis-server --appendonly no --save "" 249 | ``` 250 | 251 | ### Memory Limit 252 | 253 | Set max memory: 254 | ```yaml 255 | services: 256 | redis: 257 | command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru 258 | ``` 259 | 260 | ## Application-Specific 261 | 262 | ### Magento 2 263 | 264 | **Production Mode:** 265 | ```bash 266 | dev console bin/magento deploy:mode:set production 267 | dev console bin/magento cache:flush 268 | ``` 269 | 270 | **Flat Catalog:** 271 | Enable flat tables for categories and products: 272 | - **Stores** > **Configuration** > **Catalog** > **Catalog** 273 | - Enable "Use Flat Catalog Category" 274 | - Enable "Use Flat Catalog Product" 275 | 276 | **Indexers:** 277 | Switch to "Update on Schedule": 278 | ```bash 279 | dev console bin/magento indexer:set-mode schedule catalog_category_product 280 | dev console bin/magento indexer:set-mode schedule catalog_product_category 281 | # ... etc for all indexers 282 | ``` 283 | 284 | **Static Content:** 285 | Deploy static content: 286 | ```bash 287 | dev console bin/magento setup:static-content:deploy -f 288 | ``` 289 | 290 | ### Laravel 291 | 292 | **Config Caching:** 293 | ```bash 294 | dev console php artisan config:cache 295 | dev console php artisan route:cache 296 | dev console php artisan view:cache 297 | ``` 298 | 299 | **OPcache:** 300 | Already enabled in PHP containers. 301 | 302 | ## Monitoring Performance 303 | 304 | ### Container Resources 305 | 306 | Monitor resource usage: 307 | ```bash 308 | dev top 309 | ``` 310 | 311 | ### Identify Bottlenecks 312 | 313 | Check which container is consuming resources: 314 | ```bash 315 | docker stats 316 | ``` 317 | 318 | ### Application Profiling 319 | 320 | Use Blackfire for application profiling: 321 | ```bash 322 | dev blackfire curl http://your-site.localhost 323 | ``` 324 | 325 | See [configure-blackfire.md](configure-blackfire.md). 326 | 327 | ## Common Issues 328 | 329 | ### Slow File Operations 330 | 331 | **Problem:** File operations (composer, npm) are slow. 332 | **Solution:** Use Docker volumes instead of bind mounts (macOS/Windows). 333 | 334 | ### High CPU Usage 335 | 336 | **Problem:** Constant high CPU. 337 | **Solution:** Check logs for errors causing retry loops: 338 | ```bash 339 | dev logs 340 | ``` 341 | 342 | ### Out of Memory 343 | 344 | **Problem:** Containers crashing or OOM errors. 345 | **Solution:** 346 | - Increase Docker Desktop memory allocation 347 | - Reduce container memory limits 348 | - Optimize application memory usage 349 | 350 | ### Database Queries Slow 351 | 352 | **Problem:** Slow database queries. 353 | **Solution:** 354 | - Enable slow query log 355 | - Add indexes 356 | - Optimize queries 357 | - Increase `innodb_buffer_pool_size` 358 | 359 | ## Benchmarking 360 | 361 | ### Database Performance 362 | 363 | ```bash 364 | dev myroot -e "SHOW ENGINE INNODB STATUS\G" 365 | ``` 366 | 367 | ### Web Performance 368 | 369 | Use Apache Bench: 370 | ```bash 371 | dev exec php ab -n 1000 -c 10 http://your-site.localhost/ 372 | ``` 373 | 374 | ### PHP Performance 375 | 376 | Compare script execution time: 377 | ```bash 378 | time dev php script.php 379 | ``` 380 | 381 | ## See Also 382 | 383 | - [monitoring-tools.md](monitoring-tools.md) - Performance monitoring 384 | - [advanced-docker-configuration.md](advanced-docker-configuration.md) - Resource limits 385 | - [configure-blackfire.md](configure-blackfire.md) - Application profiling 386 | -------------------------------------------------------------------------------- /bin/dev: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | init() { 4 | 5 | DEV_SELF=$(basename $0); 6 | 7 | DEV_PATH=$(realpath $(dirname $0)); 8 | DEV_WORKPATH=$(dirname ${DEV_PATH}); 9 | DEV_PROJECT=$(basename ${DEV_WORKPATH}); 10 | DEV_USERDIR=${PWD}; 11 | 12 | DEV_COMMANDPATH=${DEV_PATH}/dev_command; 13 | 14 | DEV_SUDO=''; 15 | if [ -z "`groups | grep docker`" ]; then 16 | DEV_SUDO='sudo -E'; 17 | fi 18 | 19 | DEV_WORKSPACE_PATH="${DEV_WORKPATH}/workspace"; 20 | local DOCKERDEV_WORKSPACE=`${DEV_SUDO} docker volume inspect -f '{{ .Options.device }}' dockerdev-workspace-volume 2>/dev/null`; 21 | if [ "${DOCKERDEV_WORKSPACE}" != "" ]; then 22 | DEV_WORKSPACE_PATH=${DOCKERDEV_WORKSPACE}; 23 | fi 24 | 25 | DEV_WORKSPACE="`echo ${DEV_WORKSPACE_PATH} | sed -e 's/\\//\\\\\//g'`"; 26 | DEV_PROJECTPATH=`echo ${DEV_USERDIR} | sed -e "s/${DEV_WORKSPACE}\///"`; 27 | 28 | DEV_PHP='php82'; 29 | 30 | DEV_INTERACTIVE=0; 31 | if [ -t "0" ] && [ -t "1" ]; then 32 | DEV_INTERACTIVE=1; 33 | fi 34 | 35 | dc env conf/mysql; # fallback 36 | dc env .env; 37 | 38 | DEV_YML=''; 39 | dc yml 'docker-compose.yml'; 40 | dc yml_if 'build/dist/docker-compose-blackfire.yml' 'conf/blackfire'; 41 | dc yml_if 'build/dist/docker-compose-varnish.yml' 'conf/varnish.vcl'; 42 | dc yml_if 'build/dist/docker-compose-elasticsearch.yml' 'conf/elasticsearch'; 43 | dc yml_if 'build/dist/docker-compose-elasticsearch7.yml' 'conf/elasticsearch7'; 44 | dc yml_if 'build/dist/docker-compose-elasticsearchhq.yml' 'conf/elasticsearchhq'; 45 | dc yml_if 'build/dist/docker-compose-opensearch.yml' 'conf/opensearch'; 46 | dc yml_if 'build/dist/docker-compose-opensearch-dashboard.yml' 'conf/opensearch-dashboard'; 47 | dc yml_if 'build/dist/docker-compose-db8.yml' 'conf/mysql8'; 48 | dc yml_if 'build/dist/docker-compose-elasticvue.yml' 'conf/elasticvue'; 49 | dc yml_if 'build/dist/docker-compose-elasticvue-cors.yml' 'conf/elasticvue' 'conf/elasticsearch'; 50 | dc yml_if 'build/dist/docker-compose-elasticvue-cors7.yml' 'conf/elasticvue' 'conf/elasticsearch7'; 51 | dc yml_if 'build/dist/docker-compose-rabbitmq.yml' 'conf/rabbitmq'; 52 | dc yml_if 'build/dist/docker-compose-mongo.yml' 'conf/mongo'; 53 | dc yml_if 'build/dist/docker-compose-ftp.yml' 'conf/ftp'; 54 | dc yml_if 'docker-custom.yml' 'docker-custom.yml'; 55 | dc yml_ssh; 56 | 57 | dc mode 'run --rm'; 58 | 59 | DEV_DOCKERVARS=''; 60 | DEV_DOCKEROPTS=''; 61 | DEV_COMMAND=''; 62 | DEV_HOSTNAME=''; 63 | DEV_TRAPON=''; 64 | 65 | if [ "${DEV_PROJECTPATH}" == "${DEV_USERDIR}" ]; then 66 | # Not in WORKSPACE 67 | DEV_PROJECTPATH=''; 68 | else 69 | DEV_HOSTNAME=`echo ${DEV_PROJECTPATH} | sed -e 's/\//\./g' -e 's/^\([^\.]*\.[^\.]*\)\.\{0,1\}.*$/\\1'${DOMAINSUFFIX}'/'`; 70 | if [ ".." != "`echo ${DEV_HOSTNAME} | sed -e 's/[^\.]//g'`" ]; then 71 | DEV_HOSTNAME=''; 72 | fi 73 | fi 74 | 75 | # Check which php version to use 76 | dc php; 77 | } 78 | 79 | dc() { 80 | 81 | vars() { 82 | DEV_DOCKERVARS="${DEV_DOCKERVARS} $@"; 83 | } 84 | 85 | export_vars() { 86 | if [ -z "${DEV_DOCKERVARS}" ]; then 87 | return; 88 | fi 89 | 90 | export ${DEV_DOCKERVARS}; 91 | } 92 | 93 | ignore_orphans() { 94 | vars "COMPOSE_IGNORE_ORPHANS=True"; 95 | } 96 | 97 | show() { 98 | echo `getsudo`docker compose ${DEV_YML} ${DEV_MODE} \ 99 | ${DEV_DOCKEROPTS} \ 100 | ${DEV_SERVICE} \ 101 | "${DEV_CMD}"; 102 | } 103 | 104 | getsudo() { 105 | # Check if user is in docker group 106 | [ -n "${DEV_SUDO}" ] && echo -n ${DEV_SUDO}' '; 107 | } 108 | 109 | run() { 110 | local _child=''; 111 | cmd="`show`"; 112 | 113 | _trap() { 114 | kill -s INT ${_child} 2>/dev/null; 115 | } 116 | 117 | export_vars; 118 | 119 | if [ -z "${DEV_TRAPON}" ]; then 120 | ${cmd} "$@"; 121 | return $?; 122 | fi 123 | 124 | trap '_trap' SIGINT; 125 | ${cmd} "$@" & 126 | _child=$!; 127 | wait ${_child}; 128 | return $?; 129 | } 130 | 131 | trap_on() { 132 | DEV_TRAPON=1; 133 | } 134 | trap_off() { 135 | DEV_TRAPON=""; 136 | } 137 | 138 | opt() { 139 | DEV_DOCKEROPTS=${DEV_DOCKEROPTS}' '"$@"; 140 | } 141 | 142 | interactive() { 143 | [ ${DEV_INTERACTIVE} -eq 0 ] && opt '-T'; 144 | } 145 | 146 | nodeps() { 147 | ignore_orphans; 148 | opt '--no-deps'; 149 | } 150 | 151 | user() { 152 | opt "-u `id -u`:`id -g`"; 153 | } 154 | 155 | projectpath() { 156 | [ -n "${DEV_PROJECTPATH}" ] \ 157 | && opt "-w /data/${DEV_PROJECTPATH}" 158 | } 159 | 160 | service() { 161 | if [ "$1" == "php" ]; then 162 | DEV_SERVICE=${DEV_PHP}; 163 | else 164 | DEV_SERVICE="$@"; 165 | fi 166 | } 167 | 168 | yml_if() { 169 | local yml=$1; 170 | shift; 171 | 172 | while [ -n "$1" ]; do 173 | if [ ! -e ${DEV_WORKPATH}/$1 ]; then 174 | return 1; 175 | fi 176 | shift; 177 | done 178 | 179 | yml ${yml}; 180 | return 0; 181 | } 182 | 183 | yml_all() { 184 | yml_if 'build/dist/docker-compose-blackfireclient.yml' 'conf/blackfire'; 185 | yml 'build/dist/docker-compose-dbclient.yml'; 186 | yml 'build/dist/docker-compose-mytop.yml'; 187 | yml 'build/dist/docker-compose-ngrok.yml'; 188 | yml 'build/dist/docker-compose-ctop.yml'; 189 | yml 'build/dist/docker-compose-node.yml'; 190 | yml 'build/dist/docker-compose-expose.yml'; 191 | } 192 | 193 | yml() { 194 | if [ -n "`echo $DEV_YML | grep $1`" ]; then 195 | return; 196 | fi 197 | DEV_YML=${DEV_YML}' --file '${DEV_WORKPATH}'/'$1; 198 | } 199 | 200 | yml_local() { 201 | if [ -r ${DEV_USERDIR}/docker-compose-dev.yml ]; then 202 | export DEV_USERDIR="${DEV_USERDIR}"; 203 | DEV_YML=${DEV_YML}' --file '${DEV_USERDIR}/docker-compose-dev.yml; 204 | fi 205 | } 206 | 207 | yml_ssh() { 208 | if [ -n "${SSH_AUTH_SOCK}" ]; then 209 | yml build/dist/docker-compose-ssh.yml; 210 | fi 211 | } 212 | 213 | mode() { 214 | DEV_MODE="$@"; 215 | } 216 | 217 | cmd() { 218 | DEV_CMD="$@"; 219 | } 220 | 221 | php_versions() { 222 | grep -h '^\s*php[0-9][0-9]:' ${DEV_WORKPATH}/docker-*.yml | sed -e 's/ *//;s/:.*//' | sort -ur; 223 | } 224 | 225 | php() { 226 | local PHP=$(stopfile "`php_versions`") 227 | 228 | if [ -z "${PHP}" ]; then 229 | return 1; 230 | else 231 | DEV_PHP=${PHP}; 232 | fi 233 | 234 | return 0; 235 | } 236 | 237 | stopfile() { 238 | local available="$1" project=${DEV_WORKSPACE_PATH}/${DEV_PROJECTPATH}; 239 | 240 | # check if stopfile can be found in this directory 241 | check() { 242 | local a; 243 | for a in ${available}; do 244 | if [ -e $1/.$a ]; then 245 | echo $a; 246 | return 0; 247 | fi 248 | done 249 | 250 | return 1; 251 | } 252 | 253 | if [ -n "${DEV_PROJECTPATH}" ]; then 254 | while [ "${project}" != "${DEV_WORKSPACE_PATH}" ]; do 255 | check ${project} && return 0; 256 | project=$(dirname ${project}); 257 | done 258 | fi 259 | 260 | check ${DEV_WORKSPACE_PATH} && return 0 || return 1; 261 | } 262 | 263 | env() { 264 | local envfile=${DEV_WORKPATH}/$1 a='' c=''; 265 | if [ ! -r ${envfile} ]; then 266 | return 1; 267 | fi 268 | 269 | for a in `cat ${envfile}`; do 270 | if [ "${a:0:1}" == "#" ]; then 271 | continue; 272 | fi 273 | c='export '${a}; 274 | ${c}; 275 | done 276 | } 277 | 278 | "$@"; 279 | return $?; 280 | } 281 | 282 | exec_command() { 283 | # Check if command exists 284 | DEV_COMMAND=$1; 285 | shift; 286 | 287 | if [ -z "${DEV_COMMAND}" ] || [ ! -r "${DEV_COMMANDPATH}/${DEV_COMMAND}" ]; then 288 | return 99; 289 | fi 290 | 291 | # Change to command directory 292 | # This is so all docker-compose commands work out of the box 293 | cd ${DEV_COMMANDPATH}; 294 | 295 | # execute command 296 | . ./${DEV_COMMAND} "$@"; 297 | return $?; 298 | } 299 | 300 | exec_custom() { 301 | # Check if a custom command exists and is executable 302 | DEV_COMMAND=$1; 303 | shift; 304 | 305 | if [ -z "${DEV_COMMAND}" ] || [ ! -x "${DEV_WORKSPACE_PATH}/bin/${DEV_COMMAND}" ]; then 306 | return 1; 307 | fi 308 | 309 | exec_command custom ${DEV_COMMAND} "$@"; 310 | return $?; 311 | } 312 | 313 | usage() { 314 | exec_command usage; 315 | return $?; 316 | } 317 | 318 | main() { 319 | [ $# -lt 1 ] && (usage; return $?); 320 | 321 | exec_command "$@" && return 0; 322 | [ $? -eq 99 ] && exec_custom "$@"; 323 | return $?; 324 | } 325 | 326 | init; 327 | 328 | main "$@"; 329 | exit $?; 330 | 331 | --------------------------------------------------------------------------------