diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa3acdb..bf37679 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,42 +7,152 @@ on: tags: [ '*.*.*' ] pull_request: branches: [ master ] - -env: - # github.repository as / - IMAGE_NAME: ${{ github.repository }} - + workflow_dispatch: + inputs: + push: + description: 'Push Image (true or false)' + type: choice + options: + - "true" + - "false" + required: true jobs: Build: runs-on: 'ubuntu-latest' - container: - image: 'byjg/k8s-ci:latest' - options: --privileged -v /tmp/z:/var/lib/containers strategy: matrix: - include: - - php-version: "8.5" - architeture: "arm64,amd64" - - php-version: "8.4" - architeture: "arm64,amd64" - - php-version: "8.3" - architeture: "arm64,amd64" - - php-version: "5.6" - architeture: "arm64,amd64" + php-version: + - "8.5" + - "8.4" + - "8.3" + - "8.2" steps: + - name: Get current date + run: | + echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV + echo "MONTH=$(date +'%m')" >> $GITHUB_ENV + - uses: actions/checkout@v4 + - name: Install requirements run: pip install -r requirements.txt - - name: Login repository - run: buildah login --username ${{ secrets.DOCKER_REGISTRY_USER }} --password ${{ secrets.DOCKER_REGISTRY_TOKEN }} ${{ secrets.DOCKER_REGISTRY }} - - name: Building and Push PHP - run: python3 ./build.py ${{ matrix.php-version }} --arch ${{ matrix.architeture }} --build-base --build-cli --build-fpm --build-fpm-apache --build-fpm-nginx --build-nginx --push --debug - if: github.event_name != 'pull_request' - - name: Building PHP - run: python3 ./build.py ${{ matrix.php-version }} --arch ${{ matrix.architeture }} --build-base --build-cli --build-fpm --build-fpm-apache --build-fpm-nginx --build-nginx --debug - if: github.event_name == 'pull_request' + +# - name: Set up Docker +# uses: docker/setup-docker-action@v4 +# with: +# daemon-config: | +# { +# "debug": true, +# "features": { +# "containerd-snapshotter": true +# } +# } + + - name: Log into registry + uses: docker/login-action@v3 + with: + registry: ${{ secrets.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_REGISTRY_USER }} + password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Generate Dockerfiles + run: python3 ./build.py ${{ matrix.php-version }} --build-base --build-cli --build-fpm --build-fpm-apache --build-fpm-nginx --build-nginx + + - name: Build Docker image base + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-php-${{ matrix.php-version }}-base + platforms: linux/amd64,linux/arm64 + push: false + tags: | + byjg/php:${{ matrix.php-version }}-base, + byjg/php:${{ matrix.php-version }}-base-${{ env.YEAR }}.${{ env.MONTH }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Build Docker image cli + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-php-${{ matrix.php-version }}-cli + platforms: linux/amd64,linux/arm64 + push: false + tags: | + byjg/php:${{ matrix.php-version }}-cli, + byjg/php:${{ matrix.php-version }}-cli-${{ env.YEAR }}.${{ env.MONTH }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Build Docker image fpm + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-php-${{ matrix.php-version }}-fpm + platforms: linux/amd64,linux/arm64 + push: false + tags: | + byjg/php:${{ matrix.php-version }}-fpm, + byjg/php:${{ matrix.php-version }}-fpm-${{ env.YEAR }}.${{ env.MONTH }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Build Docker image fpm-apache + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-php-${{ matrix.php-version }}-fpm-apache + platforms: linux/amd64,linux/arm64 + push: false + tags: | + byjg/php:${{ matrix.php-version }}-fpm-apache, + byjg/php:${{ matrix.php-version }}-fpm-apache-${{ env.YEAR }}.${{ env.MONTH }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Build Docker image fpm-nginx + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-php-${{ matrix.php-version }}-fpm-nginx + platforms: linux/amd64,linux/arm64 + push: false + tags: | + byjg/php:${{ matrix.php-version }}-fpm-nginx, + byjg/php:${{ matrix.php-version }}-fpm-nginx-${{ env.YEAR }}.${{ env.MONTH }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Build Docker image nginx + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-php-${{ matrix.php-version }}-nginx + platforms: linux/amd64,linux/arm64 + push: false + tags: | + byjg/php:${{ matrix.php-version }}-nginx, + byjg/php:${{ matrix.php-version }}-nginx-${{ env.YEAR }}.${{ env.MONTH }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Push all built images + if: ${{ github.event_name != 'pull_request' || github.event.inputs.push == 'true' }} + run: | + docker push byjg/php:${{ matrix.php-version }}-base + docker push byjg/php:${{ matrix.php-version }}-base-${{ env.YEAR }}.${{ env.MONTH }} + docker push byjg/php:${{ matrix.php-version }}-cli + docker push byjg/php:${{ matrix.php-version }}-cli-${{ env.YEAR }}.${{ env.MONTH }} + docker push byjg/php:${{ matrix.php-version }}-fpm + docker push byjg/php:${{ matrix.php-version }}-fpm-${{ env.YEAR }}.${{ env.MONTH }} + docker push byjg/php:${{ matrix.php-version }}-fpm-apache + docker push byjg/php:${{ matrix.php-version }}-fpm-apache-${{ env.YEAR }}.${{ env.MONTH }} + docker push byjg/php:${{ matrix.php-version }}-fpm-nginx + docker push byjg/php:${{ matrix.php-version }}-fpm-nginx-${{ env.YEAR }}.${{ env.MONTH }} + docker push byjg/php:${{ matrix.php-version }}-nginx + docker push byjg/php:${{ matrix.php-version }}-nginx-${{ env.YEAR }}.${{ env.MONTH }} Documentation: if: github.ref == 'refs/heads/master' diff --git a/.gitignore b/.gitignore index 86a2c98..248370b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ .idea *~ /.tmp.sh -/venv/ +.venv/ .env *.pyc +Dockerfile-php-* +/examples/php/vendor/ +/examples/php/composer.lock diff --git a/.run/Build Dockerfile.run.xml b/.run/Build Dockerfile.run.xml new file mode 100644 index 0000000..6b59386 --- /dev/null +++ b/.run/Build Dockerfile.run.xml @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file diff --git a/.run/Build PHP 8.1 base.run.xml b/.run/Build PHP 8.1 base.run.xml deleted file mode 100644 index 430b9ed..0000000 --- a/.run/Build PHP 8.1 base.run.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.run/Build PHP 8.2 base.run.xml b/.run/Build PHP 8.2 base.run.xml deleted file mode 100644 index 72bf6bc..0000000 --- a/.run/Build PHP 8.2 base.run.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.run/Build PHP 8.3 base.run.xml b/.run/Build PHP 8.3 base.run.xml deleted file mode 100644 index 4cbeda4..0000000 --- a/.run/Build PHP 8.3 base.run.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.run/Build PHP 8.4 base.run.xml b/.run/Build PHP 8.4 base.run.xml deleted file mode 100644 index 4e0d194..0000000 --- a/.run/Build PHP 8.4 base.run.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.run/Clean up Containers.run.xml b/.run/Clean up Containers.run.xml deleted file mode 100644 index 0980e5d..0000000 --- a/.run/Clean up Containers.run.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - \ No newline at end of file diff --git a/README.md b/README.md index 83ea0f6..f7d9db4 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,10 @@ The PHP images are ready to use in: | Version | Latest Version | Monthly Builds | Alpine Version | |:-------:|:--------------:|:--------------:|:--------------:| -| **8.4** | **8.4.5** | **yes** | **edge** | -| **8.3** | **8.3.18** | **yes** | **edge** | -| **8.2** | **8.2.28** | **yes** | **edge** | +| **8.5** | **8.5.0RC2** | **yes** | **edge** | +| **8.4** | **8.4.13** | **yes** | **edge** | +| **8.3** | **8.3.26** | **yes** | **edge** | +| **8.2** | **8.2.29r2** | **yes** | **edge** | | 8.1 | 8.1.31 | - | 3.19 | | 8.0 | 8.0.30 | - | 3.16 | | 7.4 | 7.4.33 | - | 3.15 | diff --git a/build.py b/build.py index 016a9ab..b475521 100644 --- a/build.py +++ b/build.py @@ -1,5 +1,5 @@ import argparse - +import pathlib import os import sys @@ -79,7 +79,7 @@ # Execute the parse_args() method args = my_parser.parse_args() -gen = Generator(args.PHP_Version, args.Debug, args.push != "") + cmd_list = [] cmd_list.append(args.buildBase) if args.buildBase != "" else None @@ -90,8 +90,9 @@ cmd_list.append(args.buildNginx) if args.buildNginx != "" else None for cmd in cmd_list: - gen.manifest_create(cmd) - for arch in args.arch.split(","): - iid = getattr(gen, "build_" + cmd)(arch) - gen.manifest_add(iid, cmd, arch) - gen.manifest_push(cmd) + gen = Generator(args.PHP_Version, args.Debug, args.push != "") + image_name = getattr(gen, "build_" + cmd)() + dockerfile_content = gen.get_dockerfile_content() + dockerfile_name = gen.dockerfile_name() + print(f"docker build -t {image_name} -f {dockerfile_name} .") + pathlib.Path(dockerfile_name).write_text(dockerfile_content) diff --git a/docs/image-cli.md b/docs/image-cli.md index 710f27e..d405620 100644 --- a/docs/image-cli.md +++ b/docs/image-cli.md @@ -10,20 +10,19 @@ The CLI images extend from the "*-base" image and also include: You can create aliases to easily use the commands: ```bash -export PHP_VERSION="7.3" -alias php='docker run -it --rm -v "$PWD":/workdir -w /workdir -u $(id -u):$(id -g) byjg/php:$PHP_VERSION-cli php "$@"' -alias phpunit='docker run -it --rm -v "$PWD":/workdir -w /workdir -u $(id -u):$(id -g) byjg/php:$PHP_VERSION-cli phpunit "$@"' -alias phpcs='docker run -it --rm -v "$PWD":/workdir -w /workdir -u $(id -u):$(id -g) byjg/php:$PHP_VERSION-cli phpcs "$@"' -alias phpmd='docker run -it --rm -v "$PWD":/workdir -w /workdir -u $(id -u):$(id -g) byjg/php:$PHP_VERSION-cli phpmd "$@"' -alias composer='docker run -it --rm -v "$PWD":/workdir -v "$HOME/.composer:/.composer" -w /workdir -u $(id -u):$(id -g) byjg/php:$PHP_VERSION-cli composer "$@"' +export PHP_VERSION="8.4" +alias php='docker run -it --rm -v "$PWD":/workdir -w /workdir -u $(id -u):$(id -g) byjg/php:$PHP_VERSION-cli php' +alias composer='docker run -it --rm -v "$PWD":/workdir -v "$HOME/.composer:/.composer" -w /workdir -u $(id -u):$(id -g) byjg/php:$PHP_VERSION-cli composer' ``` When you execute, e.g., `php --version`, you will see: ```text -PHP 7.3.27 (cli) (built: Feb 4 2021 21:04:33) ( NTS ) -Copyright (c) 1997-2018 The PHP Group -Zend Engine v3.3.27, Copyright (c) 1998-2018 Zend Technologies - with Xdebug v2.9.8, Copyright (c) 2002-2020, by Derick Rethans +PHP 8.4.13 (cli) (built: Sep 23 2025 19:01:29) (NTS) +Copyright (c) The PHP Group +Built by Alpine Linux aports +Zend Engine v4.4.13, Copyright (c) Zend Technologies + with Zend OPcache v8.4.13, Copyright (c), by Zend Technologies + with Xdebug v3.4.6, Copyright (c) 2002-2025, by Derick Rethans ``` diff --git a/examples/Dockerfile-example-fpm b/examples/Dockerfile-example-fpm new file mode 100644 index 0000000..cc2dfcb --- /dev/null +++ b/examples/Dockerfile-example-fpm @@ -0,0 +1,5 @@ +FROM byjg/php:8.3-fpm + +COPY php /srv + +RUN rm -rf /srv/vendor && composer update \ No newline at end of file diff --git a/examples/Dockerfile-example-nginx b/examples/Dockerfile-example-nginx new file mode 100644 index 0000000..2b832b9 --- /dev/null +++ b/examples/Dockerfile-example-nginx @@ -0,0 +1,5 @@ +FROM byjg/php:8.3-fpm-nginx + +COPY php /srv + +RUN rm -rf /srv/vendor && composer update \ No newline at end of file diff --git a/examples/cli/php-from-docker.sh b/examples/cli/php-from-docker.sh new file mode 100755 index 0000000..870e4bd --- /dev/null +++ b/examples/cli/php-from-docker.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# Usage: +# source ./php-from-docker.sh + +if [ -z "$1" ]; then + echo Usage: + echo source "$0" \ + exit 1 +fi + +export PHP_VERSION="$1" + +docker pull byjg/php:"${PHP_VERSION}"-cli + +alias php='docker run -it --rm -v "$PWD":/workdir -w /workdir -u $(id -u):$(id -g) -p 9001:9001 byjg/php:${PHP_VERSION}-cli php' +alias composer='docker run -it --rm -v "$PWD":/workdir -v "$HOME/.composer:/.composer" -w /workdir -u $(id -u):$(id -g) byjg/php:${PHP_VERSION}-cli composer' diff --git a/examples/fpm-nginx/README.md b/examples/fpm-nginx/README.md new file mode 100644 index 0000000..5328a7f --- /dev/null +++ b/examples/fpm-nginx/README.md @@ -0,0 +1,8 @@ +## how to build this example + +```bash +docker compose -f fpm-nginx/docker-compose.yml build +docker compose -f fpm-nginx/docker-compose.yml up +``` + +Open your browser and access [http://localhost:9090/test](http://localhost:9090/test) diff --git a/examples/fpm-nginx/docker-compose.yml b/examples/fpm-nginx/docker-compose.yml new file mode 100644 index 0000000..49e9596 --- /dev/null +++ b/examples/fpm-nginx/docker-compose.yml @@ -0,0 +1,11 @@ +services: + php: + image: php-fpm-nginx-example + build: + dockerfile: Dockerfile-example-nginx + context: $PWD + environment: + NGINX_ROOT: "/srv/public" + PHP_CONTROLLER: "/app.php" + ports: + - "9090:80" diff --git a/examples/fpm/README.md b/examples/fpm/README.md new file mode 100644 index 0000000..00a02ae --- /dev/null +++ b/examples/fpm/README.md @@ -0,0 +1,8 @@ +## how to build this example + +```bash +docker compose -f fpm/docker-compose.yml build +docker compose -f fpm/docker-compose.yml up +``` + +Open your browser and access [http://localhost:9080/test](http://localhost:9080/test) diff --git a/examples/fpm/docker-compose.yml b/examples/fpm/docker-compose.yml new file mode 100644 index 0000000..37a05b9 --- /dev/null +++ b/examples/fpm/docker-compose.yml @@ -0,0 +1,16 @@ +services: + php: + image: php-fpm-example + build: + dockerfile: Dockerfile-example-fpm + context: $PWD + + nginx: + image: byjg/php:8.3-nginx-2024.06 + ports: + - "9080:80" + environment: + - NGINX_ROOT=/srv/public + - PHP_CONTROLLER=/app.php + - PHP_FPM_SERVER=php:9000 + - VERBOSE=true diff --git a/examples/php/composer.json b/examples/php/composer.json new file mode 100644 index 0000000..74cea60 --- /dev/null +++ b/examples/php/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "byjg/restserver": "^5.0" + } +} diff --git a/examples/php/public/app.php b/examples/php/public/app.php new file mode 100644 index 0000000..c235be2 --- /dev/null +++ b/examples/php/public/app.php @@ -0,0 +1,18 @@ +addRoute(Route::get("/test") + ->withOutputProcessor(JsonOutputProcessor::class) + ->withClosure(function ($response, $request) { + $response->write('OK'); + }) +); + +$restServer = new HttpRequestHandler(); +$restServer->handle($routeDefinition); \ No newline at end of file diff --git a/generator/__init__.py b/generator/__init__.py index 632c703..ac4b1de 100644 --- a/generator/__init__.py +++ b/generator/__init__.py @@ -1,14 +1,13 @@ import os, sys import yaml -import subprocess from jinja2 import Environment, FileSystemLoader from datetime import datetime, date class Generator: def __init__(self, php_version, debug, push): - content = "{dir}/config/php-{version}.yml".format(dir=os.getcwd(), version=php_version) + build_config = "{dir}/config/php-{version}.yml".format(dir=os.getcwd(), version=php_version) - if not os.path.exists(content): + if not os.path.exists(build_config): print('PHP Version {version} does not exists'.format(version=php_version)) sys.exit(1) @@ -16,154 +15,149 @@ def __init__(self, php_version, debug, push): self.debug = debug self.push = push self.build_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - self.content = yaml.load(stream=open(content), Loader=yaml.SafeLoader) + self.build_config = yaml.load(stream=open(build_config), Loader=yaml.SafeLoader) self.local_base = False - print("--------------------------------------------") - print("PHP Version: " + php_version) - print("Debug: " + ("true" if debug else "false")) - print("--------------------------------------------") - self._run_cli(["podman", "run", "--rm", "--events-backend=file", "--cgroup-manager=cgroupfs", "--privileged", "docker://multiarch/qemu-user-static", "--reset", "-p", "yes"]) + self.dockerfile_content = {"header": "", "from": "", "env": "", "cmd": "", "entrypoint": "", "workdir": "", "copy": "", "run": ""} + self.config = None + # print("--------------------------------------------") + # print("PHP Version: " + php_version) + # print("Debug: " + ("true" if debug else "false")) + # print("--------------------------------------------") + self.dockerfile_content["header"] += f"# Generated Dockerfile for PHP {php_version} at {self.build_date}\n" + self.dockerfile_content["header"] += f"# This file was generated by the byjg/docker-php Generator\n\n" - def _run_cli(self, cmds): - if self.debug: - print("\n>>>> " + " ".join(cmds)) - subprocess.run(cmds, check=True) - def parse_config(self, template, prepared=True): file_loader = FileSystemLoader('templates') env = Environment(loader=file_loader) template = env.get_template(template) - output = template.render(self.content) - + output = template.render(self.build_config) if prepared: - return map(lambda x: "echo == COMMAND: {x} \\\n && {y}".format(y=x, x=x.replace("|", "...").replace(">", "...").replace("<", "...").replace(";", "...")), filter(lambda x: not x.startswith('#') and x != "", output.split("\n"))) - + # Process each line individually + processed_lines = [] + for line in output.split('\n'): + # Remove trailing comments and strip whitespace + processed_line = line.split('#')[0].strip() + # Keep only non-empty lines + if processed_line: + processed_lines.append(processed_line) + + # Apply the join operation directly + output = " \\\n && ".join(processed_lines) return output def _banner(self, config): - print("") - print("") - print("===================================================================") - print("Building PHP {major}.{minor}-{config}".format(major=self.content["version"]["major"], minor=self.content["version"]["minor"], config=config)) - print("===================================================================") - print("") - - def _build(self, container, config, arch): - config_template = "php-" + config + ".j2" - image = "{image}-{arch}".format( - image=self.imageName(config), - arch=arch - ) - self._run_cli(["buildah", "config", "--env", "DOCKER_IMAGE={image}".format(image=image), container]) - self._run_cli(["buildah", "config", "--env", "PHP_VERSION={major}.{minor}".format(major=self.content["version"]["major"], minor=self.content["version"]["minor"]), container]) - self._run_cli(["buildah", "config", "--env", "PHP_VARIANT=php{suffix}".format(suffix=self.content["version"]["suffix"]), container]) - if not self.debug: - [self._run_cli(["buildah", "run", container, "/bin/sh", "-c", command]) for command in self.parse_config(config_template)] - else: - self._run_cli(["buildah", "run", container, "/bin/sh", "-c", " \\\n && ".join(self.parse_config(config_template))]) - self._run_cli(["buildah", "config", "--env", "BUILD_DATE={date}".format(date=self.build_date), container]) - self._run_cli(["buildah", "commit", "--iidfile", "/tmp/iid", container, "containers-storage:localhost/{image}".format(image=image)]) - with open('/tmp/iid', 'r') as f: - iid = f.read() - return iid - - def _from(self, image, arch): - cmd = "buildah --arch {arch} from {image}".format(image=image, arch=arch) - if self.debug: - print("\n>>>> " + cmd) - return subprocess.check_output(cmd, shell=True).decode("UTF-8").strip() - - def imageName(self, config): + self.config = config + # print("") + # print("") + # print("===================================================================") + # print("Building PHP {major}.{minor}-{config}".format(major=self.build_config["version"]["major"], minor=self.build_config["version"]["minor"], config=self.config)) + # print("===================================================================") + # print("") + + def _build(self): + config_template = "php-" + self.config + ".j2" + image = self.image_name() + + self.dockerfile_content["header"] += f"# Image tag (for reference): {image}\n" + self.dockerfile_content["env"] += f"ENV DOCKER_IMAGE=\"{image}\"\n" + self.dockerfile_content["env"] += "ENV PHP_VERSION=\"{major}.{minor}\"\n".format(major=self.build_config["version"]["major"], minor=self.build_config["version"]["minor"]) + self.dockerfile_content["env"] += "ENV PHP_VARIANT=\"php{suffix}\"\n".format(suffix=self.build_config["version"]["suffix"]) + self.dockerfile_content["env"] += "ENV BUILD_DATE=\"{date}\"\n".format(date=self.build_date) + self.dockerfile_content["run"] += "RUN " + self.parse_config(config_template) + "\n" + + return image + + def _from(self, image): + # Write FROM directive to Dockerfile and return a dummy container id + self.dockerfile_content["from"] += f"FROM {image}\n" + + def get_dockerfile_content(self): + return self.dockerfile_content["header"] + \ + self.dockerfile_content["from"] + \ + self.dockerfile_content["env"] + \ + self.dockerfile_content["workdir"] + \ + self.dockerfile_content["copy"] + \ + self.dockerfile_content["run"] + \ + self.dockerfile_content["cmd"] + \ + self.dockerfile_content["entrypoint"] + + def image_name(self): return "byjg/php:{major}.{minor}-{config}".format( - major=self.content["version"]["major"], - minor=self.content["version"]["minor"], - config=config.replace("_", "-") + major=self.build_config["version"]["major"], + minor=self.build_config["version"]["minor"], + config=self.config.replace("_", "-") ) - def source_repo(self, arch, php_source): - return "{source_repo}byjg/php:{major}.{minor}-{php_source}{arch}".format( - source_repo="containers-storage:localhost/" if self.local_base else "docker://", - major=self.content["version"]["major"], - minor=self.content["version"]["minor"], - php_source=php_source, - arch="-" + arch if self.local_base else "") - - def manifest_create(self, config): - self._run_cli(["buildah", "manifest", "create", self.imageName(config)]) - - def manifest_add(self, iid, config, arch): - self._run_cli(["buildah", "manifest", "add", self.imageName(config), "--arch", arch] - + (["--variant", "v8"] if arch in ['arm64', 'aarch64'] else []) - + [iid]) - - def manifest_push(self, config): - if not self.push: - return - local_image = "containers-storage:localhost/" + self.imageName(config) - image_month = "{image}-{year}.{month:02d}".format(image=self.imageName(config), year=date.today().year, month=date.today().month) - self._run_cli(["buildah", "manifest", "push", "--all", "--format", "v2s2", local_image, "docker://" + self.imageName(config)]) - self._run_cli(["buildah", "manifest", "push", "--all", "--format", "v2s2", local_image, "docker://" + image_month]) - - def build_base(self, arch): + def dockerfile_name(self): + return "Dockerfile-php-{major}.{minor}-{config}".format( + major=self.build_config["version"]["major"], + minor=self.build_config["version"]["minor"], + config=self.config.replace("_", "-") + ) + + def source_repo(self, php_source): + return "byjg/php:{major}.{minor}-{php_source}".format( + major=self.build_config["version"]["major"], + minor=self.build_config["version"]["minor"], + php_source=php_source) + + def build_base(self): self._banner("base") - base_image = self.content["image"][arch] if arch in self.content["image"] else self.content["image"]["default"] - container = self._from("docker://" + base_image, arch) - self._run_cli(["buildah", "config", "--entrypoint", '["/entrypoint.sh"]', container]) - self._run_cli(["buildah", "config", "--workingdir", "/srv", container]) - self._run_cli(["buildah", "copy", container, "assets/entrypoint.sh", "/"]) - self._run_cli(["buildah", "copy", container, "assets/script/install-sqlsvr.sh", "/install-sqlsvr.sh"]) + base_image = self.build_config["image"]["default"] + self._from(base_image) + self.dockerfile_content["entrypoint"] += "ENTRYPOINT [\"/entrypoint.sh\"]\n" + self.dockerfile_content["workdir"] += "WORKDIR /srv\n" + self.dockerfile_content["copy"] += "COPY assets/entrypoint.sh /\n" + self.dockerfile_content["copy"] += "COPY assets/script/install-sqlsvr.sh /install-sqlsvr.sh\n" self.local_base = True - return self._build(container, "base", arch) + return self._build() - def build_cli(self, arch): + def build_cli(self): self._banner("cli") - container = self._from(self.source_repo(arch, "base"), arch) - return self._build(container, "cli", arch) + self._from(self.source_repo("base")) + return self._build() - def build_fpm(self, arch): + def build_fpm(self): self._banner("fpm") - container = self._from(self.source_repo(arch, "base"), arch) - self._run_cli(["buildah", "config", "--cmd", '/start-fpm.sh', container]) - self._run_cli(["buildah", "copy", container, "assets/fpm/conf/www.conf", "/etc/php{major}{minor}/php-fpm.d/www.conf".format(major=self.content["version"]["major"], minor=self.content["version"]["minor"])]) - self._run_cli(["buildah", "copy", container, "assets/fpm/conf/base.conf", "/etc/php{major}{minor}/php-fpm.d/base.conf".format(major=self.content["version"]["major"], minor=self.content["version"]["minor"])]) - self._run_cli(["buildah", "copy", container, "assets/script/start-fpm.sh", "/start-fpm.sh"]) + self._from(self.source_repo("base")) + self.dockerfile_content["cmd"] += "CMD [\"/start-fpm.sh\"]\n" + self.dockerfile_content["copy"] += "COPY assets/fpm/conf/www.conf /etc/php{suffix}/php-fpm.d/www.conf\n".format(suffix=self.build_config["version"]["suffix"]) + self.dockerfile_content["copy"] += "COPY assets/fpm/conf/base.conf /etc/php{suffix}/php-fpm.d/base.conf\n".format(suffix=self.build_config["version"]["suffix"]) + self.dockerfile_content["copy"] += "COPY assets/script/start-fpm.sh /start-fpm.sh\n" - return self._build(container, "fpm", arch) + return self._build() - def build_fpm_apache(self, arch): + def build_fpm_apache(self): self._banner("fpm-apache") - container = self._from(self.source_repo(arch, "fpm"), arch) - self._run_cli(["buildah", "config", "--cmd", '/usr/bin/supervisord -n -c /etc/supervisord.conf', container]) - self._run_cli(["buildah", "copy", container, "assets/fpm-apache/conf/httpd.conf", "/etc/apache2/httpd.conf"]) - self._run_cli(["buildah", "copy", container, "assets/fpm-apache/conf/vhost.conf", "/etc/apache2/conf.d/"]) - self._run_cli(["buildah", "copy", container, "assets/fpm-apache/conf/supervisord.conf", "/etc/supervisord.conf"]) - self._run_cli(["buildah", "copy", container, "assets/script/exit-event-listener.py", "/exit-event-listener.py"]) - return self._build(container, "fpm-apache", arch) - - def build_fpm_nginx(self, arch): + self._from(self.source_repo("fpm")) + self.dockerfile_content["cmd"] += "CMD [\"/usr/bin/supervisord\", \"-n\", \"-c\", \"/etc/supervisord.conf\"]\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-apache/conf/httpd.conf /etc/apache2/httpd.conf\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-apache/conf/vhost.conf /etc/apache2/conf.d/\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-apache/conf/supervisord.conf /etc/supervisord.conf\n" + self.dockerfile_content["copy"] += "COPY assets/script/exit-event-listener.py /exit-event-listener.py\n" + return self._build() + + def build_fpm_nginx(self): self._banner("fpm-nginx") - container = self._from(self.source_repo(arch, "fpm"), arch) - self._run_cli(["buildah", "config", "--cmd", '/usr/bin/supervisord -n -c /etc/supervisord.conf', container]) - self._run_cli(["buildah", "copy", container, "assets/fpm-nginx/conf/nginx.conf", "/etc/nginx/nginx.conf"]) - self._run_cli(["buildah", "copy", container, "assets/fpm-nginx/conf/nginx.vh.default.conf", "/etc/nginx/http.d/default.conf"]) - self._run_cli(["buildah", "copy", container, "assets/fpm-nginx/conf/supervisord.conf", "/etc/supervisord.conf"]) - self._run_cli(["buildah", "copy", container, "assets/script/exit-event-listener.py", "/exit-event-listener.py"]) - self._run_cli(["buildah", "copy", container, "assets/script/start-nginx.sh", "/start-nginx.sh"]) - script = self.parse_config("php-fpm-nginx.j2", False) - with open(".tmp.sh", "w") as file: - file.write(script) - self._run_cli(["buildah", "copy", container, ".tmp.sh", "/tmp/install_nginx.sh"]) - return self._build(container, "fpm-nginx", arch) - - def build_nginx(self, arch): + self._from(self.source_repo("fpm")) + self.dockerfile_content["cmd"] += "CMD [\"/usr/bin/supervisord\", \"-n\", \"-c\", \"/etc/supervisord.conf\"]\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-nginx/conf/nginx.conf /etc/nginx/nginx.conf\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-nginx/conf/nginx.vh.default.conf /etc/nginx/http.d/default.conf\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-nginx/conf/supervisord.conf /etc/supervisord.conf\n" + self.dockerfile_content["copy"] += "COPY assets/script/exit-event-listener.py /exit-event-listener.py\n" + self.dockerfile_content["copy"] += "COPY assets/script/start-nginx.sh /start-nginx.sh\n" + self.dockerfile_content["run"] += "RUN " + self.parse_config("php-fpm-nginx.j2") + "\n" + return self._build() + + def build_nginx(self): self._banner("nginx") - base_image = self.content["image"][arch] if arch in self.content["image"] else self.content["image"]["default"] - container = self._from("docker://" + base_image, arch) - self._run_cli(["buildah", "config", "--cmd", "/start-nginx.sh", container]) - self._run_cli(["buildah", "config", "--entrypoint", '["/entrypoint.sh"]', container]) - self._run_cli(["buildah", "config", "--workingdir", "/srv", container]) - self._run_cli(["buildah", "copy", container, "assets/fpm-nginx/conf/nginx.conf", "/etc/nginx/nginx.conf"]) - self._run_cli(["buildah", "copy", container, "assets/fpm-nginx/conf/nginx.vh.default.conf", "/etc/nginx/http.d/default.conf"]) - self._run_cli(["buildah", "copy", container, "assets/script/start-nginx.sh", "/start-nginx.sh"]) - self._run_cli(["buildah", "copy", container, "assets/entrypoint.sh", "/"]) - return self._build(container, "nginx", arch) + base_image = self.build_config["image"]["default"] + self._from(base_image) + self.dockerfile_content["cmd"] += "CMD [\"/start-nginx.sh\"]\n" + self.dockerfile_content["entrypoint"] += "ENTRYPOINT [\"/entrypoint.sh\"]\n" + self.dockerfile_content["workdir"] += "WORKDIR /srv\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-nginx/conf/nginx.conf /etc/nginx/nginx.conf\n" + self.dockerfile_content["copy"] += "COPY assets/fpm-nginx/conf/nginx.vh.default.conf /etc/nginx/http.d/default.conf\n" + self.dockerfile_content["copy"] += "COPY assets/script/start-nginx.sh /start-nginx.sh\n" + self.dockerfile_content["copy"] += "COPY assets/entrypoint.sh /\n" + return self._build() diff --git a/requirements.txt b/requirements.txt index 3a744f7..690a2b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Jinja2==3.1.3 +Jinja2==3.1.4 jinja2-cli==0.8.2 MarkupSafe==2.1.5 argparse==1.4.0 diff --git a/templates/php-base.j2 b/templates/php-base.j2 index c94c33a..48266c4 100644 --- a/templates/php-base.j2 +++ b/templates/php-base.j2 @@ -1,10 +1,8 @@ -set -euo pipefail - # Install Packages apk --no-cache {% for rep in repositories %}--repository {{ rep }} {% endfor %} upgrade apk --no-cache {% for rep in repositories %}--repository {{ rep }} {% endfor %} add git bash php{{ version.suffix }} {% for ext in extensions %} php{{ version.suffix }}-{{ ext }}{% endfor %} -ln -s /usr/bin/php{{ version.suffix }} /usr/bin/php || true -ln -s /usr/bin/pecl{{ version.suffix }} /usr/bin/pecl || true +(ln -s /usr/bin/php{{ version.suffix }} /usr/bin/php || true) +(ln -s /usr/bin/pecl{{ version.suffix }} /usr/bin/pecl || true) mkdir -p /etc/php/conf.d # Install PECL and additional packages diff --git a/templates/php-fpm-apache.j2 b/templates/php-fpm-apache.j2 index 6c1f236..6f92dbb 100644 --- a/templates/php-fpm-apache.j2 +++ b/templates/php-fpm-apache.j2 @@ -3,7 +3,7 @@ ln -sf /dev/stdout /var/log/apache2/access.log ln -sf /dev/stderr /var/log/apache2/error.log mkdir -p /run/apache2 chmod a+x /start-fpm.sh -ln -s /usr/bin/python3 /usr/bin/python || true +(ln -s /usr/bin/python3 /usr/bin/python || true) echo "" >> /var/www/localhost/htdocs/info.php date > /etc/build-date diff --git a/templates/php-fpm-nginx.j2 b/templates/php-fpm-nginx.j2 index f72e779..39a34d8 100644 --- a/templates/php-fpm-nginx.j2 +++ b/templates/php-fpm-nginx.j2 @@ -1,8 +1,10 @@ -apk add --no-cache nginx nginx-mod-http-headers-more nginx-mod-http-zip nginx-mod-http-js supervisor bash +apk add --no-cache nginx nginx-mod-http-headers-more nginx-mod-http-js supervisor bash ln -sf /dev/stdout /var/log/nginx/access.log ln -sf /dev/stderr /var/log/nginx/error.log mkdir -p /var/www/html echo "" >> /var/www/html/info.php +rm -rf /etc/nginx/conf.d +mkdir -p /run/nginx date > /etc/build-date diff --git a/templates/php-fpm.j2 b/templates/php-fpm.j2 index 7574375..e980bf4 100644 --- a/templates/php-fpm.j2 +++ b/templates/php-fpm.j2 @@ -1,4 +1,4 @@ apk add --no-cache {% for rep in repositories %}--repository {{ rep }} {% endfor %} php{{ version.suffix }}-fpm -ln -s $(which php-fpm{{ version.suffix }}) /usr/bin/php-fpm || true +(ln -s $(which php-fpm{{ version.suffix }}) /usr/bin/php-fpm || true) date > /etc/build-date diff --git a/templates/php-nginx.j2 b/templates/php-nginx.j2 index 2b6bcea..5ab0a50 100644 --- a/templates/php-nginx.j2 +++ b/templates/php-nginx.j2 @@ -1,8 +1,10 @@ -apk add --no-cache nginx nginx-mod-http-headers-more nginx-mod-http-zip nginx-mod-http-js bash +apk add --no-cache nginx nginx-mod-http-headers-more nginx-mod-http-js bash ln -sf /dev/stdout /var/log/nginx/access.log ln -sf /dev/stderr /var/log/nginx/error.log mkdir -p /var/www/html echo "" >> /var/www/html/info.php +rm -rf /etc/nginx/conf.d +mkdir -p /run/nginx date > /etc/build-date