diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..367f341 --- /dev/null +++ b/.gitignore @@ -0,0 +1,151 @@ +# enviroment to load on bin/build +env + +# where souce code is clone with git +clone + +# where tools command are found +tools + +# where pipeline templates are found +templates + +# OSX leaves these everywhere on SMB shares +._* + +# OSX trash +.DS_Store + +# Eclipse files +.classpath +.project +.settings/** + +# Files generated by JetBrains IDEs, e.g. IntelliJ IDEA +.idea/ +*.iml + +# Vscode files +.vscode + +# This is where the result of the go build goes +/output*/ +/_output*/ +/_output + +# Emacs save files +*~ +\#*\# +.\#* + +# Vim-related files +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist + +# cscope-related files +cscope.* + +# Go test binaries +*.test +/hack/.test-cmd-auth + +# JUnit test output from ginkgo e2e tests +/junit*.xml + +# Mercurial files +**/.hg +**/.hg* + +# Vagrant +.vagrant +network_closure.sh + +# Local cluster env variables +/cluster/env.sh + +# Compiled binaries in third_party +/third_party/pkg + +# Also ignore etcd installed by hack/install-etcd.sh +/third_party/etcd* +/default.etcd + +# User cluster configs +.kubeconfig + +.tags* + +# Version file for dockerized build +.dockerized-kube-version-defs + +# Web UI +/www/master/node_modules/ +/www/master/npm-debug.log +/www/master/shared/config/development.json + +# Karma output +/www/test_out + +# precommit temporary directories created by ./hack/verify-generated-docs.sh and ./hack/lib/util.sh +/_tmp/ +/doc_tmp/ + +# Test artifacts produced by Jenkins jobs +/_artifacts/ + +# Go dependencies installed on Jenkins +/_gopath/ + +# Config directories created by gcloud and gsutil on Jenkins +/.config/gcloud*/ +/.gsutil/ + +# CoreOS stuff +/cluster/libvirt-coreos/coreos_*.img + +# Juju Stuff +/cluster/juju/charms/* +/cluster/juju/bundles/local.yaml + +# Downloaded Kubernetes binary release +/kubernetes/ + +# direnv .envrc files +.envrc + +# Downloaded kubernetes binary release tar ball +kubernetes.tar.gz + +# generated files in any directory +# TODO(thockin): uncomment this when we stop committing the generated files. +#zz_generated.* +zz_generated.openapi.go +zz_generated_*_test.go + +# TODO(roycaihw): remove this when we stop committing the generated definition +!staging/src/k8s.io/apiextensions-apiserver/pkg/generated/openapi/zz_generated.openapi.go +# low-change blueprint in code-generator to notice changes +!staging/src/k8s.io/code-generator/_examples/apiserver/openapi/zz_generated.openapi.go +# low-change sample-apiserver spec to be compilable when published +!staging/src/k8s.io/sample-apiserver/pkg/generated/openapi/zz_generated.openapi.go + +# make-related metadata +/.make/ + +# Just in time generated data in the source, should never be committed +/test/e2e/generated/bindata.go + +# This file used by some vendor repos (e.g. github.com/go-openapi/...) to store secret variables and should not be ignored +!\.drone\.sec + +# Godeps workspace +/Godeps/_workspace + +/bazel-* +*.pyc + +# generated by verify-vendor.sh +vendordiff.patch diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/pipeline/PersistentVolumeCDCI.yaml b/pipeline/PersistentVolumeCDCI.yaml new file mode 100644 index 0000000..8e15ed1 --- /dev/null +++ b/pipeline/PersistentVolumeCDCI.yaml @@ -0,0 +1,29 @@ +kind: PersistentVolume +apiVersion: v1 +metadata: + name: cdci-apache-php-pvc-volume + namespace: cdci-librecloud-online + labels: + type: local +spec: + storageClassName: manual + persistentVolumeReclaimPolicy: Delete + capacity: + storage: 1Gi + accessModes: + - ReadWriteOnce + hostPath: + path: "/mnt/cdci" +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: cdci-apache-php-pvc + namespace: cdci-librecloud-online +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi diff --git a/pipeline/down.sh b/pipeline/down.sh new file mode 100755 index 0000000..28f48ff --- /dev/null +++ b/pipeline/down.sh @@ -0,0 +1,6 @@ +#/bin/bash +kubectl delete -f pipeline-run.yaml 2>/dev/null +kubectl delete -f pipeline.yaml 2>/dev/null +kubectl delete -f task.yaml 2>/dev/null +kubectl delete -f PersistentVolumeCDCI.yaml 2>/dev/null +kubectl delete -f pipe-resource.yaml 2>/dev/null diff --git a/pipeline/pipe-resource.yaml b/pipeline/pipe-resource.yaml new file mode 100644 index 0000000..a14cf87 --- /dev/null +++ b/pipeline/pipe-resource.yaml @@ -0,0 +1,24 @@ +apiVersion: tekton.dev/v1alpha1 +kind: PipelineResource +metadata: + name: librecloud-apache-php-img + namespace: cdci-librecloud-online +spec: + type: image + params: + - name: url + value: termas.librecloud.online/termas_librecloud/apache-php:8.1 +--- +apiVersion: tekton.dev/v1alpha1 +kind: PipelineResource +metadata: + name: librecloud-apache-php-git + namespace: cdci-librecloud-online +spec: + type: git + params: + - name: revision + value: master + - name: url + value: https://rlung.librecloud.online/Termas_LibreCloud/apache-php.git + diff --git a/pipeline/pipeline-run.yaml b/pipeline/pipeline-run.yaml new file mode 100644 index 0000000..0f48953 --- /dev/null +++ b/pipeline/pipeline-run.yaml @@ -0,0 +1,22 @@ +apiVersion: tekton.dev/v1alpha1 +kind: PipelineRun +metadata: + name: cdci-apache-php + namespace: cdci-librecloud-online +spec: + serviceAccountName: build-bot + pipelineRef: + name: cdci-apache-php + # podTemplate: + #volumes: + #- name: cdci-volume + # #emptyDir: {} + # persistentVolumeClaim: + # claimName: cdci-apache-php-pvc + resources: + - name: source-repo + resourceRef: + name: librecloud-apache-php-git + - name: target-image + resourceRef: + name: librecloud-apache-php-img diff --git a/pipeline/pipeline.yaml b/pipeline/pipeline.yaml new file mode 100644 index 0000000..3eb05ca --- /dev/null +++ b/pipeline/pipeline.yaml @@ -0,0 +1,32 @@ +apiVersion: tekton.dev/v1alpha1 +kind: Pipeline +metadata: + name: cdci-apache-php + namespace: cdci-librecloud-online +spec: + #serviceAccount: build-bot + resources: + - name: source-repo + type: git + #resourceRef: + # name: librecloud-apache-php-git + - name: target-image + type: image + #resourceRef: + # name: librecloud-apache-php-img + tasks: + - name: build-apache-php-img + taskRef: + name: apache-php-build-image-from-git-source + params: + - name: pathToDockerFile + value: /workspace/source/src + - name: pathToContext + value: /workspace/source/src #configure: may change according to your source + resources: + inputs: + - name: source + resource: source-repo + outputs: + - name: builtImage + resource: target-image diff --git a/pipeline/task.yaml b/pipeline/task.yaml new file mode 100644 index 0000000..8b3fadf --- /dev/null +++ b/pipeline/task.yaml @@ -0,0 +1,91 @@ +apiVersion: tekton.dev/v1alpha1 +kind: Task +metadata: + name: apache-php-build-image-from-git-source + namespace: cdci-librecloud-online +spec: + #serviceAccount: build-bot + inputs: + params: + - name: pathToDockerFile + type: string + description: The path to the dockerfile to build + default: /workspace/source/src/Dockerfile + - name: pathToContext + type: string + description: + The build context used by Kaniko + (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts) + default: /workspace/source/src + - name: DOCKERFILE + type: string + description: The name of the Dockerfile + default: "Dockerfile" + - name: BUILDKIT_CLIENT_IMAGE + type: string + description: The name of the BuildKit client (buildctl) image + + default: "docker.io/moby/buildkit:master-rootless" + - name: BUILDKIT_DAEMON_ADDRESS + type: string + description: The address of the BuildKit daemon (buildkitd) service + default: "tcp://buildkitd:1234" + resources: + - name: source + type: git + outputs: + resources: + - name: builtImage + type: image + volumes: + + - name: dckr-cfg-volume + secret: + secretName: regcred + - name: ssh-volume + secret: + secretName: ssh-key + - name: certs + secret: + secretName: buildkit-client-certs + + steps: + - name: build-and-push + image: $(inputs.params.BUILDKIT_CLIENT_IMAGE) + + + workingDir: /workspace/source + + command: [ "buildctl" ] + args: + - --tlscacert + - /certs/ca.pem + - --tlscert + - /certs/cert.pem + - --tlskey + - /certs/key.pem + - --debug + - --addr=$(inputs.params.BUILDKIT_DAEMON_ADDRESS) + - build + - --progress=plain + - --frontend=dockerfile.v0 + - --opt + - filename=$(inputs.params.DOCKERFILE) + - --local + - context=$(inputs.params.pathToContext) + - --local + - dockerfile=$(inputs.params.pathToDockerFile) + - --output + - type=image,name=$(outputs.resources.builtImage.url),push=true + - --export-cache + - type=inline + - --import-cache + - type=registry,ref=$(outputs.resources.builtImage.url) + volumeMounts: + - name: certs + readOnly: true + mountPath: /certs + - name: ssh-volume + readOnly: true + mountPath: /.ssh + diff --git a/pipeline/up.sh b/pipeline/up.sh new file mode 100755 index 0000000..cef9b55 --- /dev/null +++ b/pipeline/up.sh @@ -0,0 +1,24 @@ +#/bin/bash +FOLLOW_UP="yes" +NS_DOMAIN="cdci-librecloud-online" +PIPELINE_NAME="cdci-apache-php" +[ "$1" == "-s" ] && FOLLOW_UP="" +is_running=`kubectl get pods -n $NS_DOMAIN | grep $PIPELINE_NAME 2>/dev/null` +if [ -n "$is_running" ] ; then + kubectl delete -f pipeline-run.yaml 2>/dev/null + kubectl delete -f pipeline.yaml 2>/dev/null + kubectl delete -f task.yaml 2>/dev/null + kubectl delete -f pipe-resource.yaml 2>/dev/null +fi +kubectl delete -f PersistentVolumeCDCI.yaml 2>/dev/null +kubectl create -f PersistentVolumeCDCI.yaml +#. lib_dply.sh +#make_host_alias task +kubectl apply -f pipe-resource.yaml +kubectl apply -f task.yaml +kubectl apply -f pipeline.yaml +kubectl apply -f pipeline-run.yaml +if [ -n "$FOLLOW_UP" ] ; then + has_tkn=`type tkn 2>/dev/null` + [ -n "$has_tkn" ] && tkn pipelinerun logs -f $PIPELINE_NAME -n $NS_DOMAIN +fi diff --git a/repo-config.yaml b/repo-config.yaml new file mode 100644 index 0000000..7bd134a --- /dev/null +++ b/repo-config.yaml @@ -0,0 +1,15 @@ +Active: true +# Active: false # to not follow up webhook workflow +# Sources for src file +# +Repo: https://github.com/docker-library/php.git +Source: php/8.1/buster/apache + +# Name - Version, etc +Name: apache-php +Version: 8.1 + +# To get latest +IMAGE_NAME: php +IMAGE_MATCH: 8. + diff --git a/src/Dockerfile b/src/Dockerfile new file mode 100644 index 0000000..a499a69 --- /dev/null +++ b/src/Dockerfile @@ -0,0 +1,308 @@ +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "update.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +FROM debian:buster-slim + +# prevent Debian's PHP packages from being installed +# https://github.com/docker-library/php/pull/542 +RUN set -eux; \ + { \ + echo 'Package: php*'; \ + echo 'Pin: release *'; \ + echo 'Pin-Priority: -1'; \ + } > /etc/apt/preferences.d/no-debian-php + +# dependencies required for running "phpize" +# (see persistent deps below) +ENV PHPIZE_DEPS \ + autoconf \ + dpkg-dev \ + file \ + g++ \ + gcc \ + libc-dev \ + gettext \ + libpq-dev \ + zlib1g-dev \ + libpng-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + make \ + pkg-config \ + re2c + +# persistent / runtime deps +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + $PHPIZE_DEPS \ + ca-certificates \ + curl \ + cron \ + vim \ + zlib1g \ + netcat \ + xz-utils \ + ; \ + rm -rf /var/lib/apt/lists/* + +ENV PHP_INI_DIR /usr/local/etc/php +RUN set -eux; \ + mkdir -p "$PHP_INI_DIR/conf.d"; \ +# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743) + [ ! -d /var/www/html ]; \ + mkdir -p /var/www/html; \ + chown www-data:www-data /var/www/html; \ + chmod 777 /var/www/html + +#### +ENV APACHE_CONFDIR /etc/apache2 +ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars + +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends apache2; \ + rm -rf /var/lib/apt/lists/*; \ + \ +# generically convert lines like +# export APACHE_RUN_USER=www-data +# into +# : ${APACHE_RUN_USER:=www-data} +# export APACHE_RUN_USER +# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...") + sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \ + \ +# setup directories and permissions + . "$APACHE_ENVVARS"; \ + for dir in \ + "$APACHE_LOCK_DIR" \ + "$APACHE_RUN_DIR" \ + "$APACHE_LOG_DIR" \ + ; do \ + rm -rvf "$dir"; \ + mkdir -p "$dir"; \ + chown "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$dir"; \ +# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743) + chmod 777 "$dir"; \ + done; \ + \ +# delete the "index.html" that installing Apache drops in here + rm -rvf /var/www/html/*; \ + \ +# logs should go to stdout / stderr + ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \ + chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR" + +# Apache + PHP requires preforking Apache for best results +RUN a2dismod mpm_event && a2enmod mpm_prefork + +# PHP files should be handled by PHP, and should be preferred over any other file type +RUN { \ + echo ''; \ + echo '\tSetHandler application/x-httpd-php'; \ + echo ''; \ + echo; \ + echo 'DirectoryIndex disabled'; \ + echo 'DirectoryIndex index.php index.html'; \ + echo; \ + echo ''; \ + echo '\tOptions -Indexes'; \ + echo '\tAllowOverride All'; \ + echo ''; \ + } | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \ + && a2enconf docker-php \ + && a2enmod ssl rewrite auth_basic + +ENV PHP_EXTRA_BUILD_DEPS apache2-dev +ENV PHP_EXTRA_CONFIGURE_ARGS --with-apxs2 --disable-cgi +#### + +# Apply stack smash protection to functions using local buffers and alloca() +# Make PHP's main executable position-independent (improves ASLR security mechanism, and has no performance impact on x86_64) +# Enable optimization (-O2) +# Enable linker optimization (this sorts the hash buckets to improve cache locality, and is non-default) +# Adds GNU HASH segments to generated executables (this is used if present, and is much faster than sysv hash; in this configuration, sysv hash is also generated) +# https://github.com/docker-library/php/issues/272 +# -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php) +ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" +ENV PHP_CPPFLAGS="$PHP_CFLAGS" +ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie" + +ENV GPG_KEYS 528995BFEDFBA7191D46839EF9BA0ADA31CBD89E 39B641343D8C104B2B146DC3F9C39DC0B9698544 F1F692238FBC1666E5A5CCD4199F9DFEF6FFBAFD + +ENV PHP_VERSION 8.1.1 +ENV PHP_URL="https://www.php.net/distributions/php-8.1.1.tar.xz" PHP_ASC_URL="https://www.php.net/distributions/php-8.1.1.tar.xz.asc" +ENV PHP_SHA256="33c09d76d0a8bbb5dd930d9dd32e6bfd44e9efcf867563759eb5492c3aff8856" + +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends gnupg dirmngr; \ + rm -rf /var/lib/apt/lists/*; \ + \ + mkdir -p /usr/src; \ + cd /usr/src; \ + \ + curl -fsSL -o php.tar.xz "$PHP_URL"; \ + \ + if [ -n "$PHP_SHA256" ]; then \ + echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c -; \ + fi; \ + \ + if [ -n "$PHP_ASC_URL" ]; then \ + curl -fsSL -o php.tar.xz.asc "$PHP_ASC_URL"; \ + export GNUPGHOME="$(mktemp -d)"; \ + for key in $GPG_KEYS; do \ + gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ + done; \ + gpg --batch --verify php.tar.xz.asc php.tar.xz; \ + gpgconf --kill all; \ + rm -rf "$GNUPGHOME"; \ + fi; \ + \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false + +COPY docker-php-source /usr/local/bin/ + +# libmariadb-dev \ +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + libargon2-dev \ + libcurl4-openssl-dev \ + libedit-dev \ + libonig-dev \ + libsodium-dev \ + libsqlite3-dev \ + libssl-dev \ + libxml2-dev \ + zlib1g-dev \ + ${PHP_EXTRA_BUILD_DEPS:-} \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + export \ + CFLAGS="$PHP_CFLAGS" \ + CPPFLAGS="$PHP_CPPFLAGS" \ + LDFLAGS="$PHP_LDFLAGS" \ + ; \ + docker-php-source extract; \ + cd /usr/src/php; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ + debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ +# https://bugs.php.net/bug.php?id=74125 + if [ ! -d /usr/include/curl ]; then \ + ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \ + fi; \ + ./configure \ + --build="$gnuArch" \ + --with-config-file-path="$PHP_INI_DIR" \ + --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \ + \ +# make sure invalid --configure-flags are fatal errors intead of just warnings + --enable-option-checking=fatal \ + \ +# https://github.com/docker-library/php/issues/439 + --with-mhash \ + \ +# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236) + --enable-ftp \ +# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195) + --enable-mbstring \ +# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself) + --enable-mysqlnd \ +# https://wiki.php.net/rfc/argon2_password_hash (7.2+) + --with-password-argon2 \ +# https://wiki.php.net/rfc/libsodium + --with-sodium=shared \ +# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109) + --with-pdo-sqlite=/usr \ + --with-sqlite3=/usr \ + \ + --with-curl \ + --with-libedit \ + --with-openssl \ + --with-zlib \ + \ +# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear") and will be removed in PHP 8+; see also https://github.com/docker-library/php/issues/846#issuecomment-505638494 + --with-pear \ + \ +# bundled pcre does not support JIT on s390x +# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT + $(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \ + --with-libdir="lib/$debMultiarch" \ + \ + --disable-cgi \ + \ + --with-apxs2 \ + \ + ${PHP_EXTRA_CONFIGURE_ARGS:-} \ + ; \ + make -j "$(nproc)"; \ + find -type f -name '*.a' -delete; \ + make install; \ + find \ + /usr/local \ + -type f \ + -perm '/0111' \ + -exec sh -euxc ' \ + strip --strip-all "$@" || : \ + ' -- '{}' + \ + ; \ + find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; \ + make clean; \ + \ +# https://github.com/docker-library/php/issues/692 (copy default example "php.ini" files somewhere easily discoverable) + cp -v php.ini-* "$PHP_INI_DIR/"; \ + \ + cd /; \ + docker-php-source delete; \ + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies + apt-mark auto '.*' > /dev/null; \ + [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ + find /usr/local -type f -executable -exec ldd '{}' ';' \ + | awk '/=>/ { print $(NF-1) }' \ + | sort -u \ + | xargs -r dpkg-query --search \ + | cut -d: -f1 \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/*; \ + \ +# update pecl channel definitions https://github.com/docker-library/php/issues/443 + pecl update-channels; \ + rm -rf /tmp/pear ~/.pearrc; \ +# smoke test + php --version + +COPY docker-php-ext-* docker-php-entrypoint /usr/local/bin/ + +# sodium was built as a shared module (so that it can be replaced later if so desired), so let's enable it too (https://github.com/docker-library/php/issues/598) +RUN docker-php-ext-install gettext gd mysqli pdo_pgsql ; \ + docker-php-ext-enable sodium gd mysqli pdo_pgsql + +ENTRYPOINT ["docker-php-entrypoint"] +#### +# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop +STOPSIGNAL SIGWINCH + +COPY apache2-foreground /usr/local/bin/ +WORKDIR /var/www/html + +#EXPOSE 80 +#CMD ( crond -f -l 8 & ) && apache2-foreground +CMD ["apache2-foreground"] +#### diff --git a/src/apache2-foreground b/src/apache2-foreground new file mode 100755 index 0000000..5fe22e2 --- /dev/null +++ b/src/apache2-foreground @@ -0,0 +1,40 @@ +#!/bin/bash +set -e + +# Note: we don't just use "apache2ctl" here because it itself is just a shell-script wrapper around apache2 which provides extra functionality like "apache2ctl start" for launching apache2 in the background. +# (also, when run as "apache2ctl ", it does not use "exec", which leaves an undesirable resident shell process) + +: "${APACHE_CONFDIR:=/etc/apache2}" +: "${APACHE_ENVVARS:=$APACHE_CONFDIR/envvars}" +if test -f "$APACHE_ENVVARS"; then + . "$APACHE_ENVVARS" +fi + +# Apache gets grumpy about PID files pre-existing +: "${APACHE_RUN_DIR:=/var/run/apache2}" +: "${APACHE_PID_FILE:=$APACHE_RUN_DIR/apache2.pid}" +rm -f "$APACHE_PID_FILE" + +# create missing directories +# (especially APACHE_RUN_DIR, APACHE_LOCK_DIR, and APACHE_LOG_DIR) +for e in "${!APACHE_@}"; do + if [[ "$e" == *_DIR ]] && [[ "${!e}" == /* ]]; then + # handle "/var/lock" being a symlink to "/run/lock", but "/run/lock" not existing beforehand, so "/var/lock/something" fails to mkdir + # mkdir: cannot create directory '/var/lock': File exists + dir="${!e}" + while [ "$dir" != "$(dirname "$dir")" ]; do + dir="$(dirname "$dir")" + if [ -d "$dir" ]; then + break + fi + absDir="$(readlink -f "$dir" 2>/dev/null || :)" + if [ -n "$absDir" ]; then + mkdir -p "$absDir" + fi + done + + mkdir -p "${!e}" + fi +done + +exec apache2 -DFOREGROUND "$@" diff --git a/src/docker-php-entrypoint b/src/docker-php-entrypoint new file mode 100755 index 0000000..3d36d5e --- /dev/null +++ b/src/docker-php-entrypoint @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +# first arg is `-f` or `--some-option` +if [ "${1#-}" != "$1" ]; then + set -- apache2-foreground "$@" +fi + +exec "$@" diff --git a/src/docker-php-ext-configure b/src/docker-php-ext-configure new file mode 100755 index 0000000..34fc133 --- /dev/null +++ b/src/docker-php-ext-configure @@ -0,0 +1,69 @@ +#!/bin/sh +set -e + +# prefer user supplied CFLAGS, but default to our PHP_CFLAGS +: ${CFLAGS:=$PHP_CFLAGS} +: ${CPPFLAGS:=$PHP_CPPFLAGS} +: ${LDFLAGS:=$PHP_LDFLAGS} +export CFLAGS CPPFLAGS LDFLAGS + +srcExists= +if [ -d /usr/src/php ]; then + srcExists=1 +fi +docker-php-source extract +if [ -z "$srcExists" ]; then + touch /usr/src/php/.docker-delete-me +fi + +cd /usr/src/php/ext + +usage() { + echo "usage: $0 ext-name [configure flags]" + echo " ie: $0 gd --with-jpeg-dir=/usr/local/something" + echo + echo 'Possible values for ext-name:' + find . \ + -mindepth 2 \ + -maxdepth 2 \ + -type f \ + -name 'config.m4' \ + | xargs -n1 dirname \ + | xargs -n1 basename \ + | sort \ + | xargs + echo + echo 'Some of the above modules are already compiled into PHP; please check' + echo 'the output of "php -i" to see which modules are already loaded.' +} + +ext="$1" +if [ -z "$ext" ] || [ ! -d "$ext" ]; then + usage >&2 + exit 1 +fi +shift + +pm='unknown' +if [ -e /lib/apk/db/installed ]; then + pm='apk' +fi + +if [ "$pm" = 'apk' ]; then + if \ + [ -n "$PHPIZE_DEPS" ] \ + && ! apk info --installed .phpize-deps > /dev/null \ + && ! apk info --installed .phpize-deps-configure > /dev/null \ + ; then + apk add --no-cache --virtual .phpize-deps-configure $PHPIZE_DEPS + fi +fi + +if command -v dpkg-architecture > /dev/null; then + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" + set -- --build="$gnuArch" "$@" +fi + +cd "$ext" +phpize +./configure --enable-option-checking=fatal "$@" diff --git a/src/docker-php-ext-enable b/src/docker-php-ext-enable new file mode 100755 index 0000000..41d20bb --- /dev/null +++ b/src/docker-php-ext-enable @@ -0,0 +1,121 @@ +#!/bin/sh +set -e + +extDir="$(php -d 'display_errors=stderr' -r 'echo ini_get("extension_dir");')" +cd "$extDir" + +usage() { + echo "usage: $0 [options] module-name [module-name ...]" + echo " ie: $0 gd mysqli" + echo " $0 pdo pdo_mysql" + echo " $0 --ini-name 0-apc.ini apcu apc" + echo + echo 'Possible values for module-name:' + find -maxdepth 1 \ + -type f \ + -name '*.so' \ + -exec basename '{}' ';' \ + | sort \ + | xargs + echo + echo 'Some of the above modules are already compiled into PHP; please check' + echo 'the output of "php -i" to see which modules are already loaded.' +} + +opts="$(getopt -o 'h?' --long 'help,ini-name:' -- "$@" || { usage >&2 && false; })" +eval set -- "$opts" + +iniName= +while true; do + flag="$1" + shift + case "$flag" in + --help|-h|'-?') usage && exit 0 ;; + --ini-name) iniName="$1" && shift ;; + --) break ;; + *) + { + echo "error: unknown flag: $flag" + usage + } >&2 + exit 1 + ;; + esac +done + +modules= +for module; do + if [ -z "$module" ]; then + continue + fi + if ! [ -f "$module" ] && ! [ -f "$module.so" ]; then + echo >&2 "error: '$module' does not exist" + echo >&2 + usage >&2 + exit 1 + fi + modules="$modules $module" +done + +if [ -z "$modules" ]; then + usage >&2 + exit 1 +fi + +pm='unknown' +if [ -e /lib/apk/db/installed ]; then + pm='apk' +fi + +apkDel= +if [ "$pm" = 'apk' ]; then + if \ + [ -n "$PHPIZE_DEPS" ] \ + && ! apk info --installed .phpize-deps > /dev/null \ + && ! apk info --installed .phpize-deps-configure > /dev/null \ + ; then + apk add --no-cache --virtual '.docker-php-ext-enable-deps' binutils + apkDel='.docker-php-ext-enable-deps' + fi +fi + +for module in $modules; do + moduleFile="$module" + if [ -f "$module.so" ] && ! [ -f "$module" ]; then + moduleFile="$module.so" + fi + if readelf --wide --syms "$moduleFile" | grep -q ' zend_extension_entry$'; then + # https://wiki.php.net/internals/extensions#loading_zend_extensions + line="zend_extension=$module" + else + line="extension=$module" + fi + + ext="$(basename "$module")" + ext="${ext%.*}" + if php -d 'display_errors=stderr' -r 'exit(extension_loaded("'"$ext"'") ? 0 : 1);'; then + # this isn't perfect, but it's better than nothing + # (for example, 'opcache.so' presents inside PHP as 'Zend OPcache', not 'opcache') + echo >&2 + echo >&2 "warning: $ext ($module) is already loaded!" + echo >&2 + continue + fi + + case "$iniName" in + /*) + # allow an absolute path + ini="$iniName" + ;; + *) + ini="$PHP_INI_DIR/conf.d/${iniName:-"docker-php-ext-$ext.ini"}" + ;; + esac + if ! grep -qFx -e "$line" -e "$line.so" "$ini" 2>/dev/null; then + echo "$line" >> "$ini" + fi +done + +if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then + apk del --no-network $apkDel +fi diff --git a/src/docker-php-ext-install b/src/docker-php-ext-install new file mode 100755 index 0000000..cc742e9 --- /dev/null +++ b/src/docker-php-ext-install @@ -0,0 +1,130 @@ +#!/bin/sh +set -e + +# prefer user supplied CFLAGS, but default to our PHP_CFLAGS +: ${CFLAGS:=$PHP_CFLAGS} +: ${CPPFLAGS:=$PHP_CPPFLAGS} +: ${LDFLAGS:=$PHP_LDFLAGS} +export CFLAGS CPPFLAGS LDFLAGS + +srcExists= +if [ -d /usr/src/php ]; then + srcExists=1 +fi +docker-php-source extract +if [ -z "$srcExists" ]; then + touch /usr/src/php/.docker-delete-me +fi + +cd /usr/src/php/ext + +usage() { + echo "usage: $0 [-jN] [--ini-name file.ini] ext-name [ext-name ...]" + echo " ie: $0 gd mysqli" + echo " $0 pdo pdo_mysql" + echo " $0 -j5 gd mbstring mysqli pdo pdo_mysql shmop" + echo + echo 'if custom ./configure arguments are necessary, see docker-php-ext-configure' + echo + echo 'Possible values for ext-name:' + find . \ + -mindepth 2 \ + -maxdepth 2 \ + -type f \ + -name 'config.m4' \ + | xargs -n1 dirname \ + | xargs -n1 basename \ + | sort \ + | xargs + echo + echo 'Some of the above modules are already compiled into PHP; please check' + echo 'the output of "php -i" to see which modules are already loaded.' +} + +opts="$(getopt -o 'h?j:' --long 'help,ini-name:,jobs:' -- "$@" || { usage >&2 && false; })" +eval set -- "$opts" + +j=1 +iniName= +while true; do + flag="$1" + shift + case "$flag" in + --help|-h|'-?') usage && exit 0 ;; + --ini-name) iniName="$1" && shift ;; + --jobs|-j) j="$1" && shift ;; + --) break ;; + *) + { + echo "error: unknown flag: $flag" + usage + } >&2 + exit 1 + ;; + esac +done + +exts= +for ext; do + if [ -z "$ext" ]; then + continue + fi + if [ ! -d "$ext" ]; then + echo >&2 "error: $PWD/$ext does not exist" + echo >&2 + usage >&2 + exit 1 + fi + exts="$exts $ext" +done + +if [ -z "$exts" ]; then + usage >&2 + exit 1 +fi + +pm='unknown' +if [ -e /lib/apk/db/installed ]; then + pm='apk' +fi + +apkDel= +if [ "$pm" = 'apk' ]; then + if [ -n "$PHPIZE_DEPS" ]; then + if apk info --installed .phpize-deps-configure > /dev/null; then + apkDel='.phpize-deps-configure' + elif ! apk info --installed .phpize-deps > /dev/null; then + apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS + apkDel='.phpize-deps' + fi + fi +fi + +popDir="$PWD" +for ext in $exts; do + cd "$ext" + [ -e Makefile ] || docker-php-ext-configure "$ext" + make -j"$j" + find modules \ + -maxdepth 1 \ + -name '*.so' \ + -exec sh -euxc ' \ + strip --strip-all "$@" || : + ' -- '{}' + + make -j"$j" install + find modules \ + -maxdepth 1 \ + -name '*.so' \ + -exec basename '{}' ';' \ + | xargs -r docker-php-ext-enable ${iniName:+--ini-name "$iniName"} + make -j"$j" clean + cd "$popDir" +done + +if [ "$pm" = 'apk' ] && [ -n "$apkDel" ]; then + apk del --no-network $apkDel +fi + +if [ -e /usr/src/php/.docker-delete-me ]; then + docker-php-source delete +fi diff --git a/src/docker-php-source b/src/docker-php-source new file mode 100755 index 0000000..9033d24 --- /dev/null +++ b/src/docker-php-source @@ -0,0 +1,34 @@ +#!/bin/sh +set -e + +dir=/usr/src/php + +usage() { + echo "usage: $0 COMMAND" + echo + echo "Manage php source tarball lifecycle." + echo + echo "Commands:" + echo " extract extract php source tarball into directory $dir if not already done." + echo " delete delete extracted php source located into $dir if not already done." + echo +} + +case "$1" in + extract) + mkdir -p "$dir" + if [ ! -f "$dir/.docker-extracted" ]; then + tar -Jxf /usr/src/php.tar.xz -C "$dir" --strip-components=1 + touch "$dir/.docker-extracted" + fi + ;; + + delete) + rm -rf "$dir" + ;; + + *) + usage + exit 1 + ;; +esac