diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml new file mode 100644 index 0000000..e1374ec --- /dev/null +++ b/.github/workflows/build-images.yml @@ -0,0 +1,176 @@ +name: Build and push images + +on: + push: + branches: + - main + paths: + - '*/*/Dockerfile' + - '*/*/variants.yaml' + - '*/*/rootfs/**' + - '*/*/.scripts/**' + - '*/*/otel/**' + - '*/latest' + workflow_dispatch: + inputs: + target: + description: 'Image/version to build (e.g. php-hyperf/8.3 or php-hyperf/latest).' + required: true + +permissions: + contents: read + +jobs: + detect: + runs-on: ubuntu-latest + outputs: + builds: ${{ steps.list.outputs.builds }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Get changed files + id: changed + if: github.event_name == 'push' + uses: tj-actions/changed-files@v44 + + - name: Build matrix + id: list + shell: bash + env: + EVENT_NAME: ${{ github.event_name }} + INPUT_TARGET: ${{ inputs.target }} + CHANGED_FILES: ${{ steps.changed.outputs.all_changed_files }} + run: | + set -euo pipefail + + declare -a versions=() + + collect_version() { + local v="$1" + [ -z "$v" ] && return + case "$v" in + [A-Za-z0-9_./-]*) ;; + *) echo "::warning::ignoring suspicious path '$v'"; return ;; + esac + local depth + depth=$(awk -F/ '{print NF}' <<< "$v") + if [ "$depth" != "2" ]; then return; fi + local resolved="$v" + if [ -L "$v" ]; then + local link_target + link_target=$(readlink "$v") + resolved="${v%/*}/${link_target}" + fi + if [ ! -f "${resolved}/Dockerfile" ]; then return; fi + for existing in "${versions[@]+"${versions[@]}"}"; do + if [ "$existing" = "$v" ]; then return; fi + done + versions+=("$v") + } + + if [ "$EVENT_NAME" = "workflow_dispatch" ]; then + collect_version "$INPUT_TARGET" + else + declare -a changed_dirs=() + for f in $CHANGED_FILES; do + dir=$(awk -F/ 'NF>=2 {print $1"/"$2}' <<< "$f") + [ -z "$dir" ] && continue + for existing in "${changed_dirs[@]+"${changed_dirs[@]}"}"; do + if [ "$existing" = "$dir" ]; then dir=""; break; fi + done + [ -n "$dir" ] && changed_dirs+=("$dir") + done + + for v in "${changed_dirs[@]+"${changed_dirs[@]}"}"; do + collect_version "$v" + done + + for symlink in */latest; do + [ -L "$symlink" ] || continue + target=$(readlink "$symlink") + parent="${symlink%/*}" + resolved="${parent}/${target}" + for changed in "${changed_dirs[@]+"${changed_dirs[@]}"}"; do + if [ "$changed" = "$resolved" ]; then + collect_version "$symlink" + break + fi + done + done + fi + + declare -a builds=() + for v in "${versions[@]+"${versions[@]}"}"; do + image="${v%%/*}" + version="${v##*/}" + ctx="$v" + if [ -L "$ctx" ]; then + link_target=$(readlink "$ctx") + ctx="${ctx%/*}/${link_target}" + fi + + manifest="${ctx}/variants.yaml" + if [ -f "$manifest" ]; then + if ! yq eval 'all_c(.target != null and .target != "" and has("suffix"))' "$manifest" | grep -qx true; then + echo "::error file=${manifest}::each entry must declare 'target' (non-empty) and 'suffix' (key required, value may be empty)" + exit 1 + fi + entries=$(yq eval -o=json "$manifest") + else + entries='[{"target":"'"$image"'","suffix":""}]' + fi + + while IFS= read -r line; do + [ -z "$line" ] && continue + builds+=("$line") + done < <(jq -c --arg img "$image" --arg ver "$version" --arg ctx "$ctx" ' + .[] | { + image: $img, + tag: ($ver + (if (.suffix // "") == "" then "" else "-" + .suffix end)), + context: $ctx, + target: .target, + build_args: ((.args // {}) | to_entries | map(.key + "=" + (.value | tostring)) | join("\n")) + } + ' <<< "$entries") + done + + if [ ${#builds[@]} -eq 0 ]; then + echo "builds=[]" >> "$GITHUB_OUTPUT" + else + joined=$(IFS=,; echo "${builds[*]}") + echo "builds=[${joined}]" >> "$GITHUB_OUTPUT" + fi + + build: + needs: detect + if: needs.detect.outputs.builds != '[]' + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + build: ${{ fromJson(needs.detect.outputs.builds) }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: ./${{ matrix.build.context }} + target: ${{ matrix.build.target }} + build-args: ${{ matrix.build.build_args }} + platforms: linux/amd64 + push: true + tags: devitools/${{ matrix.build.image }}:${{ matrix.build.tag }} + cache-from: type=gha,scope=${{ matrix.build.image }}-${{ matrix.build.tag }} + cache-to: type=gha,mode=max,scope=${{ matrix.build.image }}-${{ matrix.build.tag }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..da6b786 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,102 @@ +name: Validate variants.yaml + +on: + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Get changed variants.yaml files + id: changed + uses: tj-actions/changed-files@v44 + with: + files: '*/*/variants.yaml' + + - name: Validate each manifest + if: steps.changed.outputs.any_changed == 'true' + shell: bash + env: + CHANGED_MANIFESTS: ${{ steps.changed.outputs.all_changed_files }} + run: | + set -uo pipefail + errors=0 + + for manifest in $CHANGED_MANIFESTS; do + case "$manifest" in + [A-Za-z0-9_./-]*) ;; + *) echo "::warning::skipping suspicious path '$manifest'"; continue ;; + esac + echo "::group::${manifest}" + dir="$(dirname "$manifest")" + dockerfile="${dir}/Dockerfile" + + if ! yq eval '.' "$manifest" > /dev/null 2>&1; then + echo "::error file=${manifest}::invalid YAML syntax" + errors=$((errors+1)) + echo "::endgroup::" + continue + fi + + kind=$(yq eval 'type' "$manifest") + if [ "$kind" != "!!seq" ]; then + echo "::error file=${manifest}::root must be a YAML list (got ${kind})" + errors=$((errors+1)) + echo "::endgroup::" + continue + fi + + entries=$(yq eval -o=json "$manifest") + + bad=$(jq -c '[.[] | select((.target | type) != "string" or .target == "" or (has("suffix") | not))]' <<< "$entries") + if [ "$(jq 'length' <<< "$bad")" != "0" ]; then + echo "::error file=${manifest}::entries missing required 'target' (non-empty string) or 'suffix' key:" + jq -r '.[] | " - " + (. | tostring)' <<< "$bad" + errors=$((errors+1)) + fi + + bad_args=$(jq -c '[.[] | select(has("args") and (.args | type) != "object")]' <<< "$entries") + if [ "$(jq 'length' <<< "$bad_args")" != "0" ]; then + echo "::error file=${manifest}::'args' must be a mapping when present:" + jq -r '.[] | " - " + (. | tostring)' <<< "$bad_args" + errors=$((errors+1)) + fi + + if [ ! -f "$dockerfile" ]; then + echo "::error file=${manifest}::sibling Dockerfile not found at ${dockerfile}" + errors=$((errors+1)) + else + for target in $(jq -r '.[].target' <<< "$entries" | sort -u); do + if ! grep -qE "^FROM[[:space:]]+.*[[:space:]]+AS[[:space:]]+${target}([[:space:]]|$)" "$dockerfile"; then + echo "::error file=${manifest}::target '${target}' is not declared as a stage in ${dockerfile} (expected: FROM AS ${target})" + errors=$((errors+1)) + fi + done + fi + + duplicates=$(jq -r ' + [.[] | (if (.suffix // "") == "" then "" else .suffix end)] | + group_by(.) | map(select(length > 1)) | map(.[0]) | .[] + ' <<< "$entries" | sort -u) + if [ -n "$duplicates" ]; then + echo "::error file=${manifest}::duplicate suffix(es) detected (would produce colliding tags):" + echo "$duplicates" | sed 's/^/ - /' + errors=$((errors+1)) + fi + + echo "::endgroup::" + done + + if [ $errors -gt 0 ]; then + echo "Found ${errors} error(s) across the changed manifests." + exit 1 + fi + echo "All changed variants.yaml are valid." diff --git a/php-hyperf/8.3/.scripts/setup-dev.sh b/php-hyperf/8.3/.scripts/setup-dev.sh new file mode 100755 index 0000000..1e1beb3 --- /dev/null +++ b/php-hyperf/8.3/.scripts/setup-dev.sh @@ -0,0 +1,44 @@ +set -e + +SONAR_SCANNER_VERSION=6.2.1.4610 + +if [ "$1" = "dev" ]; then + if ! command -v apk &> /dev/null; then + echo "Error: 'apk' not found. Make sure you are running this script in an Alpine Linux environment." >&2 + exit 1 + fi + + if ! command -v composer &> /dev/null; then + echo "Error: 'composer' not found. Make sure it is installed and accessible in the system PATH." >&2 + exit 1 + fi + + echo "[$1] Installing PHP extensions and dependencies" + + apk add --no-cache \ + libstdc++ \ + ca-certificates \ + libc6-compat \ + openjdk17-jre \ + php83-pecl-xdebug \ + php83-pecl-pcov + + { + echo "opcache.enable=0" + echo "opcache.interned_strings_buffer=72" + echo "xdebug.mode=develop,debug,coverage" + echo "xdebug.idekey=PHPSTORM" + } >> /etc/php83/conf.d/zzz_2_php.ini + + mkdir -p /opt + curl -fSL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-x64.zip \ + -o /opt/sonar-scanner.zip + + unzip -qq /opt/sonar-scanner.zip -d /opt + mv /opt/sonar-scanner-${SONAR_SCANNER_VERSION}-linux-x64 /sonar-scanner + rm /opt/sonar-scanner.zip + + ln -s /sonar-scanner/bin/sonar-scanner /bin/sonar-scanner + + sed -i 's/use_embedded_jre=true/use_embedded_jre=false/g' /sonar-scanner/bin/sonar-scanner +fi diff --git a/php-hyperf/8.3/.scripts/setup.sh b/php-hyperf/8.3/.scripts/setup.sh new file mode 100755 index 0000000..b99313a --- /dev/null +++ b/php-hyperf/8.3/.scripts/setup.sh @@ -0,0 +1,18 @@ +set -e + +TIMEZONE=${1:-UTC} + +git config --global --add safe.directory /opt/www +git config --global init.defaultBranch main + +# - config PHP +{ + echo "upload_max_filesize=128M" + echo "post_max_size=128M" + echo "memory_limit=1G" + echo "date.timezone=${TIMEZONE}" +} | tee /etc/php83/conf.d/zzz_0_php.ini + +# - config timezone +ln -sf "/usr/share/zoneinfo/${TIMEZONE}" /etc/localtime +echo "${TIMEZONE}" > /etc/timezone diff --git a/php-hyperf/8.3/Dockerfile b/php-hyperf/8.3/Dockerfile new file mode 100644 index 0000000..9626fdb --- /dev/null +++ b/php-hyperf/8.3/Dockerfile @@ -0,0 +1,95 @@ +FROM alpine:3.20 AS hyperf + +ARG CONTEXT +ARG TIMEZONE +ARG APP_TARGET="liv" + +ENV TIMEZONE=${TIMEZONE:-"UTC"} \ + STDOUT_LOG_LEVEL=alert,critical,emergency,error,warning \ + SCAN_CACHEABLE=(true) + +COPY ${CONTEXT:-""}/rootfs / + +RUN apk update && \ + apk upgrade --available && \ + apk add --no-cache bash curl git unzip && \ + mkdir -p /opt/www + +SHELL ["/bin/ash", "-o", "pipefail", "-c"] + +RUN apk add --no-cache \ + php83-bcmath=8.3.15-r0 \ + php83-ctype=8.3.15-r0 \ + php83-curl=8.3.15-r0 \ + php83-dom=8.3.15-r0 \ + php83-fileinfo=8.3.15-r0 \ + php83-fpm=8.3.15-r0 \ + php83-gd=8.3.15-r0 \ + php83-iconv=8.3.15-r0 \ + php83-intl=8.3.15-r0 \ + php83-mbstring=8.3.15-r0 \ + php83-opcache=8.3.15-r0 \ + php83-openssl=8.3.15-r0 \ + php83-pcntl=8.3.15-r0 \ + php83-pdo=8.3.15-r0 \ + php83-pdo_mysql=8.3.15-r0 \ + php83-pecl-decimal=1.5.0-r1 \ + php83-pecl-ds=1.5.0-r0 \ + php83-pecl-mcrypt=1.0.7-r0 \ + php83-pecl-mongodb=1.19.1-r0 \ + php83-pecl-rdkafka=6.0.5-r0 \ + php83-pecl-redis=6.1.0-r0 \ + php83-pecl-swoole=5.1.6-r0 \ + php83-phar=8.3.15-r0 \ + php83-posix=8.3.15-r0 \ + php83-simplexml=8.3.15-r0 \ + php83-sodium=8.3.15-r0 \ + php83-tokenizer=8.3.15-r0 \ + php83-xml=8.3.15-r0 \ + php83-xmlreader=8.3.15-r0 \ + php83-xmlwriter=8.3.15-r0 \ + php83-zip=8.3.15-r0 \ + && ln -sf /usr/bin/php83 /usr/bin/php \ + && mv /etc/php/php.ini /etc/php83/conf.d/zzz_1_php.ini \ + && mv /etc/php/php-fpm.conf /etc/php83/php-fpm.d/zphp.conf + +COPY --from=composer/composer:2.8.5-bin /composer /usr/local/bin/composer + +COPY .scripts /devitools/.scripts + +RUN set -ex \ + && bash /devitools/.scripts/setup.sh "$TIMEZONE" \ + && bash /devitools/.scripts/setup-dev.sh "$APP_TARGET" \ + && rm -rf /var/cache/apk/* /tmp/* /usr/share/man + +WORKDIR /opt/www +EXPOSE 9501 +ENTRYPOINT ["php", "/opt/www/bin/hyperf.php"] +CMD ["start"] + +# --- Variant: with OTEL Collector + pgbouncer + supervisor --- +FROM hyperf AS hyperf-otel + +ARG COLLECTOR=debug +ARG OTEL_COLLECTOR_VERSION=0.121.0 + +RUN apk add --no-cache --upgrade expat \ + && apk add --no-cache supervisor wget pgbouncer \ + && OTEL_BASE_URL="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v${OTEL_COLLECTOR_VERSION}" \ + && OTEL_ASSET="otelcol-contrib_${OTEL_COLLECTOR_VERSION}_linux_amd64.tar.gz" \ + && cd /tmp \ + && wget -q "${OTEL_BASE_URL}/${OTEL_ASSET}" -O "${OTEL_ASSET}" \ + && wget -q "${OTEL_BASE_URL}/opentelemetry-collector-releases_otelcol-contrib_checksums.txt" -O checksums.txt \ + && grep " ${OTEL_ASSET}$" checksums.txt | sha256sum -c - \ + && tar -xzf "${OTEL_ASSET}" -C /usr/local/bin otelcol-contrib \ + && rm "${OTEL_ASSET}" checksums.txt \ + && chmod +x /usr/local/bin/otelcol-contrib \ + && mkdir -p /etc/pgbouncer /var/log/pgbouncer /var/run/pgbouncer /etc/supervisor.d /var/run/supervisor + +COPY otel/collectors/${COLLECTOR}.yaml /etc/otel-collector-config.yaml +COPY otel/supervisord.conf /etc/supervisord.conf +COPY otel/entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] +CMD [] diff --git a/php-hyperf/8.3/README-pt-BR.md b/php-hyperf/8.3/README-pt-BR.md new file mode 100644 index 0000000..d37d40c --- /dev/null +++ b/php-hyperf/8.3/README-pt-BR.md @@ -0,0 +1,79 @@ +# Devitools Hyperf Docker Image + +## Introdução +Esta imagem Docker foi criada para fornecer um ambiente otimizado para aplicações **Hyperf** em **PHP 8.3**, suportando tanto ambientes de desenvolvimento quanto de produção. + +Ela inclui configurações específicas para **Xdebug**, **Sonar Scanner**, ajustes de performance no PHP e suporte a análise estática de código. + +--- + +## 📦 Conteúdo da Imagem +A imagem contém: +- **PHP 8.3** com extensões essenciais +- **Composer** para gerenciamento de dependências +- **Xdebug** e **PCOV** para depuração e cobertura de código +- **Sonar Scanner** para análise de qualidade de código +- **Configuração de timezone** ajustável +- **Suporte a análise de código via SonarQube** + +--- + +## 🛠️ Configuração e Instalação +A configuração da imagem é realizada através dos scripts: + +### `setup.sh` +- Ajusta configurações do PHP, incluindo **limite de memória**, **upload_max_filesize**, e **timezone**. +- Configura o timezone do sistema. + +### `setup-dev.sh` +- Instala dependências para desenvolvimento, incluindo **Xdebug** e **Sonar Scanner**. +- Configura `xdebug.ini` para integração com **PHPStorm**. +- Desativa **JRE embutido** no Sonar Scanner para evitar conflitos. + +--- + +## 📌 Como Construir a Imagem +A imagem pode ser construída de duas formas: **para desenvolvimento** e **para produção**. + +### 🔹 **Imagem de Desenvolvimento** +Inclui **Xdebug**, **PCOV** e **Sonar Scanner** para depuração e análise de código. + +```sh +docker build --platform="linux/amd64" --build-arg APP_TARGET=dev -t devitools/php-hyperf:8.3-dev . +``` + +### 🔹 **Imagem de Produção** +Removendo ferramentas de desenvolvimento para otimizar o ambiente de execução. + +```sh +docker build --platform="linux/amd64" -t devitools/php-hyperf:8.3 . +``` + +--- + +## 🚀 Diferenças entre as Versões + +| Versão | Recursos Incluídos | +|-----------------------|------------------| +| `devitools/php-hyperf:8.3-dev` | PHP 8.3 + Xdebug + PCOV + Sonar Scanner | +| `devitools/php-hyperf:8.3` | PHP 8.3 otimizado para produção | + +--- + +## 🛠 Uso +Para rodar um container baseado na imagem: + +```sh +docker run --rm -it devitools/php-hyperf:8.3-dev php -v +``` + +Para iniciar um projeto Hyperf com a imagem: + +```sh +docker run --rm -it -v $(pwd):/opt/www devitools/php-hyperf:8.3-dev composer create-project hyperf/hyperf-skeleton . +``` + +--- + +## 📌 Conclusão +Esta imagem proporciona um ambiente completo para desenvolvimento e execução de aplicações Hyperf, garantindo produtividade e qualidade no código. diff --git a/php-hyperf/8.3/README.md b/php-hyperf/8.3/README.md new file mode 100644 index 0000000..15c9f1c --- /dev/null +++ b/php-hyperf/8.3/README.md @@ -0,0 +1,158 @@ +# Devitools Hyperf + +Optimized image for running Hyperf applications with PostgreSQL and Swoole support. + +## Introduction + +This Docker image is designed to provide an optimized environment for **Hyperf** applications running **PHP 8.3**, +supporting both development and production environments. + +It includes specific configurations for **Xdebug**, **Sonar Scanner**, PHP performance tuning, and static code analysis +support. + +## 🛠️ How to Use + +### Run a Container Directly + +```sh +docker run --rm --name hyperf -d -v "$(pwd):/opt/www" -p "8080:9501" --platform linux/amd64 devitools/php-hyperf:8.3-dev +``` + +### Example `Dockerfile` Ready for Production + +```dockerfile +FROM devitools/php-hyperf:8.3 + +COPY . /opt/www + +RUN composer install --prefer-dist --no-dev --optimize-autoloader +``` + +## 🚀 Example `docker-compose.yml` Ready for dev + +```yaml +services: + app: + image: devitools/php-hyperf:8.3-dev + container_name: template_name-app + command: [ "server:watch" ] + volumes: + - ./:/opt/www + ports: + - "9501:9501" + environment: + - SCAN_CACHEABLE=false + - STDOUT_LOG_LEVEL=alert,critical,emergency,error,warning,notice,info + restart: on-failure +``` + +## 📌 Environment Variables + +- `SCAN_CACHEABLE`: Controls Hyperf’s scan cache. +- `STDOUT_LOG_LEVEL`: Sets the log levels sent to `stdout`. + +## 🏗️ Just Run, no Build + +```sh +docker-compose up -d +``` + +## 📂 Related Repositories + +- **Dockerfile Repository** (Source code for this image): + 🔗 [github.com/devitools/dockerfile](https://github.com/devitools/dockerfile) + +- **Example Project** (Hyperf with this image): + 🔗 [github.com/phpcomrapadura/hyperf-com-rapadura](https://github.com/phpcomrapadura/hyperf-com-rapadura) + +--- + +## 📦 Image Contents + +The image includes: + +- **PHP 8.3** with essential extensions +- **Composer** for dependency management +- **Xdebug** and **PCOV** for debugging and code coverage +- **Sonar Scanner** for code quality analysis +- **Adjustable timezone configuration** +- **Support for static code analysis via SonarQube** + +--- + +## 🛠️ Configuration and Installation + +The image configuration is handled through the following scripts: + +### `setup.sh` + +- Adjusts PHP settings, including **memory limit**, **upload_max_filesize**, and **timezone**. +- Configures the system timezone. + +### `setup-dev.sh` + +- Installs development dependencies, including **Xdebug** and **Sonar Scanner**. +- Configures `xdebug.ini` for **PHPStorm** integration. +- Disables **embedded JRE** in Sonar Scanner to avoid conflicts. + +--- + +## 📌 How to Build the Image + +The image can be built in two ways: **for development** and **for production**. + +### 🔹 **Development Image** + +Includes **Xdebug**, **PCOV**, and **Sonar Scanner** for debugging and code analysis. + +```sh +docker build --platform="linux/amd64" --build-arg APP_TARGET=dev -t devitools/php-hyperf:8.3-dev . +``` + +### 🔹 **Production Image** + +Removes development tools to optimize the runtime environment. + +```sh +docker build --platform="linux/amd64" -t devitools/php-hyperf:8.3 . +``` + +## ✨ How to publish the new image + +After building the image, you can push it to Docker Hub: + +```sh +docker push devitools/php-hyperf:8.3-dev +``` + +--- + +## 🚀 Differences Between Versions + +| Version | Included Features | +|----------------------------|-----------------------------------------| +| `devitools/php-hyperf:8.3-dev` | PHP 8.3 + Xdebug + PCOV + Sonar Scanner | +| `devitools/php-hyperf:8.3` | PHP 8.3 optimized for production | + +--- + +## 🛠 Usage + +To run a container based on the image: + +```sh +docker run --rm -it devitools/php-hyperf:8.3-dev php -v +``` + +To start a Hyperf project with the image: + +```sh +docker run --rm -it -v $(pwd):/opt/www devitools/php-hyperf:8.3-dev composer create-project hyperf/hyperf-skeleton . +``` + +--- + +## 📌 Conclusion + +This image provides a complete environment for developing and running Hyperf applications, ensuring productivity and +code quality. diff --git a/php-hyperf/8.3/otel/collectors/debug.yaml b/php-hyperf/8.3/otel/collectors/debug.yaml new file mode 100644 index 0000000..4dc8718 --- /dev/null +++ b/php-hyperf/8.3/otel/collectors/debug.yaml @@ -0,0 +1,22 @@ +receivers: + zipkin: + endpoint: "0.0.0.0:9411" + +processors: + batch: + send_batch_size: 200 + timeout: 5s + memory_limiter: + check_interval: 1s + limit_mib: 256 + +exporters: + debug: + verbosity: normal + +service: + pipelines: + traces: + receivers: [zipkin] + processors: [memory_limiter, batch] + exporters: [debug] diff --git a/php-hyperf/8.3/otel/collectors/google.yaml b/php-hyperf/8.3/otel/collectors/google.yaml new file mode 100644 index 0000000..663fae1 --- /dev/null +++ b/php-hyperf/8.3/otel/collectors/google.yaml @@ -0,0 +1,22 @@ +receivers: + zipkin: + endpoint: "0.0.0.0:9411" + +processors: + batch: + send_batch_size: 200 + timeout: 5s + memory_limiter: + check_interval: 1s + limit_mib: 256 + +exporters: + googlecloud: + project: ${GOOGLE_CLOUD_PROJECT} + +service: + pipelines: + traces: + receivers: [zipkin] + processors: [memory_limiter, batch] + exporters: [googlecloud] diff --git a/php-hyperf/8.3/otel/entrypoint.sh b/php-hyperf/8.3/otel/entrypoint.sh new file mode 100755 index 0000000..57d6b3c --- /dev/null +++ b/php-hyperf/8.3/otel/entrypoint.sh @@ -0,0 +1,112 @@ +#!/bin/sh +set -e + +if [ "$PGBOUNCER_ENABLED" != "true" ]; then + exec supervisord -c /etc/supervisord.conf +fi + +PGBOUNCER_DATABASES="${PGBOUNCER_DATABASES:-default}" + +DEFAULT_POOL_SIZE="${PGBOUNCER_DEFAULT_POOL_SIZE:-5}" +MIN_POOL_SIZE="${PGBOUNCER_MIN_POOL_SIZE:-1}" +RESERVE_POOL_SIZE="${PGBOUNCER_RESERVE_POOL_SIZE:-2}" +MAX_CLIENT_CONN="${PGBOUNCER_MAX_CLIENT_CONN:-1000}" +MAX_PREPARED_STATEMENTS="${PGBOUNCER_MAX_PREPARED_STATEMENTS:-100}" +SERVER_IDLE_TIMEOUT="${PGBOUNCER_SERVER_IDLE_TIMEOUT:-300}" +SERVER_LIFETIME="${PGBOUNCER_SERVER_LIFETIME:-3600}" + +validate_alias() { + case "$1" in + *[!A-Za-z0-9_]*|"") + echo "entrypoint: invalid PGBOUNCER_DATABASES alias '$1' (allowed: [A-Za-z0-9_])" >&2 + exit 1 + ;; + esac +} + +resolve_prefix() { + if [ "$1" = "default" ]; then + echo "POSTGRES_DB" + else + echo "POSTGRES_DB_$(echo "$1" | tr '[:lower:]' '[:upper:]')" + fi +} + +echo "[databases]" > /etc/pgbouncer/pgbouncer.ini + +OLD_IFS="$IFS" +IFS=',' +for alias in $PGBOUNCER_DATABASES; do + IFS="$OLD_IFS" + alias=$(echo "$alias" | tr -d ' ') + if [ -n "$alias" ]; then + validate_alias "$alias" + prefix=$(resolve_prefix "$alias") + host=$(eval "printf '%s' \"\${${prefix}_HOST:-}\"") + port=$(eval "printf '%s' \"\${${prefix}_PORT:-5432}\"") + name=$(eval "printf '%s' \"\${${prefix}_NAME:-}\"") + user=$(eval "printf '%s' \"\${${prefix}_USERNAME:-}\"") + pass=$(eval "printf '%s' \"\${${prefix}_PASSWORD:-}\"") + + [ -z "$host" ] && { echo "entrypoint: ${prefix}_HOST is required for alias '${alias}'" >&2; exit 1; } + [ -z "$name" ] && { echo "entrypoint: ${prefix}_NAME is required for alias '${alias}'" >&2; exit 1; } + [ -z "$user" ] && { echo "entrypoint: ${prefix}_USERNAME is required for alias '${alias}'" >&2; exit 1; } + [ -z "$pass" ] && { echo "entrypoint: ${prefix}_PASSWORD is required for alias '${alias}'" >&2; exit 1; } + + echo "pgb_${alias} = host=${host} port=${port} dbname=${name} user=${user} password=${pass}" >> /etc/pgbouncer/pgbouncer.ini + fi + IFS=',' +done +IFS="$OLD_IFS" + +cat >> /etc/pgbouncer/pgbouncer.ini < /etc/supervisor.d/pgbouncer.ini <