diff --git a/.github/workflows/pipes.yaml b/.github/workflows/pipes.yaml new file mode 100644 index 0000000..5b3a00b --- /dev/null +++ b/.github/workflows/pipes.yaml @@ -0,0 +1,44 @@ +name: Pipes + +on: + pull_request: + branches: + - master + paths: + - 'bin/**' + - 'build/**' + - 'scripts/**' + - 'src/**' + types: + - labeled + - unlabeled + - opened + - synchronize + push: + branches: + - master + paths: + - 'bin/**' + - 'build/**' + - 'scripts/**' + - 'src/**' + workflow_dispatch: + +jobs: + build_and_verify: + name: Build and Verify + if: | + github.event_name == 'push' + || github.event_name == 'workflow_dispatch' + || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'ci')) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Verify builds are correct + run: | + make clean + make generate + ./scripts/git-has-changes.sh + - name: Build and verify CLI docker images + run: | + ./scripts/build-and-verify-cli-images.sh mobtitude/php-xdebug diff --git a/.gitignore b/.gitignore index a09c56d..6977e17 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -/.idea +.* + +!.gitignore + +!.github/ diff --git a/README.md b/README.md index defbc68..86bc2b0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Pipes](https://github.com/mobtitude/docker-php-xdebug/actions/workflows/pipes.yaml/badge.svg)](https://github.com/mobtitude/docker-php-xdebug/actions/workflows/pipes.yaml) + About this repo =============== This repository contains Dockerfiles to build PHP images with `xdebug` installed and configured to run with modern IDEs like phpStorm. @@ -20,6 +22,20 @@ The only difference is that, instead of downloading official Docker PHP image, y Supported tags: +* mobtitude/php-xdebug:8.1-apache +* mobtitude/php-xdebug:8.1-cli +* mobtitude/php-xdebug:8.1-fpm +* mobtitude/php-xdebug:8.2-apache +* mobtitude/php-xdebug:8.2-cli +* mobtitude/php-xdebug:8.2-fpm +* mobtitude/php-xdebug:8.3-apache +* mobtitude/php-xdebug:8.3-cli +* mobtitude/php-xdebug:8.3-fpm +* mobtitude/php-xdebug:8.4-apache +* mobtitude/php-xdebug:8.4-cli +* mobtitude/php-xdebug:8.4-fpm + +Deprecated tags (they are available in docker hub, but no further updates will be provided): * mobtitude/php-xdebug:5.6-apache * mobtitude/php-xdebug:5.6-cli * mobtitude/php-xdebug:5.6-fpm @@ -32,15 +48,7 @@ Supported tags: * mobtitude/php-xdebug:7.2-apache * mobtitude/php-xdebug:7.2-cli * mobtitude/php-xdebug:7.2-fpm -* mobtitude/php-xdebug:8.1-apache -* mobtitude/php-xdebug:8.1-cli -* mobtitude/php-xdebug:8.1-fpm -* mobtitude/php-xdebug:8.2-apache -* mobtitude/php-xdebug:8.2-cli -* mobtitude/php-xdebug:8.2-fpm -* mobtitude/php-xdebug:8.3-apache -* mobtitude/php-xdebug:8.3-cli -* mobtitude/php-xdebug:8.3-fpm + Build from source ------------------- diff --git a/bin/build-all.sh b/bin/build-all.sh index c2479a2..a91e03d 100755 --- a/bin/build-all.sh +++ b/bin/build-all.sh @@ -34,7 +34,7 @@ for i in ./build/*/; do echo "${text_bold}* Building ${image} ${text_normal}" # Builds image and check for return code - if docker build --pull -t "${image}" "./build/${version}"; then + if docker buildx build --push --platform linux/arm64,linux/amd64 -t "${image}" "./build/${version}"; then build_done+=( "${image}" ) else echo "${text_bold}${text_red}* ERROR when building ${image} ${text_normal}" @@ -60,4 +60,5 @@ if [ "${#build_failed[@]}" -gt 0 ]; then for img in "${build_failed[@]}"; do echo "${text_red}* ${img}${text_normal}" done + exit 1 fi diff --git a/bin/generate.sh b/bin/generate.sh index da0cc18..a8fa2f0 100755 --- a/bin/generate.sh +++ b/bin/generate.sh @@ -5,7 +5,7 @@ # # PHP Versions that will be generated -php_versions=( "8.3" "8.2" "8.1" ) +php_versions=( "8.4" "8.3" "8.2" "8.1" ) # PHP variants that will be generated for each PHP version # final source image will be generated as follow: php:7.2-cli, php:7-2-apache and php:7.2-fpm @@ -15,6 +15,7 @@ php_docker_suffix=( "cli" "apache" "fpm" ) # PHP_VERSION => XDEBUG_VERSION declare -A xdebug_versions xdebug_versions=( + ["8.4"]="xdebug-3.4.5" ["8.3"]="xdebug-3.3.1" ["8.2"]="xdebug-3.3.1" ["8.1"]="xdebug-3.1.3" diff --git a/build/8.1-apache/Dockerfile b/build/8.1-apache/Dockerfile index 46a257d..5911e10 100644 --- a/build/8.1-apache/Dockerfile +++ b/build/8.1-apache/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.1-apache -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.1-apache/xdebug.ini b/build/8.1-apache/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.1-apache/xdebug.ini +++ b/build/8.1-apache/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.1-cli/Dockerfile b/build/8.1-cli/Dockerfile index 4952ef7..97a60c2 100644 --- a/build/8.1-cli/Dockerfile +++ b/build/8.1-cli/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.1-cli -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.1-cli/xdebug.ini b/build/8.1-cli/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.1-cli/xdebug.ini +++ b/build/8.1-cli/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.1-fpm/Dockerfile b/build/8.1-fpm/Dockerfile index 0e1ffc4..c5dd3a3 100644 --- a/build/8.1-fpm/Dockerfile +++ b/build/8.1-fpm/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.1-fpm -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.1-fpm/xdebug.ini b/build/8.1-fpm/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.1-fpm/xdebug.ini +++ b/build/8.1-fpm/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.2-apache/Dockerfile b/build/8.2-apache/Dockerfile index 2ce61c7..835368d 100644 --- a/build/8.2-apache/Dockerfile +++ b/build/8.2-apache/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.2-apache -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.2-apache/xdebug.ini b/build/8.2-apache/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.2-apache/xdebug.ini +++ b/build/8.2-apache/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.2-cli/Dockerfile b/build/8.2-cli/Dockerfile index 1d3a7e4..9e2d770 100644 --- a/build/8.2-cli/Dockerfile +++ b/build/8.2-cli/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.2-cli -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.2-cli/xdebug.ini b/build/8.2-cli/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.2-cli/xdebug.ini +++ b/build/8.2-cli/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.2-fpm/Dockerfile b/build/8.2-fpm/Dockerfile index ebd39b5..1dd6349 100644 --- a/build/8.2-fpm/Dockerfile +++ b/build/8.2-fpm/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.2-fpm -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.2-fpm/xdebug.ini b/build/8.2-fpm/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.2-fpm/xdebug.ini +++ b/build/8.2-fpm/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.3-apache/Dockerfile b/build/8.3-apache/Dockerfile index 43b5f9c..2e8f47a 100644 --- a/build/8.3-apache/Dockerfile +++ b/build/8.3-apache/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.3-apache -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.3-apache/xdebug.ini b/build/8.3-apache/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.3-apache/xdebug.ini +++ b/build/8.3-apache/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.3-cli/Dockerfile b/build/8.3-cli/Dockerfile index d1ab114..1239a5d 100644 --- a/build/8.3-cli/Dockerfile +++ b/build/8.3-cli/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.3-cli -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.3-cli/xdebug.ini b/build/8.3-cli/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.3-cli/xdebug.ini +++ b/build/8.3-cli/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.3-fpm/Dockerfile b/build/8.3-fpm/Dockerfile index 92a6f45..ef1ec0f 100644 --- a/build/8.3-fpm/Dockerfile +++ b/build/8.3-fpm/Dockerfile @@ -1,5 +1,5 @@ FROM php:8.3-fpm -MAINTAINER Przemek Szalko +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/build/8.3-fpm/xdebug.ini b/build/8.3-fpm/xdebug.ini index a6c56ff..b04f78c 100644 --- a/build/8.3-fpm/xdebug.ini +++ b/build/8.3-fpm/xdebug.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.4-apache/Dockerfile b/build/8.4-apache/Dockerfile new file mode 100644 index 0000000..a0b7267 --- /dev/null +++ b/build/8.4-apache/Dockerfile @@ -0,0 +1,19 @@ +FROM php:8.4-apache +LABEL org.opencontainers.image.authors="Przemek Szalko " + +# php intl extension +RUN apt-get update \ + && apt-get install -y libicu-dev \ + && docker-php-ext-install intl \ + && docker-php-ext-install pdo_mysql \ + && docker-php-source delete \ + && apt-get remove -y libicu-dev \ + && apt-get autoremove -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN pecl channel-update pecl.php.net \ + && pecl install xdebug-3.4.5 \ + && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini diff --git a/build/8.4-apache/xdebug.ini b/build/8.4-apache/xdebug.ini new file mode 100644 index 0000000..b04f78c --- /dev/null +++ b/build/8.4-apache/xdebug.ini @@ -0,0 +1,14 @@ +[xdebug] +zend_extension=xdebug.so + +xdebug.cli_color=0 +xdebug.show_local_vars=1 +xdebug.start_with_request=trigger + +xdebug.output_dir="/tmp" +xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" + +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.4-cli/Dockerfile b/build/8.4-cli/Dockerfile new file mode 100644 index 0000000..921b18b --- /dev/null +++ b/build/8.4-cli/Dockerfile @@ -0,0 +1,19 @@ +FROM php:8.4-cli +LABEL org.opencontainers.image.authors="Przemek Szalko " + +# php intl extension +RUN apt-get update \ + && apt-get install -y libicu-dev \ + && docker-php-ext-install intl \ + && docker-php-ext-install pdo_mysql \ + && docker-php-source delete \ + && apt-get remove -y libicu-dev \ + && apt-get autoremove -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN pecl channel-update pecl.php.net \ + && pecl install xdebug-3.4.5 \ + && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini diff --git a/build/8.4-cli/xdebug.ini b/build/8.4-cli/xdebug.ini new file mode 100644 index 0000000..b04f78c --- /dev/null +++ b/build/8.4-cli/xdebug.ini @@ -0,0 +1,14 @@ +[xdebug] +zend_extension=xdebug.so + +xdebug.cli_color=0 +xdebug.show_local_vars=1 +xdebug.start_with_request=trigger + +xdebug.output_dir="/tmp" +xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" + +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/build/8.4-fpm/Dockerfile b/build/8.4-fpm/Dockerfile new file mode 100644 index 0000000..04b0cd8 --- /dev/null +++ b/build/8.4-fpm/Dockerfile @@ -0,0 +1,19 @@ +FROM php:8.4-fpm +LABEL org.opencontainers.image.authors="Przemek Szalko " + +# php intl extension +RUN apt-get update \ + && apt-get install -y libicu-dev \ + && docker-php-ext-install intl \ + && docker-php-ext-install pdo_mysql \ + && docker-php-source delete \ + && apt-get remove -y libicu-dev \ + && apt-get autoremove -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN pecl channel-update pecl.php.net \ + && pecl install xdebug-3.4.5 \ + && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini diff --git a/build/8.4-fpm/xdebug.ini b/build/8.4-fpm/xdebug.ini new file mode 100644 index 0000000..b04f78c --- /dev/null +++ b/build/8.4-fpm/xdebug.ini @@ -0,0 +1,14 @@ +[xdebug] +zend_extension=xdebug.so + +xdebug.cli_color=0 +xdebug.show_local_vars=1 +xdebug.start_with_request=trigger + +xdebug.output_dir="/tmp" +xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" + +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 + diff --git a/scripts/build-and-verify-cli-images.sh b/scripts/build-and-verify-cli-images.sh new file mode 100755 index 0000000..5e4561d --- /dev/null +++ b/scripts/build-and-verify-cli-images.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +# +# Script builds all Dockerfiles defined in build directory +# Prints summary after all images have been built (successfully or not) +# + +image_name="$1" + +# Checks if image name was provided by user +if [ -z "${image_name}" ]; then + echo "Usage: $0 [docker_image_name]" >&2 + exit -1 +fi + +# Change current path to project root +script_path=$(dirname "$0") +cd "${script_path}/../" || exit -1 + +# Text formatting +text_bold=$(tput bold) +text_red=$(tput setaf 1) +text_normal=$(tput sgr0) + +# Loop through all available directories in ./build +for i in ./build/*/; do + version=$(basename "$i"); + image="${image_name}:${version}" + + if [ "$version" == "${version%"cli"*}" ]; then + continue + fi + + echo "${text_bold}* Building ${image} ${text_normal}" + + # Builds image and check for return code + if ! docker build --pull -t "${image}" "./build/${version}"; then + echo "${text_bold}${text_red}* ERROR when building ${image} ${text_normal}" + exit 1 + fi + + echo "${text_bold}* Testing ${image} ${text_normal}" + + docker run \ + --volume ./scripts/test-xdebug-install.php:/app/test-xdebug-install.php \ + --workdir /app \ + --entrypoint php \ + "${image}" test-xdebug-install.php +done + diff --git a/scripts/git-has-changes.sh b/scripts/git-has-changes.sh new file mode 100755 index 0000000..59278d4 --- /dev/null +++ b/scripts/git-has-changes.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +if [[ -n $(git status --porcelain --untracked-files=no) ]]; then + exit 1 +fi diff --git a/scripts/test-xdebug-install.php b/scripts/test-xdebug-install.php new file mode 100755 index 0000000..21a8f78 --- /dev/null +++ b/scripts/test-xdebug-install.php @@ -0,0 +1,20 @@ + +LABEL org.opencontainers.image.authors="Przemek Szalko " # php intl extension RUN apt-get update \ diff --git a/src/xdebug-2.ini b/src/xdebug-2.ini deleted file mode 100644 index 94ea677..0000000 --- a/src/xdebug-2.ini +++ /dev/null @@ -1,13 +0,0 @@ -[xdebug] -zend_extension=xdebug.so - -xdebug.cli_color=1 -xdebug.profiler_enable=0 -xdebug.profiler_enable_trigger=1 - -xdebug.profiler_output_dir="/tmp" -xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" - -xdebug.remote_enable=1 -xdebug.remote_connect_back=1 -xdebug.remote_port=9000 diff --git a/src/xdebug-3.ini b/src/xdebug-3.ini index a6c56ff..b04f78c 100644 --- a/src/xdebug-3.ini +++ b/src/xdebug-3.ini @@ -1,13 +1,14 @@ [xdebug] zend_extension=xdebug.so -xdebug.cli_color=1 -xdebug.mode=debug +xdebug.cli_color=0 +xdebug.show_local_vars=1 xdebug.start_with_request=trigger -xdebug.trigger_value=StartXDebug xdebug.output_dir="/tmp" xdebug.profiler_output_name="cachegrind.out.%H.%t.%p" -xdebug.discover_client_host=true -xdebug.client_port=9003 +xdebug.mode=develop,debug +xdebug.discover_client_host=1 +xdebug.client_port=9000 +