From 731778c3f5b58ee72ff7a7854bf6c0c4b8a647a3 Mon Sep 17 00:00:00 2001 From: cytopia Date: Sun, 13 Feb 2022 12:18:21 +0100 Subject: [PATCH 1/5] Multi Arch build --- .github/dependabot.yml | 7 + .github/workflows/build.yml | 217 +++++++++++++++-------------- .github/workflows/contributor.yml | 86 ++++++++++++ .github/workflows/lint.yml | 1 + .github/workflows/nightly.yml | 222 +++++++++++++++--------------- Dockerfile | 4 +- Makefile | 86 +++++++++--- README.md | 37 ++--- build/gen-readme.sh | 3 +- {.ci => tests}/.lib.sh | 0 {.ci => tests}/00.sh | 3 +- {.ci => tests}/01.sh | 13 +- {.ci => tests}/start-ci.sh | 11 +- 13 files changed, 409 insertions(+), 281 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/contributor.yml rename {.ci => tests}/.lib.sh (100%) rename {.ci => tests}/00.sh (93%) rename {.ci => tests}/01.sh (86%) rename {.ci => tests}/start-ci.sh (59%) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2c7d170 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 28e1a1a..9d72ebf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,148 +10,151 @@ name: build # When to run # ------------------------------------------------------------------------------------------------- on: - # Runs on Pull Requests - pull_request: # Runs on Push push: -# ------------------------------------------------------------------------------------------------- -# What to run -# ------------------------------------------------------------------------------------------------- jobs: + + # ----------------------------------------------------------------------------------------------- + # Job (1/2): BUILD + # ----------------------------------------------------------------------------------------------- build: - name: "[ HTTPD ]" + name: "[ ${{ matrix.version }} (${{ matrix.arch }}) ]" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: + - 'Apache 2.2' + arch: + - 'linux/amd64' + - 'linux/arm64' + - 'linux/386' + - 'linux/arm/v7' + - 'linux/arm/v6' steps: # ------------------------------------------------------------ # Setup repository # ------------------------------------------------------------ - - name: Checkout repository + - name: "[SETUP] Checkout repository" uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Set variables - id: vars - run: | - - # Retrieve git info (tags, etc) - git fetch --all - - # Branch, Tag or Commit - GIT_TYPE="$( \ - curl -sS https://raw.githubusercontent.com/cytopia/git-tools/master/git-info.sh \ - | sh \ - | grep '^GIT_TYPE' \ - | sed 's|.*=||g' \ - )" - # Branch name, Tag name or Commit Hash - GIT_SLUG="$( \ - curl -sS https://raw.githubusercontent.com/cytopia/git-tools/master/git-info.sh \ - | sh \ - | grep '^GIT_NAME' \ - | sed 's|.*=||g' \ - )" - # Docker Tag - if [ "${GIT_TYPE}" = "BRANCH" ] && [ "${GIT_SLUG}" = "master" ]; then - DOCKER_TAG="latest" - else - DOCKER_TAG="${GIT_SLUG}" - fi - - # Output - echo "GIT_TYPE=${GIT_TYPE}" - echo "GIT_SLUG=${GIT_SLUG}" - echo "DOCKER_TAG=${DOCKER_TAG}" - - # Export variable - # https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#environment-files - echo "GIT_TYPE=${GIT_TYPE}" >> ${GITHUB_ENV} - echo "GIT_SLUG=${GIT_SLUG}" >> ${GITHUB_ENV} - echo "DOCKER_TAG=${DOCKER_TAG}" >> ${GITHUB_ENV} + - name: "[SETUP] Setup QEMU environment" + uses: docker/setup-qemu-action@v1 + with: + image: tonistiigi/binfmt:latest + platforms: all + - name: "[SETUP] Determine Docker tag" + id: tag + uses: cytopia/docker-tag@v0.3 # ------------------------------------------------------------ # Build # ------------------------------------------------------------ - name: Build - run: | - retry() { - for n in $(seq ${RETRIES}); do - echo "[${n}/${RETRIES}] ${*}"; - if eval "${*}"; then - echo "[SUCC] ${n}/${RETRIES}"; - return 0; - fi; - sleep ${PAUSE}; - echo "[FAIL] ${n}/${RETRIES}"; - done; - return 1; - } - retry make build + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make build ARCH=${ARCH} env: - RETRIES: 20 - PAUSE: 10 + ARCH: ${{ matrix.arch }} # ------------------------------------------------------------ # Test # ------------------------------------------------------------ - - name: Test Docker Image - run: | - retry() { - for n in $(seq ${RETRIES}); do - echo "[${n}/${RETRIES}] ${*}"; - if eval "${*}"; then - echo "[SUCC] ${n}/${RETRIES}"; - return 0; - fi; - sleep ${PAUSE}; - echo "[FAIL] ${n}/${RETRIES}"; - done; - return 1; - } - retry make test + - name: "[TEST] Docker Image" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make test ARCH=${ARCH} env: - RETRIES: 20 - PAUSE: 10 + ARCH: ${{ matrix.arch }} + - name: "[TEST] Update README" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make update-readme ARCH=${ARCH} + env: + ARCH: ${{ matrix.arch }} # ------------------------------------------------------------ # Deploy # ------------------------------------------------------------ - - name: Publish images (only repo owner) - run: | - retry() { - for n in $(seq ${RETRIES}); do - echo "[${n}/${RETRIES}] ${*}"; - if eval "${*}"; then - echo "[SUCC] ${n}/${RETRIES}"; - return 0; - fi; - sleep ${PAUSE}; - echo "[FAIL] ${n}/${RETRIES}"; - done; - return 1; - } - - # Output - echo "GIT_TYPE=${GIT_TYPE}" - echo "GIT_SLUG=${GIT_SLUG}" - echo "DOCKER_TAG=${DOCKER_TAG}" - - # Tag image - retry make tag TAG=${DOCKER_TAG} - docker images - - # Login and Push - retry make login USER=${{ secrets.DOCKERHUB_USERNAME }} PASS=${{ secrets.DOCKERHUB_PASSWORD }} - retry make push TAG=${DOCKER_TAG} + - name: "[DEPLOY] Login" + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + - name: "[DEPLOY] Publish architecture image (only repo owner)" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make push-arch TAG=${{ steps.tag.outputs.docker-tag }} ARCH=${ARCH} env: - RETRIES: 20 - PAUSE: 10 + ARCH: ${{ matrix.arch }} + # https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#functions + if: github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id + && ( + (github.event_name == 'schedule' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) + || + (github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) + || + (github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release-')) + ) + + # ----------------------------------------------------------------------------------------------- + # Job (2/2): DEPLOY + # ----------------------------------------------------------------------------------------------- + deploy: + needs: [build] + name: Deploy + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: + - 'Apache 2.2' + steps: + + # ------------------------------------------------------------ + # Setup repository + # ------------------------------------------------------------ + - name: "[SETUP] Checkout repository" + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: "[SETUP] Determine Docker tag" + id: tag + uses: cytopia/docker-tag@v0.3 + + # ------------------------------------------------------------ + # Deploy + # ------------------------------------------------------------ + - name: "[DEPLOY] Login" + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: "[DEPLOY] Create Docker manifest" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make manifest-create TAG=${{ steps.tag.outputs.docker-tag }} ARCH="linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6" + + - name: "[DEPLOY] Publish Docker manifest (only repo owner)" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make manifest-push TAG=${{ steps.tag.outputs.docker-tag }} # https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#functions if: github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id && ( diff --git a/.github/workflows/contributor.yml b/.github/workflows/contributor.yml new file mode 100644 index 0000000..2fca58f --- /dev/null +++ b/.github/workflows/contributor.yml @@ -0,0 +1,86 @@ +--- + +# ------------------------------------------------------------------------------------------------- +# Job Name +# ------------------------------------------------------------------------------------------------- +name: build + + +# ------------------------------------------------------------------------------------------------- +# When to run +# ------------------------------------------------------------------------------------------------- +on: + # Runs on Pull Requests + pull_request: + + +jobs: + + # ----------------------------------------------------------------------------------------------- + # Job (1/2): BUILD + # ----------------------------------------------------------------------------------------------- + build: + name: "[ ${{ matrix.version }} (${{ matrix.arch }}) ]" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: + - 'Apache 2.2' + arch: + - 'linux/amd64' + - 'linux/arm64' + - 'linux/386' + - 'linux/arm/v7' + - 'linux/arm/v6' + # Only run for forks (contributor) + if: ${{ github.event.pull_request.head.repo.fork }} + steps: + + # ------------------------------------------------------------ + # Setup repository + # ------------------------------------------------------------ + - name: "[SETUP] Checkout repository" + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: "[SETUP] Setup QEMU environment" + uses: docker/setup-qemu-action@v1 + with: + image: tonistiigi/binfmt:latest + platforms: all + + - name: "[SETUP] Determine Docker tag" + id: tag + uses: cytopia/docker-tag@v0.3 + + # ------------------------------------------------------------ + # Build + # ------------------------------------------------------------ + - name: Build + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make build ARCH=${ARCH} + env: + ARCH: ${{ matrix.arch }} + + # ------------------------------------------------------------ + # Test + # ------------------------------------------------------------ + - name: "[TEST] Docker Image" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make test ARCH=${ARCH} + env: + ARCH: ${{ matrix.arch }} + + - name: "[TEST] Update README" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make update-readme ARCH=${ARCH} + env: + ARCH: ${{ matrix.arch }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5290e4c..57a401b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -34,5 +34,6 @@ jobs: # Lint repository # ------------------------------------------------------------ - name: Lint workflow + id: vars run: | make lint-workflow diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 8858bb4..9641598 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -15,149 +15,155 @@ on: - cron: '0 0 * * *' -# ------------------------------------------------------------------------------------------------- -# What to run -# ------------------------------------------------------------------------------------------------- jobs: - nightly: - name: "[ HTTPD ] (ref: ${{ matrix.refs }})" + + # ----------------------------------------------------------------------------------------------- + # Job: BUILD + # ----------------------------------------------------------------------------------------------- + build: + name: "[ ${{ matrix.version }} (${{ matrix.arch }}) ] (ref: ${{ matrix.refs }})" runs-on: ubuntu-latest strategy: - fail-fast: False + fail-fast: false matrix: + version: + - 'Apache 2.2' + arch: + - 'linux/amd64' + - 'linux/arm64' + - 'linux/386' + - 'linux/arm/v7' + - 'linux/arm/v6' refs: - 'master' - - '0.39' + - '0.40' steps: # ------------------------------------------------------------ # Setup repository # ------------------------------------------------------------ - - name: Checkout repository + - name: "[SETUP] Checkout repository" uses: actions/checkout@v2 with: fetch-depth: 0 ref: ${{ matrix.refs }} - - name: Set variables - id: vars - run: | - - # Retrieve git info (tags, etc) - git fetch --all - - # Branch, Tag or Commit - GIT_TYPE="$( \ - curl -sS https://raw.githubusercontent.com/cytopia/git-tools/master/git-info.sh \ - | sh \ - | grep '^GIT_TYPE' \ - | sed 's|.*=||g' \ - )" - # Branch name, Tag name or Commit Hash - GIT_SLUG="$( \ - curl -sS https://raw.githubusercontent.com/cytopia/git-tools/master/git-info.sh \ - | sh \ - | grep '^GIT_NAME' \ - | sed 's|.*=||g' \ - )" - # Docker Tag - if [ "${GIT_TYPE}" = "BRANCH" ] && [ "${GIT_SLUG}" = "master" ]; then - DOCKER_TAG="latest" - else - DOCKER_TAG="${GIT_SLUG}" - fi - - # Output - echo "GIT_TYPE=${GIT_TYPE}" - echo "GIT_SLUG=${GIT_SLUG}" - echo "DOCKER_TAG=${DOCKER_TAG}" - - # Export variable - # https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#environment-files - echo "GIT_TYPE=${GIT_TYPE}" >> ${GITHUB_ENV} - echo "GIT_SLUG=${GIT_SLUG}" >> ${GITHUB_ENV} - echo "DOCKER_TAG=${DOCKER_TAG}" >> ${GITHUB_ENV} + - name: "[SETUP] Setup QEMU environment" + uses: docker/setup-qemu-action@v1 + with: + image: tonistiigi/binfmt:latest + platforms: all + - name: "[SETUP] Determine Docker tag" + id: tag + uses: cytopia/docker-tag@v0.3 # ------------------------------------------------------------ # Build # ------------------------------------------------------------ - name: Build - run: | - retry() { - for n in $(seq ${RETRIES}); do - echo "[${n}/${RETRIES}] ${*}"; - if eval "${*}"; then - echo "[SUCC] ${n}/${RETRIES}"; - return 0; - fi; - sleep ${PAUSE}; - echo "[FAIL] ${n}/${RETRIES}"; - done; - return 1; - } - retry make build + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make build ARCH=${ARCH} env: - RETRIES: 20 - PAUSE: 10 + ARCH: ${{ matrix.arch }} # ------------------------------------------------------------ # Test # ------------------------------------------------------------ - - name: Test Docker Image - run: | - retry() { - for n in $(seq ${RETRIES}); do - echo "[${n}/${RETRIES}] ${*}"; - if eval "${*}"; then - echo "[SUCC] ${n}/${RETRIES}"; - return 0; - fi; - sleep ${PAUSE}; - echo "[FAIL] ${n}/${RETRIES}"; - done; - return 1; - } - retry make test + - name: "[TEST] Docker Image" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make test ARCH=${ARCH} env: - RETRIES: 20 - PAUSE: 10 + ARCH: ${{ matrix.arch }} + - name: "[TEST] Update README" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make update-readme ARCH=${ARCH} + env: + ARCH: ${{ matrix.arch }} # ------------------------------------------------------------ # Deploy # ------------------------------------------------------------ - - name: Publish images (only repo owner) - run: | - retry() { - for n in $(seq ${RETRIES}); do - echo "[${n}/${RETRIES}] ${*}"; - if eval "${*}"; then - echo "[SUCC] ${n}/${RETRIES}"; - return 0; - fi; - sleep ${PAUSE}; - echo "[FAIL] ${n}/${RETRIES}"; - done; - return 1; - } - - # Output - echo "GIT_TYPE=${GIT_TYPE}" - echo "GIT_SLUG=${GIT_SLUG}" - echo "DOCKER_TAG=${DOCKER_TAG}" - - # Tag image - retry make tag TAG=${DOCKER_TAG} - docker images - - # Login and Push - retry make login USER=${{ secrets.DOCKERHUB_USERNAME }} PASS=${{ secrets.DOCKERHUB_PASSWORD }} - retry make push TAG=${DOCKER_TAG} + - name: "[DEPLOY] Login" + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + - name: "[DEPLOY] Publish architecture image (only repo owner)" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make push-arch TAG=${{ steps.tag.outputs.docker-tag }} ARCH=${ARCH} env: - RETRIES: 20 - PAUSE: 10 + ARCH: ${{ matrix.arch }} + # https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#functions + if: github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id + && ( + (github.event_name == 'schedule' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) + || + (github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))) + || + (github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release-')) + ) + + # ----------------------------------------------------------------------------------------------- + # Job (2/2): DEPLOY + # ----------------------------------------------------------------------------------------------- + deploy: + needs: [build] + name: "[ Deploy (ref: ${{ matrix.refs }})" + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: + - 'Apache 2.2' + refs: + - 'master' + - '0.40' + steps: + + # ------------------------------------------------------------ + # Setup repository + # ------------------------------------------------------------ + - name: "[SETUP] Checkout repository" + uses: actions/checkout@v2 + with: + fetch-depth: 0 + ref: ${{ matrix.refs }} + + - name: "[SETUP] Determine Docker tag" + id: tag + uses: cytopia/docker-tag@v0.3 + + # ------------------------------------------------------------ + # Deploy + # ------------------------------------------------------------ + - name: "[DEPLOY] Login" + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: "[DEPLOY] Create Docker manifest" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make manifest-create TAG=${{ steps.tag.outputs.docker-tag }} ARCH="linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6" + + - name: "[DEPLOY] Publish Docker manifest (only repo owner)" + uses: cytopia/shell-command-retry-action@v0.1 + with: + command: | + make manifest-push TAG=${{ steps.tag.outputs.docker-tag }} # https://help.github.com/en/github/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#functions if: github.event.pull_request.base.repo.id == github.event.pull_request.head.repo.id && ( diff --git a/Dockerfile b/Dockerfile index f0a9ef0..a692196 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,8 +43,8 @@ ENV HTTPD_RELOAD="/usr/local/apache2/bin/httpd -k stop" RUN set -x \ && rm -f /etc/apt/sources.list \ && { \ - echo "deb http://ftp.debian.org/debian jessie main"; \ - echo "deb http://security.debian.org/debian-security jessie/updates main"; \ + echo "deb http://deb.debian.org/debian/ stretch main"; \ + echo "deb http://security.debian.org/debian-security stretch/updates main"; \ } | tee /etc/apt/sources.list \ && apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y \ diff --git a/Makefile b/Makefile index e0d25ec..dff60a5 100644 --- a/Makefile +++ b/Makefile @@ -7,20 +7,30 @@ endif # Docker configuration # ------------------------------------------------------------------------------------------------- +DIR = . +FILE = Dockerfile IMAGE = devilbox/apache-2.2 TAG = latest +ARCH = linux/amd64 +NO_CACHE = # ------------------------------------------------------------------------------------------------- # Default Target # ------------------------------------------------------------------------------------------------- - +.PHONY: help help: @echo "lint Lint project files and repository" + @echo @echo "build Build Docker image" @echo "rebuild Build Docker image without cache" + @echo + @echo "manifest-create Create multi-arch manifest" + @echo "manifest-push Push multi-arch manifest" + @echo @echo "test Test built Docker image" @echo "update-readme Update README.md with PHP modules" + @echo @echo "tag [TAG=...] Retag Docker image" @echo "login USER=... PASS=... Login to Docker hub" @echo "push [TAG=...] Push Docker image to Docker hub" @@ -29,65 +39,101 @@ help: # ------------------------------------------------------------------------------------------------- # Lint Targets # ------------------------------------------------------------------------------------------------- - +.PHONY: lint lint: lint-workflow +.PHONY: lint-workflow lint-workflow: @\ GIT_CURR_MAJOR="$$( git tag | sort -V | tail -1 | sed 's|\.[0-9]*$$||g' )"; \ GIT_CURR_MINOR="$$( git tag | sort -V | tail -1 | sed 's|^[0-9]*\.||g' )"; \ GIT_NEXT_TAG="$${GIT_CURR_MAJOR}.$$(( GIT_CURR_MINOR + 1 ))"; \ - if ! grep 'refs:' -A 100 .github/workflows/nightly.yml \ - | grep " - '$${GIT_NEXT_TAG}'" >/dev/null; then \ - echo "[ERR] New Tag required in .github/workflows/nightly.yml: $${GIT_NEXT_TAG}"; \ - exit 1; \ - else \ - echo "[OK] Git Tag present in .github/workflows/nightly.yml: $${GIT_NEXT_TAG}"; \ - fi + grep 'refs:' -A 20 .github/workflows/nightly.yml \ + | grep '^ -' \ + | grep -v master \ + | while read -r i; do \ + if ! echo "$${i}" | grep -- "- '$${GIT_NEXT_TAG}'" >/dev/null; then \ + echo "[ERR] New Tag required in .github/workflows/nightly.yml: $${GIT_NEXT_TAG}"; \ + exit 1; \ + else \ + echo "[OK] Git Tag present in .github/workflows/nightly.yml: $${GIT_NEXT_TAG}"; \ + fi \ + done # ------------------------------------------------------------------------------------------------- # Build Targets # ------------------------------------------------------------------------------------------------- +.PHONY: build +build: + docker build --platform=$(ARCH) $(NO_CACHE) -t $(IMAGE) -f $(DIR)/$(FILE) $(DIR) + ./build/gen-readme.sh $(IMAGE) $(ARCH) -build: pull-base-image - docker build -t $(IMAGE) . - ./build/gen-readme.sh $(IMAGE) - +.PHONY: rebuild +rebuild: NO_CACHE=--no-cache rebuild: pull-base-image - docker build --no-cache -t $(IMAGE) . - ./build/gen-readme.sh $(IMAGE) +rebuild: build # ------------------------------------------------------------------------------------------------- -# Test Targets +# Manifest Targets # ------------------------------------------------------------------------------------------------- +.PHONY: manifest-create +manifest-create: + @echo "docker manifest create \ + $(IMAGE):$(TAG) \ + $$( echo $(ARCH) | sed 's/,/ /g' | sed 's|/|-|g' | xargs -n1 sh -c 'printf -- " --amend $(IMAGE):$(TAG)-manifest-$${1}"' -- )" \ + | sed 's/\s\s*/ /g' \ + | sed 's/--/\\\n --/g' + @echo "docker manifest create \ + $(IMAGE):$(TAG) \ + $$( echo $(ARCH) | sed 's/,/ /g' | sed 's|/|-|g' | xargs -n1 sh -c 'printf -- " --amend $(IMAGE):$(TAG)-manifest-$${1}"' -- )" \ + | bash + +.PHONY: manifest-push +manifest-push: + docker manifest push $(IMAGE):$(TAG) + +# ------------------------------------------------------------------------------------------------- +# Test Targets +# ------------------------------------------------------------------------------------------------- +.PHONY: test test: - .ci/start-ci.sh $(IMAGE) $(ARG) + ./tests/start-ci.sh $(IMAGE) $(ARCH) +.PHONY: update-readme + ./build/gen-readme.sh $(IMAGE) $(ARCH) # ------------------------------------------------------------------------------------------------- # Deploy Targets # ------------------------------------------------------------------------------------------------- - +.PHONY: tag tag: docker tag $(IMAGE) $(IMAGE):$(TAG) +.PHONY: login login: yes | docker login --username $(USER) --password $(PASS) +.PHONY: push push: @$(MAKE) tag TAG=$(TAG) docker push $(IMAGE):$(TAG) +.PHONY: push-arch +push-arch: + $(MAKE) tag TAG=$(TAG)-manifest-$(subst /,-,$(ARCH)) + docker push $(IMAGE):$(TAG)-manifest-$(subst /,-,$(ARCH)) + # ------------------------------------------------------------------------------------------------- # Helper Targets # ------------------------------------------------------------------------------------------------- - +.PHONY: enter enter: - docker run --rm --name $(subst /,-,$(IMAGE)) -it --entrypoint=bash $(ARG) $(IMAGE) + docker run --rm --platform=$(ARCH) -it --entrypoint=bash $(ARG) $(IMAGE) +.PHONY: pull-base-image pull-base-image: @docker pull $(shell grep FROM Dockerfile | sed 's/^FROM\s*//g';) diff --git a/README.md b/README.md index 6057a8a..111fcf9 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ **[devilbox/docker-apache-2.2](https://github.com/devilbox/docker-apache-2.2)** +**Available Architectures:** `amd64`, `arm64`, `386`, `arm/v7`, `arm/v6` + This image is based on the official **[Apache 2.2](https://hub.docker.com/_/httpd)** Docker image and extends it with the ability to have **virtual hosts created automatically**, as well as **adding SSL certificates** when creating new directories. For that to work, it integrates two tools that will take care about the whole process: **[watcherd](https://github.com/devilbox/watcherd)** and **[vhost-gen](https://github.com/devilbox/vhost-gen)**. From a users perspective, you mount your local project directory into the container under `/shared/httpd`. Any directory then created in your local project directory wil spawn a new virtual host by the same name. Additional settings such as custom server names, PHP-FPM or even different Apache templates per project are supported as well. @@ -261,32 +263,11 @@ It allows any of the following combinations: ## Version ``` -Server version: Apache/2.2.34 (Unix) -Server built: Jan 18 2018 23:12:10 -Server's Module Magic Number: 20051115:43 -Server loaded: APR 1.5.1, APR-Util 1.5.4 -Compiled using: APR 1.5.1, APR-Util 1.5.4 -Architecture: 64-bit -Server MPM: Prefork - threaded: no - forked: yes (variable process count) -Server compiled with.... - -D APACHE_MPM_DIR="server/mpm/prefork" - -D APR_HAS_SENDFILE - -D APR_HAS_MMAP - -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) - -D APR_USE_SYSVSEM_SERIALIZE - -D APR_USE_PTHREAD_SERIALIZE - -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT - -D APR_HAS_OTHER_CHILD - -D AP_HAVE_RELIABLE_PIPED_LOGS - -D DYNAMIC_MODULE_LIMIT=128 - -D HTTPD_ROOT="/usr/local/apache2" - -D SUEXEC_BIN="/usr/local/apache2/bin/suexec" - -D DEFAULT_PIDLOG="logs/httpd.pid" - -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" - -D DEFAULT_LOCKFILE="logs/accept.lock" - -D DEFAULT_ERRORLOG="logs/error_log" - -D AP_TYPES_CONFIG_FILE="conf/mime.types" - -D SERVER_CONFIG_FILE="conf/httpd.conf" +Unable to find image 'devilbox/apache-2.2:latest' locally +latest: Pulling from devilbox/apache-2.2 +Digest: sha256:cfccd4377265ca0cfea871c192c7d5db2763c176c7550b1d20c6fbd963bb6d3e +Status: Downloaded newer image for devilbox/apache-2.2:latest +WARNING: image with reference devilbox/apache-2.2 was found but does not match the specified platform: wanted linux/arm64, actual: linux/amd64 +docker: Error response from daemon: image with reference devilbox/apache-2.2 was found but does not match the specified platform: wanted linux/arm64, actual: linux/amd64. +See 'docker run --help'. ``` diff --git a/build/gen-readme.sh b/build/gen-readme.sh index 9229ba1..ed5660b 100755 --- a/build/gen-readme.sh +++ b/build/gen-readme.sh @@ -6,11 +6,12 @@ ### CWD="$(cd -P -- "$(dirname -- "$0")" && pwd -P)/.." IMAGE="${1}" +ARCH="${2}" ### ### Retrieve information afterwards and Update README.md ### -INFO="$( docker run --rm --entrypoint=httpd "${IMAGE}" -V 2>&1 | tr -d '\r' )" +INFO="$( docker run --rm --platform "${ARCH}" --entrypoint=httpd "${IMAGE}" -V 2>&1 | tr -d '\r' )" echo "${INFO}" sed -i'' '/##[[:space:]]Version/q' "${CWD}/README.md" diff --git a/.ci/.lib.sh b/tests/.lib.sh similarity index 100% rename from .ci/.lib.sh rename to tests/.lib.sh diff --git a/.ci/00.sh b/tests/00.sh similarity index 93% rename from .ci/00.sh rename to tests/00.sh index 83d1db1..cc32977 100755 --- a/.ci/00.sh +++ b/tests/00.sh @@ -6,6 +6,7 @@ set -o pipefail CWD="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" DOCKER_NAME="${1}" +ARCH="${2}" ### @@ -27,7 +28,7 @@ run "echo \"hello world\" > ${RAND_DIR}/index.html" ### ### Startup container ### -run "docker run -d --rm \ +run "docker run -d --rm --platform ${ARCH} \ -v ${RAND_DIR}:/var/www/default/htdocs \ -p 127.0.0.1:80:80 \ -e DEBUG_ENTRYPOINT=2 \ diff --git a/.ci/01.sh b/tests/01.sh similarity index 86% rename from .ci/01.sh rename to tests/01.sh index 53b7ba3..5f42877 100755 --- a/.ci/01.sh +++ b/tests/01.sh @@ -6,6 +6,7 @@ set -o pipefail CWD="$(cd -P -- "$(dirname -- "$0")" && pwd -P)" DOCKER_NAME="${1}" +ARCH="${2}" ### @@ -25,23 +26,17 @@ RAND_NAME2="$( get_random_name )" run "echo \" ${RAND_DIR}/index.php" -### -### Build container -### -run "docker build -t ${DOCKER_NAME} ${CWD}/.." - - ### ### Startup container ### -run "docker run -d --rm \ +run "docker run -d --rm --platform ${ARCH} \ -v ${RAND_DIR}:/var/www/default/htdocs \ -e DEBUG_ENTRYPOINT=1 \ -e NEW_UID=$( id -u ) \ -e NEW_GID=$( id -g ) \ - --name ${RAND_NAME1} cytopia/php-fpm-5.6" + --name ${RAND_NAME1} devilbox/php-fpm-8.1" -run "docker run -d --rm \ +run "docker run -d --rm --platform ${ARCH} \ -v ${RAND_DIR}:/var/www/default/htdocs \ -p 127.0.0.1:80:80 \ -e DEBUG_ENTRYPOINT=2 \ diff --git a/.ci/start-ci.sh b/tests/start-ci.sh similarity index 59% rename from .ci/start-ci.sh rename to tests/start-ci.sh index 647b208..959fbcf 100755 --- a/.ci/start-ci.sh +++ b/tests/start-ci.sh @@ -13,6 +13,7 @@ IFS=$'\n' # Current directory CWD="$( dirname "${0}" )" IMAGE="${1}" +ARCH="${2:-linux/amd64}" declare -a TESTS=() @@ -22,19 +23,19 @@ declare -a TESTS=() ### # Get all [0-9]+.sh test files -FILES="$( find ${CWD} -regex "${CWD}/[0-9].+\.sh" | sort -u )" +FILES="$( find "${CWD}" -regex "${CWD}/[0-9].+\.sh" | sort -u )" for f in ${FILES}; do TESTS+=("${f}") done # Start a single test -if [ "${#}" -eq "2" ]; then - sh -c "${TESTS[${2}]} ${IMAGE}" +if [ "${#}" -eq "3" ]; then + sh -c "${TESTS[${2}]} ${IMAGE} ${ARCH}" # Run all tests else for i in "${TESTS[@]}"; do - echo "sh -c ${CWD}/${i} ${IMAGE}" - sh -c "${i} ${IMAGE}" + echo "sh -c ${CWD}/${i} ${IMAGE} ${ARCH}" + sh -c "${i} ${IMAGE} ${ARCH}" done fi From d01a8d05b08a4d97ed08d7842719daf13aea8e04 Mon Sep 17 00:00:00 2001 From: cytopia Date: Sun, 13 Feb 2022 14:08:45 +0100 Subject: [PATCH 2/5] Fix tests --- README.md | 35 ++++++++++++++++++++++++++++------- tests/01.sh | 4 +--- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 111fcf9..cd3a055 100644 --- a/README.md +++ b/README.md @@ -263,11 +263,32 @@ It allows any of the following combinations: ## Version ``` -Unable to find image 'devilbox/apache-2.2:latest' locally -latest: Pulling from devilbox/apache-2.2 -Digest: sha256:cfccd4377265ca0cfea871c192c7d5db2763c176c7550b1d20c6fbd963bb6d3e -Status: Downloaded newer image for devilbox/apache-2.2:latest -WARNING: image with reference devilbox/apache-2.2 was found but does not match the specified platform: wanted linux/arm64, actual: linux/amd64 -docker: Error response from daemon: image with reference devilbox/apache-2.2 was found but does not match the specified platform: wanted linux/arm64, actual: linux/amd64. -See 'docker run --help'. +Server version: Apache/2.2.34 (Unix) +Server built: Jan 18 2018 23:12:10 +Server's Module Magic Number: 20051115:43 +Server loaded: APR 1.5.1, APR-Util 1.5.4 +Compiled using: APR 1.5.1, APR-Util 1.5.4 +Architecture: 64-bit +Server MPM: Prefork + threaded: no + forked: yes (variable process count) +Server compiled with.... + -D APACHE_MPM_DIR="server/mpm/prefork" + -D APR_HAS_SENDFILE + -D APR_HAS_MMAP + -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) + -D APR_USE_SYSVSEM_SERIALIZE + -D APR_USE_PTHREAD_SERIALIZE + -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT + -D APR_HAS_OTHER_CHILD + -D AP_HAVE_RELIABLE_PIPED_LOGS + -D DYNAMIC_MODULE_LIMIT=128 + -D HTTPD_ROOT="/usr/local/apache2" + -D SUEXEC_BIN="/usr/local/apache2/bin/suexec" + -D DEFAULT_PIDLOG="logs/httpd.pid" + -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" + -D DEFAULT_LOCKFILE="logs/accept.lock" + -D DEFAULT_ERRORLOG="logs/error_log" + -D AP_TYPES_CONFIG_FILE="conf/mime.types" + -D SERVER_CONFIG_FILE="conf/httpd.conf" ``` diff --git a/tests/01.sh b/tests/01.sh index 5f42877..792e268 100755 --- a/tests/01.sh +++ b/tests/01.sh @@ -23,6 +23,7 @@ ARCH="${2}" RAND_DIR="$( mktemp -d )" RAND_NAME1="$( get_random_name )" RAND_NAME2="$( get_random_name )" +run "chmod 0755 ${RAND_DIR}" run "echo \" ${RAND_DIR}/index.php" @@ -31,9 +32,6 @@ run "echo \" ${RAND_DIR}/index.php" ### run "docker run -d --rm --platform ${ARCH} \ -v ${RAND_DIR}:/var/www/default/htdocs \ - -e DEBUG_ENTRYPOINT=1 \ - -e NEW_UID=$( id -u ) \ - -e NEW_GID=$( id -g ) \ --name ${RAND_NAME1} devilbox/php-fpm-8.1" run "docker run -d --rm --platform ${ARCH} \ From a8a131852fad1babe4e9fd4fe8f977a8312134bb Mon Sep 17 00:00:00 2001 From: cytopia Date: Sun, 13 Feb 2022 14:25:34 +0100 Subject: [PATCH 3/5] Increase test waiting time --- tests/00.sh | 2 +- tests/01.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/00.sh b/tests/00.sh index cc32977..f3692d0 100755 --- a/tests/00.sh +++ b/tests/00.sh @@ -41,7 +41,7 @@ run "docker run -d --rm --platform ${ARCH} \ ### ### Tests ### -run "sleep 5" +run "sleep 20" # Startup-time is longer on cross-platform run "docker ps" run "docker logs ${RAND_NAME}" run "curl -sS localhost/index.html" diff --git a/tests/01.sh b/tests/01.sh index 792e268..463d5e0 100755 --- a/tests/01.sh +++ b/tests/01.sh @@ -51,7 +51,7 @@ run "docker run -d --rm --platform ${ARCH} \ ### ### Tests ### -run "sleep 5" +run "sleep 20" # Startup-time is longer on cross-platform run "docker ps" run "docker logs ${RAND_NAME1}" run "docker logs ${RAND_NAME2}" From dad98331576c9d60e8a23dc086850a14f8c12646 Mon Sep 17 00:00:00 2001 From: cytopia Date: Sun, 13 Feb 2022 15:12:24 +0100 Subject: [PATCH 4/5] Fixing i386 builds --- Dockerfile | 16 +++++++++++----- Makefile | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index a692196..c95cc8e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,7 @@ LABEL \ ARG VHOST_GEN_GIT_REF=1.0.3 ARG WATCHERD_GIT_REF=v1.0.2 ARG CERT_GEN_GIT_REF=0.7 +ARG ARCH ENV BUILD_DEPS \ autoconf \ @@ -36,11 +37,10 @@ ENV MY_GROUP=daemon ENV HTTPD_START="httpd-foreground" ENV HTTPD_RELOAD="/usr/local/apache2/bin/httpd -k stop" - ### ### Install required packages ### -RUN set -x \ +RUN set -eux \ && rm -f /etc/apt/sources.list \ && { \ echo "deb http://deb.debian.org/debian/ stretch main"; \ @@ -51,6 +51,12 @@ RUN set -x \ ${BUILD_DEPS} \ ${RUN_DEPS} \ \ + # Required symlinks to build mod-proxy-fcgi on i386 + && if [ "${ARCH}" = "linux/386" ]; then \ + ln -s $(which ar) /usr/bin/i586-linux-gnu-ar; \ + ln -s $(which ranlib) /usr/bin/i586-linux-gnu-ranlib ; \ + fi \ + \ # mod-proxy-fcgi && wget --no-check-certificate -O mod-proxy-fcgi.tar.gz https://github.com/devilbox/mod-proxy-fcgi/archive/master.tar.gz \ && tar xvfz mod-proxy-fcgi.tar.gz \ @@ -81,7 +87,7 @@ RUN set -x \ && chmod +x /usr/bin/watcherd \ \ # Clean-up - && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps \ + && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ ${BUILD_DEPS} \ && rm -rf /var/lib/apt/lists/* @@ -89,7 +95,7 @@ RUN set -x \ ### ### Configure Apache ### -RUN set -x \ +RUN set -eux \ && ( \ echo "ServerName localhost"; \ echo "LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so"; \ @@ -119,7 +125,7 @@ RUN set -x \ ### ### Create directories ### -RUN set -x \ +RUN set -eux \ && mkdir -p /etc/httpd-custom.d \ && mkdir -p /etc/httpd/conf.d \ && mkdir -p /etc/httpd/vhost.d \ diff --git a/Makefile b/Makefile index dff60a5..67551eb 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ lint-workflow: # ------------------------------------------------------------------------------------------------- .PHONY: build build: - docker build --platform=$(ARCH) $(NO_CACHE) -t $(IMAGE) -f $(DIR)/$(FILE) $(DIR) + docker build --platform=$(ARCH) $(NO_CACHE) --build-arg ARCH=$(ARCH) -t $(IMAGE) -f $(DIR)/$(FILE) $(DIR) ./build/gen-readme.sh $(IMAGE) $(ARCH) .PHONY: rebuild From 029c526a323249e49361bae877f7f025113b1849 Mon Sep 17 00:00:00 2001 From: cytopia Date: Sun, 13 Feb 2022 15:28:53 +0100 Subject: [PATCH 5/5] Fix vhost-gen install on old arm platforms --- Dockerfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index c95cc8e..2f17183 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,6 @@ ARG ARCH ENV BUILD_DEPS \ autoconf \ gcc \ - git \ make \ wget @@ -69,9 +68,9 @@ RUN set -eux \ && rm -rf mod-proxy-fcgi* \ \ # Install vhost-gen - && git clone https://github.com/devilbox/vhost-gen \ - && cd vhost-gen \ - && git checkout "${VHOST_GEN_GIT_REF}" \ + && wget --no-check-certificate -O vhost-gen.tar.gz "https://github.com/devilbox/vhost-gen/archive/refs/tags/${VHOST_GEN_GIT_REF}.tar.gz" \ + && tar xvfz vhost-gen.tar.gz \ + && cd "vhost-gen-${VHOST_GEN_GIT_REF}" \ && make install \ && cd .. \ && rm -rf vhost*gen* \