Skip to content

PHP auto - build binaries with Docker instead of Shell #3922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
BenElferink opened this issue Apr 18, 2025 · 1 comment
Open

PHP auto - build binaries with Docker instead of Shell #3922

BenElferink opened this issue Apr 18, 2025 · 1 comment

Comments

@BenElferink
Copy link

BenElferink commented Apr 18, 2025

          How about running this inside the Dockerfile? As part of a multi-stage build

Originally posted by @iblancasa in #3409 (comment)


I noticed the discussion referenced above, and have already done this for Odigos auto-instrumentation. So I thought I could start this issue to discuss on implementing this for OpenTelemetry.

Here's the repo for full inspection (some of it is still a work in progress, focus on v8.1): https://github.com/odigos-io/opentelemetry-php

Dockerfile for building the binaries (per PHP version):

ARG PHP_VERSION
FROM --platform=$BUILDPLATFORM php:${PHP_VERSION}-cli AS builder
ARG PHP_VERSION
ARG PHP_OTEL_VERSION
WORKDIR /${PHP_VERSION}

# Install system/docker dependencies
RUN apt-get update && apt-get upgrade -y \
  && apt-get install -y wget unzip gcc make autoconf libicu-dev \
  && curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer

# Install the OTel extension (see https://opentelemetry.io/docs/zero-code/php/#install-the-opentelemetry-extension)
RUN pecl install opentelemetry-${PHP_OTEL_VERSION} \
  && docker-php-ext-enable opentelemetry

# Isolate the binary & create a pointer
RUN cp "$(php-config --extension-dir)/opentelemetry.so" opentelemetry.so
RUN echo "extension=/var/odigos/php/${PHP_VERSION}/opentelemetry.so\nauto_prepend_file=/var/odigos/php/${PHP_VERSION}/index.php" > opentelemetry.ini

# Enable extensions (for 'composer install' below)
RUN cp opentelemetry.so "$(php-config --extension-dir)/opentelemetry.so" \
  && docker-php-ext-enable opentelemetry
# Install composer libraries
COPY ./${PHP_VERSION}/composer.json .
RUN composer install --no-dev --optimize-autoloader --ignore-platform-reqs

FROM scratch AS output
ARG PHP_VERSION
COPY --from=builder ./${PHP_VERSION} ./${PHP_VERSION}
CMD ["ls", "-al", "./${PHP_VERSION}"]

Makefile for building the images, mounting the containers, extracting the binaries, and then unmounting the containers:

PHP_OTEL_VERSION=1.1.2
PHP_VERSIONS=8.0 8.1 8.2 8.3 8.4
DOCKER_MOUNT_NAME=php-otel-ext-out

# Helper method to switch PHP version during development
.PHONY: switch-php/%
switch-php/%:
	@for v in $(PHP_VERSIONS); do \
		brew unlink php@$$v || true; \
	done
	@if [ "$*" = "8.0" ]; then \
		brew install shivammathur/php/[email protected]; \
	else \
		brew install php@$* || true; \
	fi
	@brew link --overwrite --force php@$*

# Main method to build the binaries
.PHONY: all
all:
	@$(MAKE) -j $(nproc) binaries

delete-files/%:
	@rm -rf ./$*/vendor
	@rm -rf ./$*/composer.lock
	@rm -rf ./$*/opentelemetry.so
	@rm -rf ./$*/opentelemetry.ini

copy-files-from-container/%:
	@docker cp ${DOCKER_MOUNT_NAME}-$*:/$*/vendor ./$*/vendor
	@docker cp ${DOCKER_MOUNT_NAME}-$*:/$*/composer.lock ./$*/composer.lock
	@docker cp ${DOCKER_MOUNT_NAME}-$*:/$*/opentelemetry.so ./$*/opentelemetry.so
	@docker cp ${DOCKER_MOUNT_NAME}-$*:/$*/opentelemetry.ini ./$*/opentelemetry.ini

build-image/%:
	@docker build --target output -t ${DOCKER_MOUNT_NAME}:$* -f Dockerfile \
		--build-arg PHP_OTEL_VERSION=$(PHP_OTEL_VERSION) \
		--build-arg PHP_VERSION=$* .

mount-container/%:
	@docker create --name ${DOCKER_MOUNT_NAME}-$* ${DOCKER_MOUNT_NAME}:$*

unmount-container/%:
	@docker rm ${DOCKER_MOUNT_NAME}-$*

.PHONY: binaries
binaries:
	@for v in $(PHP_VERSIONS); do \
		$(MAKE) delete-files/$$v; \
		$(MAKE) build-image/$$v; \
		$(MAKE) mount-container/$$v; \
		$(MAKE) copy-files-from-container/$$v; \
		$(MAKE) unmount-container/$$v; \
	done
@BenElferink
Copy link
Author

P.S.

The Makefile can be made easier by using docker bake for matrix-like execution, the Dockerfile does not need any changes, just a relevant docker-bake.hcl or docker-bake.json.

Execute with:

docker buildx bake --file docker-bake.json --set *.args.PHP_OTEL_VERSION=1.1.2

Example .json:

{
  "group": {
    "default": {
      "targets": ["php80", "php81", "php82", "php83", "php84"]
    }
  },
  "variable": {
    "PHP_OTEL_VERSION": {
      "default": "1.1.2"
    }
  },
  "target": {
    "php-base": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "target": "output",
      "args": {
        "PHP_OTEL_VERSION": "${PHP_OTEL_VERSION}"
      }
    },
    "php80": {
      "inherits": ["php-base"],
      "tags": ["php-otel-ext-out:8.0"],
      "args": {
        "PHP_VERSION": "8.0"
      }
    },
    "php81": {
      "inherits": ["php-base"],
      "tags": ["php-otel-ext-out:8.1"],
      "args": {
        "PHP_VERSION": "8.1"
      }
    },
    "php82": {
      "inherits": ["php-base"],
      "tags": ["php-otel-ext-out:8.2"],
      "args": {
        "PHP_VERSION": "8.2"
      }
    },
    "php83": {
      "inherits": ["php-base"],
      "tags": ["php-otel-ext-out:8.3"],
      "args": {
        "PHP_VERSION": "8.3"
      }
    },
    "php84": {
      "inherits": ["php-base"],
      "tags": ["php-otel-ext-out:8.4"],
      "args": {
        "PHP_VERSION": "8.4"
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant