mirror of
https://github.com/N0rthernL1ghts/wordpress.git
synced 2025-12-09 00:12:40 +01:00
Compare commits
223 Commits
other/depr
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
cf83bd7ef7
|
|||
| a554422633 | |||
| d3141d20f8 | |||
|
|
90b952798d | ||
|
|
3bd33afb64 | ||
| 2e345410fc | |||
|
bca1e03d59
|
|||
|
0e38adade4
|
|||
|
912b0e666c
|
|||
|
0475842323
|
|||
|
0aa2eed313
|
|||
| f1f1606a71 | |||
|
|
b48a8b8be3 | ||
| a06876919a | |||
| 6b04af76de | |||
|
|
9f4e8932b1 | ||
|
|
ef51ddfea9 | ||
|
07f1759885
|
|||
|
1035ee59aa
|
|||
|
dbce14299f
|
|||
|
fa0f3253ee
|
|||
|
4893db1ed3
|
|||
| 01e065f42e | |||
|
90d44ccaf8
|
|||
|
24427cb2c6
|
|||
|
93e089323a
|
|||
|
|
8a8a1c4cc7 | ||
|
563cd9fd35
|
|||
|
2d7515e371
|
|||
|
c9fc0d2292
|
|||
|
1d2bc2a087
|
|||
|
21af566d20
|
|||
|
096b72c3d2
|
|||
|
933e25a75a
|
|||
|
16fe42e402
|
|||
|
21718c14b4
|
|||
|
ed80e85570
|
|||
|
b6eba6bf01
|
|||
|
fdbe04e587
|
|||
| a8fb70a9c5 | |||
|
|
fac5c23e69 | ||
|
40a0e10c7b
|
|||
|
08a5288dba
|
|||
|
4e6e2aa78e
|
|||
|
0cb7952020
|
|||
|
c692812e24
|
|||
|
2245ae0217
|
|||
|
a5d36946b4
|
|||
|
6dba8a19f9
|
|||
|
108fd72c86
|
|||
|
abcb0d0fe3
|
|||
|
1191b6120e
|
|||
|
696e1aea16
|
|||
|
53c16e53c3
|
|||
|
b7e9ab4d5c
|
|||
|
7a3ef92e87
|
|||
|
5dc47e9ee7
|
|||
|
bc40d123ae
|
|||
|
294e7dd725
|
|||
|
d5d0754606
|
|||
| e0c2678233 | |||
|
|
2c40a93f93 | ||
| 5e24e51e57 | |||
| 35a4183322 | |||
|
|
86492d4255 | ||
|
|
e1730014e6 | ||
|
cfa873fd4b
|
|||
|
90645d32bd
|
|||
|
3210cc265e
|
|||
|
3cb2b8afdd
|
|||
|
f228e0554b
|
|||
|
bcf6214c3d
|
|||
|
27880b836a
|
|||
|
2ca07e8102
|
|||
|
5c8959d938
|
|||
|
f2951e8d8b
|
|||
|
6c7a9812e0
|
|||
|
48ba044713
|
|||
|
3b184d71a7
|
|||
|
007660573b
|
|||
|
c9f5cf3a81
|
|||
|
4e256a82e5
|
|||
|
333acce410
|
|||
|
a24c5bd1a5
|
|||
|
650bdcb161
|
|||
|
aa5e378f30
|
|||
|
40dd1e2987
|
|||
|
80d592cf97
|
|||
|
f86a28f3a6
|
|||
|
cca0dd0d5d
|
|||
|
90cbfcbbd3
|
|||
|
ff4fc6104d
|
|||
|
a9350c0119
|
|||
|
57f8be82cf
|
|||
|
90ae49de10
|
|||
|
0e70c8c099
|
|||
|
2fb3374416
|
|||
|
dc8930d6b8
|
|||
|
c7a402cf26
|
|||
|
e6110e37f2
|
|||
|
4cb7286fc4
|
|||
|
63832d68b4
|
|||
|
0b82cf55b7
|
|||
|
1660ab8dc7
|
|||
|
cb4331a506
|
|||
|
af3b52044c
|
|||
|
fb1ad09486
|
|||
| f74617501d | |||
|
7368178d9c
|
|||
|
7511668511
|
|||
|
a3085c8e7b
|
|||
|
5d591330fd
|
|||
|
29e5cef77f
|
|||
|
e4995b84c1
|
|||
|
86700bf5c4
|
|||
|
68cc36b40c
|
|||
|
7a03849aed
|
|||
| a53567bf75 | |||
|
|
70d72c7e90 | ||
|
|
ff04cb4433 | ||
| 5fd146bc5c | |||
|
|
dc5203a67a | ||
| ba5b57b5fc | |||
|
|
6f4ddfdd6c | ||
|
c612778207
|
|||
|
4543c24b1e
|
|||
|
9f82dcf635
|
|||
| c2feba5cfb | |||
| 3b584cf483 | |||
|
|
b908ee2ec4 | ||
| 59cddab5ff | |||
| 5a45c15357 | |||
| 650efecafb | |||
|
|
ccafce6e08 | ||
| 6ca3199972 | |||
|
|
6dcf8945fa | ||
|
|
26a43c9024 | ||
|
|
06c31a111d | ||
|
|
1f4cd946a9 | ||
|
a30b44b34e
|
|||
|
6178bbb0f8
|
|||
|
f2d68e2d55
|
|||
|
b5781420c8
|
|||
|
f038f0e042
|
|||
| a9ab27db1b | |||
|
|
11fa24773d | ||
|
5e1a787329
|
|||
| 04393a679c | |||
|
b51d428221
|
|||
|
|
449429be08 | ||
| 82237ce431 | |||
| e96813bdd1 | |||
| f26a5d68e6 | |||
|
|
eed560bb99 | ||
|
5b75b4119e
|
|||
| 4d712f7861 | |||
| 83e0bc5924 | |||
|
04f0dc4d93
|
|||
|
ec520c2e42
|
|||
|
0a225eedd7
|
|||
|
9a2794d584
|
|||
|
e39555b0b1
|
|||
|
a6080cbef0
|
|||
|
7e55f47ac6
|
|||
|
f8beef6bf4
|
|||
|
cad36f6e7e
|
|||
|
a50ce69fc0
|
|||
|
6f165400a4
|
|||
|
f57537dfcf
|
|||
|
7c8fa6cfc8
|
|||
|
d236f0ba51
|
|||
|
69c43a5caa
|
|||
|
1357f2fec3
|
|||
|
fd6fba8dc9
|
|||
|
8a0671090e
|
|||
|
f70d3d891c
|
|||
|
fc85a1d8cb
|
|||
|
23192aaa94
|
|||
|
e184127d38
|
|||
|
aeb39d0f13
|
|||
|
250227f3e1
|
|||
|
90f38805fa
|
|||
|
ef47e1b2b9
|
|||
|
1b62dba10a
|
|||
|
f79da27583
|
|||
|
53ab34b35e
|
|||
|
47ba7873f1
|
|||
|
879df6c042
|
|||
|
8df891a400
|
|||
|
c26a0afd1f
|
|||
|
aa68d5ba82
|
|||
|
e2ed315ff2
|
|||
|
a8f2aadab2
|
|||
|
f387ec0773
|
|||
|
c41860611d
|
|||
|
4fc19fa5e7
|
|||
|
f81ec4c67e
|
|||
|
f0ce5dae9e
|
|||
| 924a9c9304 | |||
|
|
0b69603a10 | ||
|
2fd2e0d6aa
|
|||
| fcd9719d6b | |||
|
|
89fb3fa6a0 | ||
|
e398d3a71a
|
|||
|
64722d5b6c
|
|||
|
fedfaeafc4
|
|||
|
bb3f62ef10
|
|||
|
a72f393567
|
|||
|
705a2d505d
|
|||
|
dd43a2e929
|
|||
|
e5ad0997f6
|
|||
|
4edf0ee410
|
|||
|
fdb3c6727e
|
|||
|
824994c6b7
|
|||
|
3377076391
|
|||
|
88b4e4514a
|
|||
|
149e34bcd2
|
|||
|
0d454a15d9
|
|||
|
e344128779
|
|||
|
6d526d71e1
|
|||
|
550bcea00d
|
|||
|
68da285e90
|
|||
| a1563b89f4 |
42
.github/workflows/image.yml
vendored
42
.github/workflows/image.yml
vendored
@@ -1,8 +1,21 @@
|
||||
name: Build docker WordPress image
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 4 * * */7"
|
||||
push:
|
||||
branches: master
|
||||
paths:
|
||||
- .github/workflows/image.yml # This workflow file itself
|
||||
- .dockerignore
|
||||
- Dockerfile
|
||||
- Dockerfile.cron
|
||||
- build/docker-bake.hcl
|
||||
- build/docker-bake-cron.hcl
|
||||
- rootfs/**
|
||||
- src/**
|
||||
- patches/**
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -10,37 +23,46 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: checkout code
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v5
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 16
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{github.actor}}
|
||||
password: ${{secrets.PAT_TOKEN}}
|
||||
-
|
||||
name: Await successful tests
|
||||
uses: lewagon/wait-on-check-action@v1.2.0
|
||||
uses: lewagon/wait-on-check-action@v1.4.1
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
check-name: tests
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 20
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/bake-action@v2.3.0
|
||||
name: Build and push WordPress Web image
|
||||
uses: docker/bake-action@v6.9.0
|
||||
with:
|
||||
files: build/docker-bake.hcl
|
||||
push: true
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=wordpress
|
||||
*.cache-to=type=gha,scope=wordpress,mode=max
|
||||
- name: Build and push WordPress Cron image
|
||||
uses: docker/bake-action@v6.9.0
|
||||
with:
|
||||
files: build/docker-bake-cron.hcl
|
||||
push: true
|
||||
6
.github/workflows/tests.yml
vendored
6
.github/workflows/tests.yml
vendored
@@ -12,15 +12,15 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: "Checkout"
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v5
|
||||
|
||||
-
|
||||
name: "Set up Docker Buildx"
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
-
|
||||
name: "Build tests-util image"
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v6
|
||||
id: build
|
||||
with:
|
||||
context: build/tests-util/
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,8 @@
|
||||
.idea/
|
||||
wordpress.iml
|
||||
data/
|
||||
.secrets/
|
||||
build/patch-util/wp-src/
|
||||
build/tests-util/composer.lock
|
||||
build/tests-util/vendor/
|
||||
./docker-compose.override.yml
|
||||
|
||||
84
Dockerfile
84
Dockerfile
@@ -1,8 +1,11 @@
|
||||
ARG PHP_VERSION=7.4
|
||||
ARG PHP_VERSION=8.1
|
||||
ARG WP_VERSION=6.1.0
|
||||
ARG WP_PATCH_VERSION=5.9.1
|
||||
|
||||
# WordPress resources
|
||||
FROM wordpress:cli-php${PHP_VERSION} AS wp-cli
|
||||
FROM wordpress:${WP_VERSION}-php${PHP_VERSION}-fpm-alpine AS wp-src
|
||||
|
||||
# WP CLI
|
||||
FROM --platform=${TARGETPLATFORM} wordpress:cli-php${PHP_VERSION} AS wp-cli
|
||||
|
||||
|
||||
# Build rootfs
|
||||
@@ -11,68 +14,59 @@ FROM scratch AS rootfs
|
||||
# Install wp-cli
|
||||
COPY --from=wp-cli ["/usr/local/bin/wp", "/usr/local/bin/wp-cli"]
|
||||
|
||||
# Install attr utility
|
||||
COPY --from=nlss/attr ["/usr/local/bin/attr", "/usr/local/bin/"]
|
||||
|
||||
# Add crond service
|
||||
COPY --from=nlss/base-alpine:3.14 ["/etc/services.d/cron/", "/etc/services.d/cron/"]
|
||||
|
||||
# Add container init tasks
|
||||
COPY --from=nlss/php-nginx:7.4 ["/etc/cont-init.d/", "/etc/cont-init.d/"]
|
||||
|
||||
# Add php-fpm configuration
|
||||
COPY --from=nlss/php-nginx:7.4 ["/usr/local/etc/php-fpm.d/", "/usr/local/etc/php-fpm.d/"]
|
||||
|
||||
# Add php-fpm service
|
||||
COPY --from=nlss/php-nginx:7.4 ["/etc/services.d/php-fpm/", "/etc/services.d/php-fpm/"]
|
||||
|
||||
# Add nginx service and configuration
|
||||
COPY --from=nlss/php-nginx:7.4 ["/etc/services.d/nginx/", "/etc/services.d/nginx/"]
|
||||
COPY --from=nlss/php-nginx:7.4 ["/etc/nginx/", "/etc/nginx/"]
|
||||
COPY --from=nlss/php-nginx:7.4 ["/var/log/nginx/", "/var/log/nginx/"]
|
||||
COPY --from=nlss/php-nginx:7.4 ["/var/www/", "/var/www/"]
|
||||
|
||||
# Install gomplate
|
||||
COPY --from=hairyhenderson/gomplate:v3.10.0-alpine ["/bin/gomplate", "/usr/local/bin/"]
|
||||
|
||||
# Install s6 supervisor
|
||||
COPY --from=nlss/s6-rootfs:2.2 ["/", "/"]
|
||||
# Install wp-utils
|
||||
COPY ["./src/wp-utils/", "/usr/local/bin/"]
|
||||
|
||||
# Overlay
|
||||
COPY ["./rootfs/", "/"]
|
||||
|
||||
# Configuration and patches
|
||||
ARG WP_VERSION
|
||||
COPY ["wp-config.php", "/var/www/html/"]
|
||||
COPY ["patches/${WP_VERSION}/wp-admin-update-core.patch", "/etc/wp-mods/"]
|
||||
ARG WP_PATCH_VERSION
|
||||
|
||||
# Copy WordPress source from the official image
|
||||
COPY --from=wp-src ["/usr/src/wordpress/", "/var/www/html/"]
|
||||
|
||||
COPY ["patches/${WP_PATCH_VERSION}/wp-admin-update-core.patch", "/etc/wp-mods/"]
|
||||
|
||||
# Copy wp-content/themes to src - This is needed if wp-content is mounted as a volume and not initialized prior
|
||||
COPY --from=wp-src ["/usr/src/wordpress/wp-content/themes/", "/usr/src/wordpress/wp-content/themes/"]
|
||||
|
||||
|
||||
|
||||
# Stage 3 - Final
|
||||
FROM --platform=${TARGETPLATFORM} wordpress:${WP_VERSION}-php${PHP_VERSION}-fpm-alpine
|
||||
FROM ghcr.io/n0rthernl1ghts/wordpress-unit-base:2.1.0
|
||||
|
||||
RUN apk add --update --no-cache patch less mysql-client tzdata
|
||||
RUN apk add --update --no-cache patch
|
||||
|
||||
COPY --from=rootfs ["/", "/"]
|
||||
|
||||
RUN mv /etc/nginx/conf.d /etc/nginx/http.d \
|
||||
&& apk add --update --no-cache nginx \
|
||||
&& echo "*/5 * * * * /usr/local/bin/wp cron event run --due-now" >> /etc/crontabs/www-data \
|
||||
&& chmod a+x /usr/local/bin/wp
|
||||
RUN set -eux \
|
||||
&& apk add --update --no-cache rsync \
|
||||
&& chmod a+x /usr/local/bin/wp \
|
||||
&& mv "/var/www/html/wp-config-docker.php" "/var/www/html/wp-config.php" \
|
||||
&& wp-apply-patch "/etc/wp-mods/wp-admin-update-core.patch" "/var/www/html/wp-admin/update-core.php" "true" \
|
||||
&& php -l /var/www/html/wp-admin/update-core.php
|
||||
|
||||
ARG WP_VERSION
|
||||
ARG WP_PATCH_VERSION
|
||||
ENV WP_VERSION="${WP_VERSION}"
|
||||
ARG WP_LOCALE="en_US"
|
||||
ENV WP_LOCALE=${WP_LOCALE}
|
||||
ENV VIRTUAL_HOST=your-domain.com
|
||||
ENV S6_KEEP_ENV=1
|
||||
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2
|
||||
ENV WP_PATCH_VERSION="${WP_PATCH_VERSION}"
|
||||
ENV ENFORCE_DISABLE_WP_UPDATES=true
|
||||
ENV WP_CLI_DISABLE_AUTO_CHECK_UPDATE=true
|
||||
ENV CRON_ENABLED=true
|
||||
ENV WEB_ROOT=html
|
||||
ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
|
||||
|
||||
WORKDIR "/var/www/html/"
|
||||
VOLUME ["/root/.wp-cli", "/var/www/html/wp-content"]
|
||||
|
||||
LABEL maintainer="Aleksandar Puharic <aleksandar@puharic.com>" \
|
||||
org.opencontainers.image.documentation="https://github.com/N0rthernL1ghts/wordpress/wiki" \
|
||||
org.opencontainers.image.source="https://github.com/N0rthernL1ghts/wordpress" \
|
||||
org.opencontainers.image.description="NGINX Unit Powered WordPress ${WP_VERSION} - Build ${TARGETPLATFORM}" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.version="${WP_VERSION}"
|
||||
|
||||
WORKDIR "/var/www/${WEB_ROOT}/"
|
||||
VOLUME ["/root/.wp-cli", "/var/www/${WEB_ROOT}", "/var/www/${WEB_ROOT}/wp-content"]
|
||||
|
||||
ENTRYPOINT ["/init"]
|
||||
EXPOSE 80/TCP
|
||||
|
||||
12
Dockerfile.cron
Normal file
12
Dockerfile.cron
Normal file
@@ -0,0 +1,12 @@
|
||||
ARG WP_VERSION=6.1.0
|
||||
FROM ghcr.io/n0rthernl1ghts/wordpress:${WP_VERSION}
|
||||
|
||||
# Disable all s6 services except for svc-crond and init-wpconfig-verify
|
||||
RUN set -eux \
|
||||
&& bash -c "rm -rf /etc/s6-overlay/s6-rc.d/{svc-unitd,init-unitd-configure,init-verify-wordpress,init-install-wordpress,init-install-resources,init-webuser-permissions,init-wpcontent} \
|
||||
&& rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/{svc-unitd,init-unitd-configure,init-unitd-load-secrets,init-verify-wordpress,init-install-wordpress,init-install-resources,init-webuser-permissions,init-wpcontent} \
|
||||
&& rm -rf /etc/s6-overlay/s6-rc.d/svc-crond/dependencies.d/{init-install-wordpress,svc-unitd}"
|
||||
|
||||
|
||||
ENV CRON_ENABLED=true
|
||||
|
||||
47
Dockerfile.dev
Normal file
47
Dockerfile.dev
Normal file
@@ -0,0 +1,47 @@
|
||||
ARG WP_VERSION=6.5.3
|
||||
FROM ghcr.io/n0rthernl1ghts/wordpress:${WP_VERSION} AS composer-build
|
||||
|
||||
COPY --from=composer:2.7 ["/usr/bin/composer", "/usr/local/bin/composer"]
|
||||
|
||||
RUN set -eux \
|
||||
&& apk add --update --no-cache git unzip \
|
||||
&& export COMPOSER_ALLOW_SUPERUSER=1 \
|
||||
&& export COMPOSER_HOME="/tmp/composer" \
|
||||
&& composer global require --no-interaction --ignore-platform-reqs \
|
||||
php-parallel-lint/php-console-highlighter \
|
||||
php-parallel-lint/php-parallel-lint \
|
||||
squizlabs/php_codesniffer
|
||||
|
||||
|
||||
|
||||
FROM scratch AS rootfs
|
||||
|
||||
# Install shellcheck
|
||||
COPY --from=koalaman/shellcheck:stable ["/bin/shellcheck", "/usr/local/bin/shellcheck"]
|
||||
|
||||
# Install shfmt
|
||||
COPY --from=mvdan/shfmt:latest ["/bin/shfmt", "/usr/local/bin/shfmt"]
|
||||
|
||||
# Install hadolint
|
||||
COPY --from=hadolint/hadolint:latest ["/bin/hadolint", "/usr/local/bin/hadolint"]
|
||||
|
||||
# Install composer
|
||||
COPY --from=composer-build ["/usr/local/bin/composer", "/usr/local/bin/"]
|
||||
COPY --from=composer-build ["/tmp/composer/", "/root/.composer/"]
|
||||
|
||||
|
||||
|
||||
ARG WP_VERSION
|
||||
FROM ghcr.io/n0rthernl1ghts/wordpress:${WP_VERSION}
|
||||
|
||||
ENV PATH="${PATH}:/root/.composer/vendor/bin"
|
||||
|
||||
RUN set -eux \
|
||||
&& apk add --update --no-cache curl exa file fish git less nano openssh-client rsync tree unzip wget
|
||||
|
||||
COPY --from=rootfs ["/", "/"]
|
||||
|
||||
ENV COMPOSER_ALLOW_SUPERUSER=1
|
||||
|
||||
WORKDIR "/workspace"
|
||||
ENTRYPOINT ["/usr/bin/fish"]
|
||||
107
README.md
107
README.md
@@ -1,7 +1,11 @@
|
||||
# wordpress
|
||||
WorPress docker image, powered by nginx/php-fpm combo and managed by s6 supervisor.
|
||||
WordPress docker image, powered by s6 supervised nginx unit.
|
||||
|
||||
Attempt to fix several of WordPress anti-patterns in ready to deploy container
|
||||
Attempt to fix several of WordPress anti-patterns in ready to deploy container.
|
||||
|
||||
Native support for docker secrets! Secrets are automatically imported into the container environment.
|
||||
No more need for `_FILE` suffixed environment variables. Still, you're free to use whichever way you want, but using secrets like this is highly encouraged.
|
||||
Please check docker-compose.yml for usage example.
|
||||
|
||||
#### Deprecation notice
|
||||
- 2023-01-20 Deprecation of WordPress versions prior to 5.9
|
||||
@@ -11,46 +15,127 @@ Attempt to fix several of WordPress anti-patterns in ready to deploy container
|
||||
* PHP7.4 reached end-of-life on 2022-11-28 and should not be used.
|
||||
* Old images will remain, but will receive no further updates, until their eventual removal. Usage is not recommended.
|
||||
* This decision will make build stack significantly lighter, ensuring much faster future builds
|
||||
- 2023-01-21 Retirement of PHP7.4. The king is dead, long live the king!
|
||||
- 2023-01-22 Replace NGINX + PHP-FPM combo with NGINX Unit
|
||||
* Split and rebase image and rework build
|
||||
* This is breaking change affecting all images
|
||||
* If your setup was vanilla, it should work out of the box
|
||||
* If you need nginx, you can set it up as a reverse proxy
|
||||
* NGINX Unit is modern application server, replacing old PHP-FPM
|
||||
* Independent benchmarks have show that NGINX Unit can handle much higher load and remain stable
|
||||
- 2023-01-23 WordPress is no longer installed during runtime and it's bundled into the image
|
||||
* This renders WP_LOCALE environment variable useless
|
||||
* Instead, you will be offered to select locale during the first setup
|
||||
- 2023-04-09 Deprecation of docker.io hosted images. We're moving to ghcr.io.
|
||||
* This is due to Docker Hub's sunsetting of free teams. See docker/hub-feedback#2314
|
||||
* If you are using nlss/wordpress images, you should switch to ghcr.io/n0rthernl1ghts/wordpress
|
||||
* nlss/wordpress images will be removed in May. Further usage is not recommended, although we'll keep them up to date until then.
|
||||
- 2023-08-06 Deprecation/removal of linux/armhf architecture
|
||||
* 32-bit ARM is [officialy dead](https://www.androidauthority.com/arm-32-vs-64-bit-explained-1232065/).
|
||||
* It has been deprecated/removed in the base
|
||||
* This improves build speed as buidling linux/armhf is slow and was taking the most of the time
|
||||
* Simplifies maintenance
|
||||
- 2024-05-13 Deprecation of WordPress versions prior to 6.2
|
||||
* Old images will remain, but will receive no further updates, until their eventual removal. Usage is not recommended.
|
||||
* This decision will make build stack significantly lighter, ensuring much faster future builds
|
||||
- 2024-05-17 Upgrade S6 supervisor to v3
|
||||
* This is breaking change affecting all images
|
||||
* If your setup was vanilla, it should work out of the box
|
||||
* If you have custom scripts, you should review them and migrate to new format
|
||||
* S6 supervisor v3 brings many improvements and bugfixes in addition to performance improvements
|
||||
* This change is necessary to ensure compatibility with future base image updates
|
||||
- 2024-10-28 Multiple changes
|
||||
* Deprecate docker hub images
|
||||
* Add WordPress versions 6.5.3 -> 6.6.2
|
||||
* Add support for docker secrets
|
||||
- 2024-11-02 Add specially optimized WordPress cron image. See docker-compose.yml for usage
|
||||
|
||||
#### Public builds (docker)
|
||||
|
||||
See: [packages](../../pkgs/container/wordpress)
|
||||
|
||||
You can use public build:
|
||||
```
|
||||
nlss/wordpress
|
||||
ghcr.io/n0rthernl1ghts/wordpress:latest
|
||||
ghcr.io/n0rthernl1ghts/wordpress-cron:latest
|
||||
```
|
||||
|
||||
You can also use specific version of WordPress:
|
||||
```
|
||||
nlss/wordpress:6.1.0
|
||||
ghcr.io/n0rthernl1ghts/wordpress:6.6.2
|
||||
ghcr.io/n0rthernl1ghts/wordpress-cron:6.6.2
|
||||
```
|
||||
|
||||
Replace version number with desired version, eg. 6.0.2.
|
||||
Replace version number with desired version, eg. 6.6.1.
|
||||
|
||||
#### Cron
|
||||
Cron is supported out of the box in `ghcr.io/n0rthernl1ghts/wordpress` image, but the best practice is to use dedicated image `ghcr.io/n0rthernl1ghts/wordpress-cron` for this purpose. <br/>
|
||||
This image is optimized for running cron jobs, and is stripped of unnecessary components.
|
||||
|
||||
Running cron in the main image is not recommended, as it can cause performance issues, and can lead to unexpected behavior.
|
||||
|
||||
#### Plugin installer
|
||||
|
||||
### Automatic plugin installer
|
||||
```
|
||||
WARNING: This feature is experimental and can fail. Proceed with caution
|
||||
```
|
||||
|
||||
This container can install plugins during container startup defined in environment variable WORDPRESS_PLUGIN_LIST
|
||||
|
||||
If environment variable is left empty, or undefined, installer will skip.
|
||||
If environment variable is left empty, or undefined, installer will skip.<br/>
|
||||
Consider using custom image with plugins pre-installed in order to speed up container startup, and follow the best practices.
|
||||
|
||||
Plugins are not activated automatically; This is intentional.
|
||||
|
||||
Usage example:
|
||||
```
|
||||
# Notice that specific version can be defined
|
||||
WORDPRESS_PLUGIN_LIST=akismet:4.1.8 two-factor
|
||||
WP_PLUGINS_INSTALL_CONCURRENCY=10
|
||||
```
|
||||
`WP_PLUGINS_INSTALL_CONCURRENCY` is optional, and defines how many plugins can be installed in parallel. Default is 5. <br/>
|
||||
If you have a lot of plugins, you can increase this value to speed up installation, but be aware that this can cause issues, such as overloaded network connection, or even server overload. <br/>
|
||||
You should not set this value to value higher than number of CPU threads ( * 1.5 ).
|
||||
|
||||
Caveats:
|
||||
* If plugin was previously installed, and not defined on the list, it will NOT be removed.
|
||||
* If plugin install fails, container will exit with error
|
||||
* Plugins are not activated automatically; This is intentional.
|
||||
* If container startup speed is crucial (eg. start-on-demand ), don't use this feature, as it will block container startup until all plugins are installed.
|
||||
|
||||
#### Extending image
|
||||
You can extend this image and install plugins during build time, using `wp-plugin` script. <br/>
|
||||
|
||||
Example:
|
||||
```Dockerfile
|
||||
FROM ghcr.io/n0rthernl1ghts/wordpress:6.7.1 AS wp-plugins-installer
|
||||
|
||||
RUN set -eux \
|
||||
&& export WP_PLUGINS_PATH="/var/www/html/wp-content/plugins" \
|
||||
&& wp-plugin download akismet 4.1.8 \
|
||||
&& wp-plugin download two-factor \
|
||||
&& wp-plugin download wp-mail-smtp
|
||||
|
||||
# Final image
|
||||
FROM ghcr.io/n0rthernl1ghts/wordpress:6.7.1
|
||||
|
||||
# Example:
|
||||
# - Install ext-redis with pecl
|
||||
# - Enable ext-redis
|
||||
# - Remove pear/pecl cache
|
||||
# - Put production-ready php.ini in use
|
||||
RUN set -eux \
|
||||
&& pecl install redis \
|
||||
&& docker-php-ext-enable redis \
|
||||
&& rm -rf /tmp/pear \
|
||||
&& cp "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini"
|
||||
|
||||
COPY --from=wp-plugins-installer ["/var/www/html/wp-content/plugins", "/var/www/html/wp-content/plugins"]
|
||||
```
|
||||
|
||||
### TODO
|
||||
* Out-of-the-box SSL support
|
||||
* ~Disable core updates~
|
||||
* ~Install/update plugins on the fly using wp cli (with versioning)~
|
||||
* Install/update themes on the fly using wp cli (with versioning)
|
||||
* ~Apply theme and eventual plugin customizations using patch files~ (Partial)
|
||||
* Support automatic install using ENV
|
||||
* ~Support automatic install using ENV~
|
||||
* Create users automatically using ENV
|
||||
* Support non-blocking plugin installation
|
||||
|
||||
13
bin/build
Executable file
13
bin/build
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
main() {
|
||||
echo "Warning: This is resource-intensive and might crash your system if you don't have enough resources !!!"
|
||||
echo "Press Ctrl+C to cancel. Automatically continuing in 5 seconds..."
|
||||
sleep 5
|
||||
|
||||
docker buildx bake --file build/docker-bake.hcl --pull "${@}" &
|
||||
docker buildx bake --file build/docker-bake-cron.hcl --pull "${@}" &
|
||||
wait
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
24
bin/dev-shell
Executable file
24
bin/dev-shell
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This is development util
|
||||
main() {
|
||||
local wpVersion="${1:-6.5.3}"
|
||||
|
||||
set -ex
|
||||
|
||||
docker build \
|
||||
--file=Dockerfile.dev \
|
||||
--build-arg="WP_VERSION=${wpVersion}" \
|
||||
-t "localhost/nlss-wp-dev:${wpVersion}" .
|
||||
|
||||
docker run \
|
||||
--init \
|
||||
--rm \
|
||||
-it \
|
||||
-v "${PWD}/:/workspace" \
|
||||
-v "${PWD}/data/fish/config:/root/.config/fish" \
|
||||
-v "${PWD}/data/fish/local:/root/.local/share/fish" \
|
||||
"localhost/nlss-wp-dev:${wpVersion}"
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
1
bin/generate-wp-salts
Symbolic link
1
bin/generate-wp-salts
Symbolic link
@@ -0,0 +1 @@
|
||||
../src/wp-utils/wp-generate-salts
|
||||
1
bin/init-wp
Symbolic link
1
bin/init-wp
Symbolic link
@@ -0,0 +1 @@
|
||||
../src/init-utils/init-wp
|
||||
42
bin/tests
42
bin/tests
@@ -1,9 +1,37 @@
|
||||
#!/usr/bin/env sh
|
||||
set -ex
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#docker build -t localhost/tests-util build/tests-util
|
||||
docker run --init \
|
||||
build_tests_util() {
|
||||
docker build -t "${TESTS_UTIL_IMAGE:?}" build/tests-util
|
||||
}
|
||||
|
||||
main() {
|
||||
# Use docker BuildKit
|
||||
DOCKER_BUILDKIT=1
|
||||
export DOCKER_BUILDKIT
|
||||
|
||||
TESTS_UTIL_IMAGE="localhost/tests-util:latest"
|
||||
export TESTS_UTIL_IMAGE
|
||||
|
||||
if [ "${1:-}" = "build" ]; then
|
||||
echo "Rebuilding image..."
|
||||
build_tests_util
|
||||
elif ! docker inspect --type=image "${TESTS_UTIL_IMAGE}" > /dev/null 2>&1; then
|
||||
echo "Image does not exist locally. Building..."
|
||||
build_tests_util
|
||||
fi
|
||||
|
||||
local runCommand="wp-patch-tests"
|
||||
if [ "${1:-}" = "shell" ]; then
|
||||
runCommand="/bin/bash"
|
||||
fi
|
||||
|
||||
docker run --init \
|
||||
--rm \
|
||||
-i \
|
||||
-v "${PWD}:/var/www/html" \
|
||||
localhost/tests-util wp-patch-tests
|
||||
--interactive \
|
||||
--volume "./build/tests-util/wp-patch-tests.sh:/usr/local/bin/wp-patch-tests" \
|
||||
--volume "./build/docker-bake.hcl:/data/docker-bake.hcl:ro" \
|
||||
--volume "./patches:/data/patches:ro" \
|
||||
"${TESTS_UTIL_IMAGE}" "${runCommand}"
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
|
||||
285
build/docker-bake-cron.hcl
Normal file
285
build/docker-bake-cron.hcl
Normal file
@@ -0,0 +1,285 @@
|
||||
group "default" {
|
||||
targets = [
|
||||
"6_2_0",
|
||||
"6_2_1",
|
||||
"6_2_2",
|
||||
"6_3_0",
|
||||
"6_3_1",
|
||||
"6_3_2",
|
||||
"6_4_0",
|
||||
"6_4_1",
|
||||
"6_4_2",
|
||||
"6_4_3",
|
||||
"6_5_0",
|
||||
"6_5_2",
|
||||
"6_5_3",
|
||||
"6_5_4",
|
||||
"6_5_5",
|
||||
"6_6_0",
|
||||
"6_6_1",
|
||||
"6_6_2",
|
||||
"6_7_0",
|
||||
"6_7_1",
|
||||
"6_7_2",
|
||||
"6_8_0",
|
||||
"6_8_1",
|
||||
"6_8_2"
|
||||
]
|
||||
}
|
||||
|
||||
target "build-dockerfile" {
|
||||
dockerfile = "Dockerfile.cron"
|
||||
}
|
||||
|
||||
target "build-platforms" {
|
||||
platforms = ["linux/amd64", "linux/aarch64"]
|
||||
}
|
||||
|
||||
target "build-common" {
|
||||
pull = true
|
||||
}
|
||||
|
||||
variable "REGISTRY_CACHE" {
|
||||
default = "ghcr.io/n0rthernl1ghts/wordpress-cron-cache"
|
||||
}
|
||||
|
||||
######################
|
||||
# Define the functions
|
||||
######################
|
||||
|
||||
# Get the arguments for the build
|
||||
function "get-args" {
|
||||
params = [version]
|
||||
result = {
|
||||
WP_VERSION = version
|
||||
}
|
||||
}
|
||||
|
||||
# Get the cache-from configuration
|
||||
function "get-cache-from" {
|
||||
params = [version]
|
||||
result = [
|
||||
"type=registry,ref=${REGISTRY_CACHE}:${sha1("${version}-${BAKE_LOCAL_PLATFORM}")}"
|
||||
]
|
||||
}
|
||||
|
||||
# Get the cache-to configuration
|
||||
function "get-cache-to" {
|
||||
params = [version]
|
||||
result = [
|
||||
"type=registry,mode=max,ref=${REGISTRY_CACHE}:${sha1("${version}-${BAKE_LOCAL_PLATFORM}")}"
|
||||
]
|
||||
}
|
||||
|
||||
# Get list of image tags and registries
|
||||
# Takes a version and a list of extra versions to tag
|
||||
# eg. get-tags("6.2.0", ["6", "6.2", "latest"])
|
||||
function "get-tags" {
|
||||
params = [version, extra_versions]
|
||||
result = concat(
|
||||
[
|
||||
"ghcr.io/n0rthernl1ghts/wordpress-cron:${version}"
|
||||
],
|
||||
flatten([
|
||||
for extra_version in extra_versions : [
|
||||
"ghcr.io/n0rthernl1ghts/wordpress-cron:${extra_version}"
|
||||
]
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
##########################
|
||||
# Define the build targets
|
||||
##########################
|
||||
|
||||
target "6_2_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.2.0")
|
||||
cache-to = get-cache-to("6.2.0")
|
||||
tags = get-tags("6.2.0", [])
|
||||
args = get-args("6.2.0")
|
||||
}
|
||||
|
||||
target "6_2_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.2.1")
|
||||
cache-to = get-cache-to("6.2.1")
|
||||
tags = get-tags("6.2.1", [])
|
||||
args = get-args("6.2.1")
|
||||
}
|
||||
|
||||
target "6_2_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.2.2")
|
||||
cache-to = get-cache-to("6.2.2")
|
||||
tags = get-tags("6.2.2", ["6.2"])
|
||||
args = get-args("6.2.2")
|
||||
}
|
||||
|
||||
target "6_3_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.3.0")
|
||||
cache-to = get-cache-to("6.3.0")
|
||||
tags = get-tags("6.3.0", [])
|
||||
args = get-args("6.3.0")
|
||||
}
|
||||
|
||||
target "6_3_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.3.1")
|
||||
cache-to = get-cache-to("6.3.1")
|
||||
tags = get-tags("6.3.1", [])
|
||||
args = get-args("6.3.1")
|
||||
}
|
||||
|
||||
target "6_3_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.3.2")
|
||||
cache-to = get-cache-to("6.3.2")
|
||||
tags = get-tags("6.3.2", [])
|
||||
args = get-args("6.3.2")
|
||||
}
|
||||
|
||||
target "6_4_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.0")
|
||||
cache-to = get-cache-to("6.4.0")
|
||||
tags = get-tags("6.4.0", [])
|
||||
args = get-args("6.4.0")
|
||||
}
|
||||
|
||||
target "6_4_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.1")
|
||||
cache-to = get-cache-to("6.4.1")
|
||||
tags = get-tags("6.4.1", [])
|
||||
args = get-args("6.4.1")
|
||||
}
|
||||
|
||||
target "6_4_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.2")
|
||||
cache-to = get-cache-to("6.4.2")
|
||||
tags = get-tags("6.4.2", [])
|
||||
args = get-args("6.4.2")
|
||||
}
|
||||
|
||||
target "6_4_3" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.3")
|
||||
cache-to = get-cache-to("6.4.3")
|
||||
tags = get-tags("6.4.3", ["6.4"])
|
||||
args = get-args("6.4.3")
|
||||
}
|
||||
|
||||
target "6_5_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.0")
|
||||
cache-to = get-cache-to("6.5.0")
|
||||
tags = get-tags("6.5.0", [])
|
||||
args = get-args("6.5.0")
|
||||
}
|
||||
|
||||
target "6_5_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.2")
|
||||
cache-to = get-cache-to("6.5.2")
|
||||
tags = get-tags("6.5.2", [])
|
||||
args = get-args("6.5.2")
|
||||
}
|
||||
|
||||
target "6_5_3" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.3")
|
||||
cache-to = get-cache-to("6.5.3")
|
||||
tags = get-tags("6.5.3", [])
|
||||
args = get-args("6.5.3")
|
||||
}
|
||||
|
||||
target "6_5_4" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.4")
|
||||
cache-to = get-cache-to("6.5.4")
|
||||
tags = get-tags("6.5.4", [])
|
||||
args = get-args("6.5.4")
|
||||
}
|
||||
|
||||
target "6_5_5" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.5")
|
||||
cache-to = get-cache-to("6.5.5")
|
||||
tags = get-tags("6.5.5", ["6.5"])
|
||||
args = get-args("6.5.5")
|
||||
}
|
||||
|
||||
target "6_6_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.6.0")
|
||||
cache-to = get-cache-to("6.6.0")
|
||||
tags = get-tags("6.6.0", [])
|
||||
args = get-args("6.6.0")
|
||||
}
|
||||
|
||||
target "6_6_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.6.1")
|
||||
cache-to = get-cache-to("6.6.1")
|
||||
tags = get-tags("6.6.1", [])
|
||||
args = get-args("6.6.1")
|
||||
}
|
||||
|
||||
target "6_6_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.6.2")
|
||||
cache-to = get-cache-to("6.6.2")
|
||||
tags = get-tags("6.6.2", ["6.6"])
|
||||
args = get-args("6.6.2")
|
||||
}
|
||||
|
||||
target "6_7_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.7.0")
|
||||
cache-to = get-cache-to("6.7.0")
|
||||
tags = get-tags("6.7.0", [])
|
||||
args = get-args("6.7.0")
|
||||
}
|
||||
|
||||
target "6_7_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.7.1")
|
||||
cache-to = get-cache-to("6.7.1")
|
||||
tags = get-tags("6.7.1", [])
|
||||
args = get-args("6.7.1")
|
||||
}
|
||||
|
||||
target "6_7_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.7.2")
|
||||
cache-to = get-cache-to("6.7.2")
|
||||
tags = get-tags("6.7.2", ["6.7"])
|
||||
args = get-args("6.7.2")
|
||||
}
|
||||
|
||||
target "6_8_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.8.0")
|
||||
cache-to = get-cache-to("6.8.0")
|
||||
tags = get-tags("6.8.0", [])
|
||||
args = get-args("6.8.0")
|
||||
}
|
||||
|
||||
target "6_8_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.8.1")
|
||||
cache-to = get-cache-to("6.8.1")
|
||||
tags = get-tags("6.8.1", [])
|
||||
args = get-args("6.8.1")
|
||||
}
|
||||
|
||||
target "6_8_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.8.2")
|
||||
cache-to = get-cache-to("6.8.2")
|
||||
tags = get-tags("6.8.2", ["6", "6.8", "latest"])
|
||||
args = get-args("6.8.2")
|
||||
}
|
||||
@@ -1,5 +1,30 @@
|
||||
group "default" {
|
||||
targets = ["5_9_0", "5_9_1", "5_9_2", "5_9_3", "6_0_0", "6_0_1", "6_0_2", "6_0_3", "6_1_0", "6_1_1"]
|
||||
targets = [
|
||||
"6_2_0",
|
||||
"6_2_1",
|
||||
"6_2_2",
|
||||
"6_3_0",
|
||||
"6_3_1",
|
||||
"6_3_2",
|
||||
"6_4_0",
|
||||
"6_4_1",
|
||||
"6_4_2",
|
||||
"6_4_3",
|
||||
"6_5_0",
|
||||
"6_5_2",
|
||||
"6_5_3",
|
||||
"6_5_4",
|
||||
"6_5_5",
|
||||
"6_6_0",
|
||||
"6_6_1",
|
||||
"6_6_2",
|
||||
"6_7_0",
|
||||
"6_7_1",
|
||||
"6_7_2",
|
||||
"6_8_0",
|
||||
"6_8_1",
|
||||
"6_8_2"
|
||||
]
|
||||
}
|
||||
|
||||
target "build-dockerfile" {
|
||||
@@ -7,89 +32,255 @@ target "build-dockerfile" {
|
||||
}
|
||||
|
||||
target "build-platforms" {
|
||||
platforms = ["linux/amd64", "linux/armhf", "linux/aarch64"]
|
||||
platforms = ["linux/amd64", "linux/aarch64"]
|
||||
}
|
||||
|
||||
target "build-common" {
|
||||
pull = true
|
||||
}
|
||||
|
||||
target "5_9_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:5.9.0"]
|
||||
args = {
|
||||
WP_VERSION = "5.9.0"
|
||||
variable "REGISTRY_CACHE" {
|
||||
default = "ghcr.io/n0rthernl1ghts/wordpress-cache"
|
||||
}
|
||||
|
||||
######################
|
||||
# Define the functions
|
||||
######################
|
||||
|
||||
# Get the arguments for the build
|
||||
function "get-args" {
|
||||
params = [version, patch_version]
|
||||
result = {
|
||||
WP_VERSION = version
|
||||
WP_PATCH_VERSION = patch_version
|
||||
}
|
||||
}
|
||||
|
||||
target "5_9_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:5.9.1"]
|
||||
args = {
|
||||
WP_VERSION = "5.9.1"
|
||||
}
|
||||
# Get the cache-from configuration
|
||||
function "get-cache-from" {
|
||||
params = [version]
|
||||
result = [
|
||||
"type=registry,ref=${REGISTRY_CACHE}:${sha1("${version}-${BAKE_LOCAL_PLATFORM}")}"
|
||||
]
|
||||
}
|
||||
|
||||
target "5_9_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:5.9.2"]
|
||||
args = {
|
||||
WP_VERSION = "5.9.2"
|
||||
}
|
||||
# Get the cache-to configuration
|
||||
function "get-cache-to" {
|
||||
params = [version]
|
||||
result = [
|
||||
"type=registry,mode=max,ref=${REGISTRY_CACHE}:${sha1("${version}-${BAKE_LOCAL_PLATFORM}")}"
|
||||
]
|
||||
}
|
||||
|
||||
target "5_9_3" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:5", "docker.io/nlss/wordpress:5.9", "docker.io/nlss/wordpress:5.9.3"]
|
||||
args = {
|
||||
WP_VERSION = "5.9.3"
|
||||
}
|
||||
# Get list of image tags and registries
|
||||
# Takes a version and a list of extra versions to tag
|
||||
# eg. get-tags("6.2.0", ["6", "6.2", "latest"])
|
||||
function "get-tags" {
|
||||
params = [version, extra_versions]
|
||||
result = concat(
|
||||
[
|
||||
"ghcr.io/n0rthernl1ghts/wordpress:${version}"
|
||||
],
|
||||
flatten([
|
||||
for extra_version in extra_versions : [
|
||||
"ghcr.io/n0rthernl1ghts/wordpress:${extra_version}"
|
||||
]
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
target "6_0_0" {
|
||||
##########################
|
||||
# Define the build targets
|
||||
##########################
|
||||
|
||||
target "6_2_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:6.0.0"]
|
||||
args = {
|
||||
WP_VERSION = "6.0.0"
|
||||
}
|
||||
cache-from = get-cache-from("6.2.0")
|
||||
cache-to = get-cache-to("6.2.0")
|
||||
tags = get-tags("6.2.0", [])
|
||||
args = get-args("6.2.0", "5.9.1")
|
||||
}
|
||||
|
||||
target "6_0_1" {
|
||||
target "6_2_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:6.0.1"]
|
||||
args = {
|
||||
WP_VERSION = "6.0.1"
|
||||
}
|
||||
cache-from = get-cache-from("6.2.1")
|
||||
cache-to = get-cache-to("6.2.1")
|
||||
tags = get-tags("6.2.1", [])
|
||||
args = get-args("6.2.1", "5.9.1")
|
||||
}
|
||||
|
||||
target "6_0_2" {
|
||||
target "6_2_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:6.0.2"]
|
||||
args = {
|
||||
WP_VERSION = "6.0.2"
|
||||
}
|
||||
cache-from = get-cache-from("6.2.2")
|
||||
cache-to = get-cache-to("6.2.2")
|
||||
tags = get-tags("6.2.2", ["6.2"])
|
||||
args = get-args("6.2.2", "5.9.1")
|
||||
}
|
||||
|
||||
target "6_0_3" {
|
||||
target "6_3_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:6.0.3"]
|
||||
args = {
|
||||
WP_VERSION = "6.0.3"
|
||||
}
|
||||
cache-from = get-cache-from("6.3.0")
|
||||
cache-to = get-cache-to("6.3.0")
|
||||
tags = get-tags("6.3.0", [])
|
||||
args = get-args("6.3.0", "6.3.0")
|
||||
}
|
||||
|
||||
target "6_1_0" {
|
||||
target "6_3_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:6.1.0"]
|
||||
args = {
|
||||
WP_VERSION = "6.1.0"
|
||||
}
|
||||
cache-from = get-cache-from("6.3.1")
|
||||
cache-to = get-cache-to("6.3.1")
|
||||
tags = get-tags("6.3.1", [])
|
||||
args = get-args("6.3.1", "6.3.0")
|
||||
}
|
||||
|
||||
target "6_1_1" {
|
||||
target "6_3_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
tags = ["docker.io/nlss/wordpress:6", "docker.io/nlss/wordpress:6.1", "docker.io/nlss/wordpress:6.1.1", "docker.io/nlss/wordpress:latest"]
|
||||
args = {
|
||||
WP_VERSION = "6.1.1"
|
||||
}
|
||||
cache-from = get-cache-from("6.3.2")
|
||||
cache-to = get-cache-to("6.3.2")
|
||||
tags = get-tags("6.3.2", [])
|
||||
args = get-args("6.3.2", "6.3.0")
|
||||
}
|
||||
|
||||
target "6_4_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.0")
|
||||
cache-to = get-cache-to("6.4.0")
|
||||
tags = get-tags("6.4.0", [])
|
||||
args = get-args("6.4.0", "6.4.0")
|
||||
}
|
||||
|
||||
target "6_4_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.1")
|
||||
cache-to = get-cache-to("6.4.1")
|
||||
tags = get-tags("6.4.1", [])
|
||||
args = get-args("6.4.1", "6.4.0")
|
||||
}
|
||||
|
||||
target "6_4_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.2")
|
||||
cache-to = get-cache-to("6.4.2")
|
||||
tags = get-tags("6.4.2", [])
|
||||
args = get-args("6.4.2", "6.4.0")
|
||||
}
|
||||
|
||||
target "6_4_3" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.4.3")
|
||||
cache-to = get-cache-to("6.4.3")
|
||||
tags = get-tags("6.4.3", ["6.4"])
|
||||
args = get-args("6.4.3", "6.4.0")
|
||||
}
|
||||
|
||||
target "6_5_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.0")
|
||||
cache-to = get-cache-to("6.5.0")
|
||||
tags = get-tags("6.5.0", [])
|
||||
args = get-args("6.5.0", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_5_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.2")
|
||||
cache-to = get-cache-to("6.5.2")
|
||||
tags = get-tags("6.5.2", [])
|
||||
args = get-args("6.5.2", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_5_3" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.3")
|
||||
cache-to = get-cache-to("6.5.3")
|
||||
tags = get-tags("6.5.3", [])
|
||||
args = get-args("6.5.3", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_5_4" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.4")
|
||||
cache-to = get-cache-to("6.5.4")
|
||||
tags = get-tags("6.5.4", [])
|
||||
args = get-args("6.5.4", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_5_5" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.5.5")
|
||||
cache-to = get-cache-to("6.5.5")
|
||||
tags = get-tags("6.5.5", ["6.5"])
|
||||
args = get-args("6.5.5", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_6_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.6.0")
|
||||
cache-to = get-cache-to("6.6.0")
|
||||
tags = get-tags("6.6.0", [])
|
||||
args = get-args("6.6.0", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_6_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.6.1")
|
||||
cache-to = get-cache-to("6.6.1")
|
||||
tags = get-tags("6.6.1", [])
|
||||
args = get-args("6.6.1", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_6_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.6.2")
|
||||
cache-to = get-cache-to("6.6.2")
|
||||
tags = get-tags("6.6.2", ["6.6"])
|
||||
args = get-args("6.6.2", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_7_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.7.0")
|
||||
cache-to = get-cache-to("6.7.0")
|
||||
tags = get-tags("6.7.0", [])
|
||||
args = get-args("6.7.0", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_7_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.7.1")
|
||||
cache-to = get-cache-to("6.7.1")
|
||||
tags = get-tags("6.7.1", [])
|
||||
args = get-args("6.7.1", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_7_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.7.2")
|
||||
cache-to = get-cache-to("6.7.2")
|
||||
tags = get-tags("6.7.2", ["6.7"])
|
||||
args = get-args("6.7.2", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_8_0" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.8.0")
|
||||
cache-to = get-cache-to("6.8.0")
|
||||
tags = get-tags("6.8.0", [])
|
||||
args = get-args("6.8.0", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_8_1" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.8.1")
|
||||
cache-to = get-cache-to("6.8.1")
|
||||
tags = get-tags("6.8.1", [])
|
||||
args = get-args("6.8.1", "6.5.0")
|
||||
}
|
||||
|
||||
target "6_8_2" {
|
||||
inherits = ["build-dockerfile", "build-platforms", "build-common"]
|
||||
cache-from = get-cache-from("6.8.2")
|
||||
cache-to = get-cache-to("6.8.2")
|
||||
tags = get-tags("6.8.2", ["6", "6.8", "latest"])
|
||||
args = get-args("6.8.2", "6.5.0")
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ echo "> Two files are now downloaded to wp-src"
|
||||
echo "> Please update wp-src/mod-update-core.php with code bellow and then execute ./01-create-patch.sh"
|
||||
echo ""
|
||||
echo ""
|
||||
echo "wp_die("
|
||||
echo " wp_die("
|
||||
echo " __( 'Sorry, you are not allowed to update this site.' ) ."
|
||||
echo " ' Click <a href=\"https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates\">here</a> to learn why.'"
|
||||
echo ");"
|
||||
echo " ' Click <a href=\"https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates\" target=\"_blank\">here</a> to learn why.'"
|
||||
echo " );"
|
||||
echo ""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM wordpress:cli-php7.4 AS wordpress-builder
|
||||
FROM wordpress:cli-php8.1 AS wordpress-builder
|
||||
|
||||
USER root
|
||||
|
||||
@@ -7,8 +7,8 @@ WORKDIR "/wp"
|
||||
|
||||
ENV UID 1000
|
||||
ENV GID 1000
|
||||
ENV WP_LOCALE "en_US"
|
||||
ARG WP_VERSION "5.8.0"
|
||||
ENV WP_VERSION "${WP_VERSION}"
|
||||
ENV WP_LOCALE="en_US"
|
||||
ARG WP_VERSION="6.0.2"
|
||||
ENV WP_VERSION="${WP_VERSION}"
|
||||
|
||||
ENTRYPOINT ["/wp/entrypoint.sh"]
|
||||
|
||||
@@ -6,7 +6,7 @@ echo "> Downloading WordPress ${WP_VERSION} ..."
|
||||
WP_SHORT_VERSION=$(echo "${WP_VERSION}" | sed --expression='s/.0$//g');
|
||||
echo "> Short Version: ${WP_SHORT_VERSION}"
|
||||
|
||||
wp --allow-root --path="/tmp" core download --locale="${WP_LOCALE}" --version="${WP_SHORT_VERSION}"
|
||||
php -d "memory_limit=512M" /usr/local/bin/wp --allow-root --path="/tmp" core download --locale="${WP_LOCALE}" --version="${WP_SHORT_VERSION}"
|
||||
|
||||
if [ ! -f "/tmp/wp-admin/update-core.php" ]; then
|
||||
echo "X WordPress download failed"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG PHP_VERSION=7.4
|
||||
ARG PHP_VERSION=8.1
|
||||
ARG WP_VERSION=6.0.2
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ RUN set -eux \
|
||||
|
||||
|
||||
# Build/tag WPCLI
|
||||
FROM --platform=${TARGETPLATFORM} wordpress:cli-php${PHP_VERSION} AS wp-cli
|
||||
FROM wordpress:cli-php${PHP_VERSION} AS wp-cli
|
||||
|
||||
|
||||
|
||||
@@ -30,16 +30,18 @@ COPY --from=wp-cli ["/usr/local/bin/wp", "/usr/local/bin/wp"]
|
||||
# WP patch tests
|
||||
COPY --chmod=0777 ["./wp-patch-tests.sh", "/usr/local/bin/wp-patch-tests"]
|
||||
|
||||
|
||||
# Build final image
|
||||
ARG PHP_VERSION
|
||||
ARG WP_VERSION
|
||||
FROM --platform=${TARGETPLATFORM} wordpress:${WP_VERSION}-php${PHP_VERSION}-fpm-alpine
|
||||
FROM wordpress:${WP_VERSION}-php${PHP_VERSION}-fpm-alpine
|
||||
|
||||
|
||||
RUN set -eux \
|
||||
&& apk add --update --no-cache git patch less \
|
||||
&& apk add --update --no-cache gawk git grep patch less \
|
||||
&& git config --global --add safe.directory /var/www/html \
|
||||
&& echo "memory_limit = 512M" > /usr/local/etc/php/conf.d/memory-limit.ini \
|
||||
&& ln -sf /var/www/composer/vendor/bin/parallel-lint /usr/local/bin/php-parallel-lint
|
||||
|
||||
COPY --from=rootfs ["/", "/"]
|
||||
|
||||
WORKDIR /data
|
||||
|
||||
@@ -4,81 +4,122 @@
|
||||
trap scriptExitHandler EXIT
|
||||
|
||||
function scriptExitHandler() {
|
||||
LAST_EXIT_CODE=$?
|
||||
local lastExitCode=$?
|
||||
|
||||
if [ -n "${WP_DL_TEMP_DIR}" ] && [ -d "${WP_DL_TEMP_DIR}" ]; then
|
||||
rm -rf "${WP_DL_TEMP_DIR:?}"
|
||||
fi
|
||||
|
||||
if [ -n "${PHP_TESTS_TEMP_DIR}" ] && [ -d "${PHP_TESTS_TEMP_DIR}" ]; then
|
||||
rm -rf "${PHP_TESTS_TEMP_DIR:?}"
|
||||
fi
|
||||
|
||||
if [ "${LAST_EXIT_CODE}" = "0" ]; then
|
||||
if [ "${lastExitCode}" = "0" ]; then
|
||||
echo "> Script finished successfully"
|
||||
exit "${LAST_EXIT_CODE}"
|
||||
exit "${lastExitCode}"
|
||||
fi
|
||||
|
||||
echo "> Script finished with an error"
|
||||
exit "${LAST_EXIT_CODE}"
|
||||
return "${lastExitCode}"
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
PHP_TESTS_TEMP_DIR="$(mktemp -d -t XXXXXXXXXXX)"
|
||||
|
||||
function getFileCount() {
|
||||
ALL_DIRECTORIES=("${1:?Target dir is required}"/*)
|
||||
echo ${#ALL_DIRECTORIES[@]} # Sometimes, you just need a count
|
||||
}
|
||||
|
||||
function taskPrepareWpPatch() {
|
||||
WP_DL_TEMP_DIR="$(mktemp -d -t XXXXXXXXXXX)"
|
||||
PATCH_DIR=${1:?}
|
||||
set -eou pipefail
|
||||
|
||||
WP_WORK_LONG_VERSION="$(basename "${PATCH_DIR}")"
|
||||
WP_WORK_SHORT_VERSION="$(echo "${WP_WORK_LONG_VERSION:?}" | sed --expression='s/.0$//g')"
|
||||
wp --allow-root core download --locale="en_GB" --version="${WP_WORK_SHORT_VERSION}" --path="${WP_DL_TEMP_DIR}"
|
||||
local wpLongVersion="${1:?}"
|
||||
local patchDir="${2:?}"
|
||||
local downloadRoot="${3:?}"
|
||||
|
||||
# Define variables
|
||||
local wpShortVersion
|
||||
local downloadPath
|
||||
|
||||
wpShortVersion="$(echo "${wpLongVersion}" | sed --expression='s/.0$//g')"
|
||||
downloadPath="${downloadRoot}/${wpLongVersion}"
|
||||
|
||||
mkdir -p "${downloadPath}"
|
||||
|
||||
# Download WordPress
|
||||
wp --allow-root core download --locale="en_GB" --version="${wpShortVersion}" --path="${downloadPath}"
|
||||
|
||||
echo "> Applying patch"
|
||||
patch "${WP_DL_TEMP_DIR}/wp-admin/update-core.php" <"${PATCH_DIR}/wp-admin-update-core.patch"
|
||||
mv -v "${WP_DL_TEMP_DIR}/wp-admin/update-core.php" "${PHP_TESTS_TEMP_DIR}/update-core-${WP_WORK_LONG_VERSION}.php"
|
||||
patch "${downloadPath}/wp-admin/update-core.php" <"${patchDir}/wp-admin-update-core.patch"
|
||||
cp -v "${downloadPath}/wp-admin/update-core.php" "${PHP_TESTS_DIR}/update-core-${wpLongVersion}.php"
|
||||
|
||||
rm "${WP_DL_TEMP_DIR?}" -rf
|
||||
rm "${downloadPath}" -rf
|
||||
}
|
||||
|
||||
# For each patch, download appropriate WP version, apply patch and check if file syntax is correct afterwards
|
||||
for PATCH_DIR in patches/*/; do
|
||||
echo "> Deploying task ${PATCH_DIR}"
|
||||
function extractVersionsFromHCL() {
|
||||
local hclFile="${1:?HCL file path required}"
|
||||
|
||||
gawk '
|
||||
/args *= *get-args/ {
|
||||
if (match($0, /get-args\("([0-9]+\.[0-9]+\.[0-9]+)", *"([0-9]+\.[0-9]+\.[0-9]+)"\)/, arr)) {
|
||||
print arr[1], arr[2];
|
||||
}
|
||||
}
|
||||
' "${hclFile}"
|
||||
}
|
||||
|
||||
main() {
|
||||
PHP_TESTS_DIR="/data/test_files"
|
||||
export PHP_TESTS_DIR
|
||||
|
||||
mkdir -p "${PHP_TESTS_DIR}"
|
||||
|
||||
local patchDir
|
||||
|
||||
local wpLongVersion
|
||||
local wpPatchVersion
|
||||
local expectedPatchCount=0
|
||||
|
||||
declare -a versions
|
||||
mapfile -t versions < <(extractVersionsFromHCL /data/docker-bake.hcl)
|
||||
|
||||
for version in "${versions[@]}"; do
|
||||
wpLongVersion=$(echo "$version" | awk '{print $1}')
|
||||
wpPatchVersion=$(echo "$version" | awk '{print $2}')
|
||||
patchDir="/data/patches/${wpPatchVersion}"
|
||||
printf "Deploying task [Version: %s, Patch: %s, Path: %s]\n" "${wpLongVersion}" "${wpPatchVersion}" "${patchDir}"
|
||||
|
||||
# Introduce ~50ms overhead before deploying another task
|
||||
# Even shorter overhead helps. but better to be on safe side.
|
||||
# This should prevent concurrency issues
|
||||
sleep 0.05
|
||||
|
||||
# Run task concurrently
|
||||
taskPrepareWpPatch "${PATCH_DIR}" &
|
||||
done
|
||||
if [ ! -d "${patchDir}" ]; then
|
||||
printf "Error: Patch directory not found: %s\n" "${patchDir}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Waiting for all tasks to finish..."
|
||||
wait
|
||||
# Start the task in the background and capture the PID
|
||||
taskPrepareWpPatch "${wpLongVersion}" "${patchDir}" "/data/wp_src" &
|
||||
((expectedPatchCount++))
|
||||
done
|
||||
|
||||
# Make sure that directory is not empty
|
||||
if [ ! "$(ls -A "${PHP_TESTS_TEMP_DIR}")" ]; then
|
||||
echo "Waiting for all tasks to complete..."
|
||||
wait
|
||||
|
||||
# Make sure that directory is not empty
|
||||
if [ ! "$(ls -A "${PHP_TESTS_DIR}")" ]; then
|
||||
echo "Error: Target directory is empty"
|
||||
exit 1
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
NUMBER_OF_PATCHES="$(getFileCount patches)"
|
||||
NUMBER_OF_TEST_FILES="$(getFileCount "${PHP_TESTS_TEMP_DIR}")"
|
||||
local numberOfTestFiles
|
||||
numberOfTestFiles="$(getFileCount "${PHP_TESTS_DIR}")"
|
||||
|
||||
if [ "${NUMBER_OF_PATCHES}" != "${NUMBER_OF_TEST_FILES}" ]; then
|
||||
if [ "${expectedPatchCount}" != "${numberOfTestFiles}" ]; then
|
||||
echo "> Error - Unexpected number of files"
|
||||
echo " Expected: ${NUMBER_OF_PATCHES}"
|
||||
echo " Actual: ${NUMBER_OF_TEST_FILES}"
|
||||
exit 1
|
||||
fi
|
||||
echo " Expected: ${expectedPatchCount}"
|
||||
echo " Actual: ${numberOfTestFiles}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Run php-lint on resulting patch files
|
||||
php-parallel-lint "${PHP_TESTS_TEMP_DIR}" -s --blame --exclude vendor -p php
|
||||
exit $?
|
||||
# Run php-lint on resulting patch files
|
||||
if php-parallel-lint "${PHP_TESTS_DIR}" -s --blame --exclude vendor -p php; then
|
||||
printf "> Success. All of the %d generated patch files were valid.\n" "${expectedPatchCount}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
|
||||
161
docker-compose.yml
Normal file
161
docker-compose.yml
Normal file
@@ -0,0 +1,161 @@
|
||||
x-wordpress-configuration-env: &wordpress-configuration-env
|
||||
WORDPRESS_PLUGIN_LIST: "maintenance redis-cache"
|
||||
WORDPRESS_REDIS_HOST: redis
|
||||
WORDPRESS_CACHE: 1
|
||||
WORDPRESS_CACHE_KEY_SALT: 'Wp-'
|
||||
WORDPRESS_TABLE_PREFIX: 'wp_'
|
||||
WORDPRESS_DEBUG: 0
|
||||
DEFAULT_EMAIL: "webmaster@example.com"
|
||||
WORDPRESS_DB_USER: wordpress
|
||||
WORDPRESS_DB_NAME: wordpress
|
||||
WORDPRESS_DB_HOST: database
|
||||
WORDPRESS_CONFIG_EXTRA: |
|
||||
define('WP_AUTO_UPDATE_CORE', false);
|
||||
define('WP_SITEURL', 'http://localhost');
|
||||
define('WP_HOME', 'http://localhost');
|
||||
define('WP_CACHE', true);
|
||||
define('WP_CACHE_KEY_SALT', 'Wp-');
|
||||
define('WP_REDIS_HOST', "cache");
|
||||
define('DISABLE_WP_CRON', true);
|
||||
$$_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'] = false;
|
||||
|
||||
x-wordpress-init-env: &wordpress-init-env
|
||||
WORDPRESS_INIT_ENABLE: "true"
|
||||
WORDPRESS_INIT_ADMIN_USER: admin
|
||||
# WORDPRESS_INIT_ADMIN_PASSWORD is defined in secrets
|
||||
WORDPRESS_INIT_ADMIN_EMAIL: admin@example.com
|
||||
WORDPRESS_INIT_SITE_TITLE: "Your Example Site"
|
||||
WORDPRESS_INIT_SITE_URL: "http://localhost"
|
||||
|
||||
|
||||
networks:
|
||||
default:
|
||||
|
||||
secrets:
|
||||
database_root_password:
|
||||
file: ./.secrets/database_root_password.txt
|
||||
wordpress_database_password:
|
||||
file: ./.secrets/wordpress_database_password.txt
|
||||
wordpress_db_password:
|
||||
file: ./.secrets/wordpress_database_password.txt
|
||||
wordpress_auth_key:
|
||||
file: ./.secrets/wordpress_auth_key
|
||||
wordpress_secure_auth_key:
|
||||
file: ./.secrets/wordpress_secure_auth_key
|
||||
wordpress_logged_in_key:
|
||||
file: ./.secrets/wordpress_logged_in_key
|
||||
wordpress_nonce_key:
|
||||
file: ./.secrets/wordpress_nonce_key
|
||||
wordpress_auth_salt:
|
||||
file: ./.secrets/wordpress_auth_salt
|
||||
wordpress_secure_auth_salt:
|
||||
file: ./.secrets/wordpress_secure_auth_salt
|
||||
wordpress_logged_in_salt:
|
||||
file: ./.secrets/wordpress_logged_in_salt
|
||||
wordpress_nonce_salt:
|
||||
file: ./.secrets/wordpress_nonce_salt
|
||||
wordpress_init_admin_password:
|
||||
file: ./.secrets/wordpress_init_admin_password
|
||||
|
||||
|
||||
services:
|
||||
wordpress:
|
||||
image: ghcr.io/n0rthernl1ghts/wordpress:6.7.1
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: any
|
||||
healthcheck: # See: src/wp-utils/healthcheck
|
||||
test: [ "CMD", "/usr/local/bin/healthcheck" ]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
secrets:
|
||||
- wordpress_db_password
|
||||
- wordpress_auth_key
|
||||
- wordpress_secure_auth_key
|
||||
- wordpress_logged_in_key
|
||||
- wordpress_nonce_key
|
||||
- wordpress_auth_salt
|
||||
- wordpress_secure_auth_salt
|
||||
- wordpress_logged_in_salt
|
||||
- wordpress_nonce_salt
|
||||
- wordpress_init_admin_password
|
||||
environment:
|
||||
<<: [ *wordpress-configuration-env, *wordpress-init-env ]
|
||||
CRON_ENABLED: "false"
|
||||
# S6_KEEP_ENV: 0 # Uncomment to load secrets to environment
|
||||
labels: # This configures traefik - if you have it. You also need to make sure that this service is in the same network with Traefik instance
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.rule=Host(`example.com`)"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-http.entrypoints=web"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-https.tls=true"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-https.tls.certresolver=le"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-https.rule=Host(`example.com`)"
|
||||
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}-https.entrypoints=websecure"
|
||||
- "traefik.http.services.${COMPOSE_PROJECT_NAME}.loadbalancer.server.port=80"
|
||||
volumes:
|
||||
- ./data/wordpress/wp-content:/var/www/html/wp-content
|
||||
networks:
|
||||
default:
|
||||
|
||||
# It's a good idea to have a separate service for the cron job
|
||||
cron:
|
||||
extends:
|
||||
service: wordpress
|
||||
image: ghcr.io/n0rthernl1ghts/wordpress-cron:6.7.1
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M # Limit the memory for the cron job to 512 MB. This is a good practice to avoid memory leaks.
|
||||
environment:
|
||||
CRON_ENABLED: "true"
|
||||
|
||||
# Redis is optional, but it works really well for caching. If removed, please update x-wordpress-configuration-env
|
||||
cache:
|
||||
image: redis:alpine
|
||||
init: true
|
||||
healthcheck:
|
||||
test: ["CMD", "/usr/local/bin/redis-cli", "PING"]
|
||||
interval: 20s
|
||||
timeout: 3s
|
||||
retries: 3
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: any
|
||||
resources:
|
||||
limits:
|
||||
memory: 64M
|
||||
networks:
|
||||
default:
|
||||
|
||||
# Please update environment accordingly
|
||||
database:
|
||||
image: 'ghcr.io/n0rthernl1ghts/mariadb:10.11'
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart_policy:
|
||||
condition: any
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M # Should be adjusted accordingly to the website size. 512MB is usually enough for small website
|
||||
healthcheck:
|
||||
test: ["CMD", "/usr/bin/healthcheck"]
|
||||
interval: 30s
|
||||
timeout: 20s
|
||||
retries: 3
|
||||
environment:
|
||||
PUID: 1000
|
||||
PGID: 1000
|
||||
MARIADB_INIT_DATABASES: wordpress
|
||||
MARIADB_INIT_USERS: wordpress
|
||||
FILE__MARIADB_ROOT_PASSWORD: /run/secrets/database_root_password
|
||||
FILE__MARIADB_USER_wordpress_PASSWORD: /run/secrets/wordpress_database_password
|
||||
FORCE_CONFIG_OVERWRITE: 1
|
||||
volumes:
|
||||
- ./data/database/config:/config
|
||||
- ./data/database/data:/var/lib/mysql
|
||||
secrets:
|
||||
- database_root_password
|
||||
- wordpress_database_password
|
||||
networks:
|
||||
default:
|
||||
@@ -1,14 +0,0 @@
|
||||
--- update-core.php 2022-07-25 23:31:49.413445800 +0200
|
||||
+++ update-core.php 2022-07-25 23:35:11.026340149 +0200
|
||||
@@ -1096,6 +1096,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
|
||||
// Do the (un)dismiss actions before headers, so that they can redirect.
|
||||
@@ -1,14 +0,0 @@
|
||||
--- update-core.php 2022-07-25 23:40:10.667406949 +0200
|
||||
+++ update-core.php 2022-07-25 23:41:52.068913892 +0200
|
||||
@@ -1096,6 +1096,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
|
||||
// Do the (un)dismiss actions before headers, so that they can redirect.
|
||||
@@ -1,14 +0,0 @@
|
||||
--- update-core.php 2022-09-10 03:36:26.120553829 +0200
|
||||
+++ update-core.php 2022-09-10 03:37:29.638236917 +0200
|
||||
@@ -1096,6 +1096,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
|
||||
// Do the (un)dismiss actions before headers, so that they can redirect.
|
||||
@@ -1,14 +0,0 @@
|
||||
--- update-core.php 2022-11-02 21:28:47.121321629 +0100
|
||||
+++ update-core.php 2022-11-02 21:31:38.007567026 +0100
|
||||
@@ -1096,6 +1096,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
|
||||
// Do the (un)dismiss actions before headers, so that they can redirect.
|
||||
@@ -1,14 +0,0 @@
|
||||
--- update-core.php 2022-11-02 21:35:23.068067797 +0100
|
||||
+++ update-core.php 2022-11-02 21:36:03.955439331 +0100
|
||||
@@ -1096,6 +1096,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
|
||||
// Do the (un)dismiss actions before headers, so that they can redirect.
|
||||
@@ -1,14 +0,0 @@
|
||||
--- update-core.php 2023-01-20 13:36:28.762998072 +0100
|
||||
+++ update-core.php 2023-01-20 13:38:35.335180877 +0100
|
||||
@@ -1096,6 +1096,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
|
||||
// Do the (un)dismiss actions before headers, so that they can redirect.
|
||||
@@ -1,12 +1,12 @@
|
||||
--- update-core.php 2022-02-03 19:41:16.566727872 +0100
|
||||
+++ update-core.php 2022-02-03 19:44:43.875250278 +0100
|
||||
@@ -1088,6 +1088,11 @@
|
||||
--- update-core.php 2023-09-22 20:48:32.331308554 +0200
|
||||
+++ update-core.php 2023-09-22 20:49:26.927349080 +0200
|
||||
@@ -1131,6 +1131,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates" target="_blank">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
@@ -1,12 +1,12 @@
|
||||
--- update-core.php 2022-03-22 19:22:19.921705536 +0100
|
||||
+++ update-core.php 2022-03-22 19:22:41.242213723 +0100
|
||||
@@ -1096,6 +1096,11 @@
|
||||
--- update-core.php 2024-05-12 23:12:04.606527072 +0200
|
||||
+++ update-core.php 2024-05-12 23:18:40.981751231 +0200
|
||||
@@ -1148,6 +1148,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates" target="_blank">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
@@ -1,12 +1,12 @@
|
||||
--- update-core.php 2022-05-25 19:16:03.906128294 +0200
|
||||
+++ update-core.php 2022-05-25 19:16:56.079812565 +0200
|
||||
@@ -1096,6 +1096,11 @@
|
||||
--- update-core.php 2024-05-12 23:33:34.405330883 +0200
|
||||
+++ update-core.php 2024-05-12 23:33:54.551751539 +0200
|
||||
@@ -1155,6 +1155,11 @@
|
||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||
}
|
||||
|
||||
+ wp_die(
|
||||
+ __( 'Sorry, you are not allowed to update this site.' ) .
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates">here</a> to learn why.'
|
||||
+ ' Click <a href="https://github.com/N0rthernL1ghts/wordpress/wiki/WordPress-Core-Updates" target="_blank">here</a> to learn why.'
|
||||
+ );
|
||||
+
|
||||
check_admin_referer( 'upgrade-core' );
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
# Designed to replace original, overcomplicated entrypoint script from official wordpress docker repository
|
||||
# Why not use already available tools instead?!
|
||||
|
||||
# Register exit handler
|
||||
trap scriptExitHandler EXIT
|
||||
|
||||
function scriptExitHandler() {
|
||||
LAST_EXIT_CODE=$?
|
||||
if [ "${LAST_EXIT_CODE}" = "0" ]; then
|
||||
echo "> Script finished successfully"
|
||||
exit "${LAST_EXIT_CODE}"
|
||||
fi
|
||||
|
||||
echo "> Script finished with an error"
|
||||
exit "${LAST_EXIT_CODE}"
|
||||
}
|
||||
|
||||
# Applies patch for making WordPress updates impossible
|
||||
function disableUpdatesPatch() {
|
||||
DISABLE_WP_UPDATES="${ENFORCE_DISABLE_WP_UPDATES:-true}"
|
||||
if [ "${DISABLE_WP_UPDATES}" != "false" ]; then
|
||||
echo "> Disabling WordPress updates..."
|
||||
patch /var/www/html/wp-admin/update-core.php </etc/wp-mods/wp-admin-update-core.patch
|
||||
echo "> Making the patched file read-only..."
|
||||
chmod 0440 /var/www/html/wp-admin/update-core.php
|
||||
fi
|
||||
}
|
||||
|
||||
# Deletes known WordPress files
|
||||
function deleteWordPress() {
|
||||
echo "> Deleting WordPress installation (core files)"
|
||||
|
||||
# Instead of one-line find, we're taking a bit conservative approach and separating file and directory removal
|
||||
# This is to ensure that this script never runs on unintended set of files as it's data loss risk
|
||||
rm -rf "/var/www/${WEB_ROOT}/"{wp-includes,wp-admin}
|
||||
rm -rf "/var/www/${WEB_ROOT}/"{.htaccess,index.php,license.txt,readme.html,wp-activate.php,wp-blog-header.php,wp-comments-post.php,wp-config-sample.php.php,wp-cron.php,wp-links-opml.php,wp-load.php,wp-login.php,wp-mail.php,wp-settings.php,wp-signup.php,wp-trackback.php,xmlrpc.php}
|
||||
}
|
||||
|
||||
# Main function
|
||||
function main() {
|
||||
# Removes trailing zero if found
|
||||
# This is required due to inconsistencies between WodPress docker image versioning and wp-cli core download
|
||||
# If patch version is 0, it is not considered by wp-cli.
|
||||
WP_VERSION=$(echo "${WP_VERSION:?}" | sed --expression='s/.0$//g')
|
||||
WP_LOCALE="${WP_LOCALE:?}"
|
||||
|
||||
echo "> Verifying 'WordPress ${WP_VERSION}' installation..."
|
||||
WP_INSTALLED_VERSION="$(wp core version)"
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "${WP_INSTALLED_VERSION}" ]; then
|
||||
echo "> WordPress is not present"
|
||||
echo "> Downloading 'WordPress ${WP_VERSION}'..."
|
||||
deleteWordPress
|
||||
wp core download --locale="${WP_LOCALE}" --version="${WP_VERSION}"
|
||||
disableUpdatesPatch
|
||||
elif [ "${WP_INSTALLED_VERSION}" != "${WP_VERSION}" ]; then
|
||||
echo "> WordPress version mismatch"
|
||||
echo "> Expected version: ${WP_VERSION}"
|
||||
echo "> Detected version: ${WP_INSTALLED_VERSION}"
|
||||
echo "> Scraping current files"
|
||||
deleteWordPress
|
||||
echo "> Downloading WordPress version '${WP_VERSION}'..."
|
||||
wp core download --locale="${WP_LOCALE}" --version="${WP_VERSION}"
|
||||
disableUpdatesPatch
|
||||
else
|
||||
echo "> Identified 'WordPress ${WP_VERSION}'"
|
||||
fi
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
exit $?
|
||||
@@ -1,95 +0,0 @@
|
||||
#!/usr/bin/with-contenv bash
|
||||
|
||||
# Register exit handler
|
||||
trap scriptExitHandler EXIT
|
||||
|
||||
function scriptExitHandler() {
|
||||
LAST_EXIT_CODE=$?
|
||||
if [ "${LAST_EXIT_CODE}" = "0" ]; then
|
||||
echo "> Script finished successfully"
|
||||
exit "${LAST_EXIT_CODE}"
|
||||
fi
|
||||
|
||||
echo "> Script finished with an error"
|
||||
exit "${LAST_EXIT_CODE}"
|
||||
}
|
||||
|
||||
# Check if plugin installed. This is very basic check that doesn't involve database
|
||||
function isPluginInstalled() {
|
||||
if [ -d "${PLUGIN_PATH}" ] || [ -f "${PLUGIN_PATH}.php" ]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Install plugin
|
||||
function installPlugin() {
|
||||
wp plugin install "${@}" >/dev/null 2>&1
|
||||
sleep 0.5
|
||||
}
|
||||
|
||||
# Main function
|
||||
function main() {
|
||||
PLUGIN_LIST="${WORDPRESS_PLUGIN_LIST:-}"
|
||||
PLUGIN_STRICT_INSTALL="${WORDPRESS_PLUGIN_INSTALL_STRICT:-false}"
|
||||
WP_CONTENT_PATH="/var/www/${WEB_ROOT}/wp-content"
|
||||
|
||||
echo "> Automated WordPress Plugin Installer"
|
||||
if [ -z "${PLUGIN_LIST}" ]; then
|
||||
echo "> No plugins defined. Skipping installation."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "> About to install defined plugins"
|
||||
for PLUGIN_EXPR in ${PLUGIN_LIST}; do
|
||||
IFS=':' read -ra PLUGIN <<<"${PLUGIN_EXPR}"
|
||||
|
||||
PLUGIN_PATH="${WP_CONTENT_PATH}/plugins/${PLUGIN[0]}"
|
||||
|
||||
if isPluginInstalled; then
|
||||
echo "> Plugin '${PLUGIN[0]}' already installed and will be skipped."
|
||||
continue
|
||||
fi
|
||||
|
||||
WP_PLUGIN_INSTALL_ARGS="${PLUGIN[0]}"
|
||||
|
||||
if [ -n "${PLUGIN[1]}" ]; then
|
||||
WP_PLUGIN_INSTALL_ARGS="${WP_PLUGIN_INSTALL_ARGS} --version=${PLUGIN[1]}"
|
||||
fi
|
||||
|
||||
echo "> Installing plugin '${PLUGIN[0]}' version '${PLUGIN[1]}'"
|
||||
installPlugin "${WP_PLUGIN_INSTALL_ARGS}" &
|
||||
done
|
||||
|
||||
echo "> Waiting for all plugins to install..."
|
||||
wait
|
||||
|
||||
# Plugins are installed concurrently, so we need to verify if installed, separately
|
||||
echo "> About to verify install of defined plugins"
|
||||
|
||||
FAILED_COUNT=0
|
||||
|
||||
for PLUGIN_EXPR in ${PLUGIN_LIST}; do
|
||||
IFS=':' read -ra PLUGIN <<<"${PLUGIN_EXPR}"
|
||||
|
||||
PLUGIN_PATH="${WP_CONTENT_PATH}/plugins/${PLUGIN[0]}"
|
||||
|
||||
if isPluginInstalled; then
|
||||
echo "> Plugin '${PLUGIN[0]}' installed"
|
||||
continue
|
||||
fi
|
||||
|
||||
((FAILED_COUNT = FAILED_COUNT + 1))
|
||||
echo "> Warning: Plugin '${PLUGIN[0]}' failed to install"
|
||||
done
|
||||
|
||||
echo "> Total of ${FAILED_COUNT} plugins failed to install"
|
||||
|
||||
if [ "${PLUGIN_STRICT_INSTALL}" = "true" ] && [ ${FAILED_COUNT} != "0" ]; then
|
||||
echo "> WORDPRESS_PLUGIN_INSTALL_STRICT is set to true. Terminating with non-zero exit code"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
exit $?
|
||||
140
rootfs/etc/s6-overlay/s6-rc.d/init-install-resources/run
Executable file
140
rootfs/etc/s6-overlay/s6-rc.d/init-install-resources/run
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
# Install plugin
|
||||
installPlugin() {
|
||||
local pluginArchive
|
||||
pluginArchive="$(wp-plugin download "${@}" 2>/dev/null)"
|
||||
if [ -z "${pluginArchive}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
wp-plugin unpack "${@}"
|
||||
return $?
|
||||
}
|
||||
|
||||
checkInstalled() {
|
||||
local failedCount=0
|
||||
local pluginSlug
|
||||
local pluginExpr
|
||||
local plugin
|
||||
|
||||
for pluginExpr in ${PLUGIN_LIST}; do
|
||||
IFS=':' read -ra plugin <<<"${pluginExpr}"
|
||||
|
||||
pluginSlug="${plugin[0]}"
|
||||
|
||||
if wp-plugin check "${pluginSlug}"; then
|
||||
echo "Plugin '${pluginSlug}' installed"
|
||||
continue
|
||||
fi
|
||||
|
||||
((failedCount = failedCount + 1))
|
||||
echo "Warning: Plugin '${pluginSlug}' failed to install"
|
||||
done
|
||||
|
||||
if [ "${failedCount}" = "0" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Total of ${failedCount} plugins failed to install"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Plugins installer
|
||||
taskInstallPlugins() {
|
||||
export WP_PLUGINS_PATH
|
||||
|
||||
local concurrencyLimit="${WP_PLUGINS_INSTALL_CONCURRENCY:-5}"
|
||||
local pluginSlug
|
||||
local pluginVersion
|
||||
local pluginExpr
|
||||
local plugin
|
||||
|
||||
echo "Automated WordPress Plugins Installer"
|
||||
if [ -z "${PLUGIN_LIST}" ]; then
|
||||
echo "No plugins defined. Skipping installation."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local jobs=()
|
||||
|
||||
echo "About to install defined plugins"
|
||||
for pluginExpr in ${PLUGIN_LIST}; do
|
||||
|
||||
# Split plugin name and version
|
||||
IFS=':' read -ra plugin <<<"${pluginExpr}"
|
||||
|
||||
pluginSlug="${plugin[0]}"
|
||||
pluginVersion="${plugin[1]:-}"
|
||||
|
||||
if wp-plugin check "${pluginSlug}"; then
|
||||
echo "Plugin '${pluginSlug}' already installed and will be skipped."
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -n "${pluginVersion}" ]; then
|
||||
echo "Installing plugin '${pluginSlug}' version '${pluginVersion}'"
|
||||
installPlugin "${pluginSlug}" "${pluginVersion}" &
|
||||
jobs+=($!)
|
||||
else
|
||||
echo "Installing plugin '${pluginSlug}'"
|
||||
installPlugin "${pluginSlug}" &
|
||||
jobs+=($!)
|
||||
fi
|
||||
|
||||
# Run maximum of X plugin installs in parallel
|
||||
while [ "$(jobs | wc -l)" -ge "${concurrencyLimit}" ]; do
|
||||
echo " Waiting for batch of ${concurrencyLimit} plugins to install..."
|
||||
wait
|
||||
done
|
||||
done
|
||||
|
||||
echo "Waiting for all tasks to finish..."
|
||||
|
||||
for pid in "${jobs[@]}"; do
|
||||
wait "$pid"
|
||||
done
|
||||
|
||||
# Plugins are installed concurrently, so we need to verify if installed, separately
|
||||
echo "About to verify install of defined plugins"
|
||||
|
||||
if ! checkInstalled; then
|
||||
echo "Some plugins failed to install"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "All plugins installed successfully"
|
||||
return 0
|
||||
}
|
||||
|
||||
# init-install-resources main
|
||||
main() {
|
||||
exec > >(while read -r line; do echo "[init-install-resources] ${line}"; done) 2>&1
|
||||
|
||||
PLUGIN_LIST="${WORDPRESS_PLUGIN_LIST:-}"
|
||||
WP_CONTENT_PATH="/var/www/html/wp-content"
|
||||
WP_PLUGINS_PATH="${WP_CONTENT_PATH}/plugins"
|
||||
|
||||
echo "Automated WordPress Resources Installer"
|
||||
|
||||
local jobs=()
|
||||
|
||||
export WP_CONTENT_PATH
|
||||
|
||||
WP_PLUGINS_INSTALL_CONCURRENCY="${WP_PLUGINS_INSTALL_CONCURRENCY:-5}"
|
||||
export PLUGIN_LIST WP_PLUGINS_PATH WP_PLUGINS_INSTALL_CONCURRENCY
|
||||
taskInstallPlugins "${@}" &
|
||||
jobs+=($!)
|
||||
|
||||
echo "Waiting for all tasks to complete"
|
||||
|
||||
# Wait for all tasks but do not wait for the background task
|
||||
for pid in "${jobs[@]}"; do
|
||||
wait "$pid"
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-install-resources/up
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-install-resources/up
Normal file
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-install-resources/run
|
||||
66
rootfs/etc/s6-overlay/s6-rc.d/init-install-wordpress/run
Executable file
66
rootfs/etc/s6-overlay/s6-rc.d/init-install-wordpress/run
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
await_database() {
|
||||
# Settings
|
||||
local interval="1"
|
||||
local status
|
||||
|
||||
# For loop
|
||||
for i in {1..30}
|
||||
do
|
||||
# Check if database is reachable
|
||||
status="$(wp core is-installed 2>&1)"
|
||||
|
||||
# Check if status contains database connection (partial match)
|
||||
if echo "${status}" | grep -q "Error establishing"; then
|
||||
echo "Database is not reachable, retrying in ${interval} seconds [${i}/30]"
|
||||
sleep "${interval}"
|
||||
continue
|
||||
fi
|
||||
|
||||
return 0
|
||||
done
|
||||
}
|
||||
|
||||
# init-install-wordpress main
|
||||
main() {
|
||||
# This will prepend service name to all output from here
|
||||
exec > >(while read -r line; do echo "[init-install-wordpress] ${line}"; done) 2>&1
|
||||
|
||||
if [ "${WORDPRESS_INIT_ENABLE:-false}" = "false" ]; then
|
||||
echo "WordPress init is disabled"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if WordPress is already installed
|
||||
if wp core is-installed 2>&1; then
|
||||
echo "WordPress is already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! await_database; then
|
||||
echo "Error: Database is not reachable"
|
||||
return 1
|
||||
fi
|
||||
|
||||
wp core install \
|
||||
--url="${WORDPRESS_INIT_SITE_URL:?}" \
|
||||
--title="${WORDPRESS_INIT_SITE_TITLE:-WordPress}" \
|
||||
--admin_user="${WORDPRESS_INIT_ADMIN_USER:?}" \
|
||||
--admin_password="${WORDPRESS_INIT_ADMIN_PASSWORD:?}" \
|
||||
--admin_email="${WORDPRESS_INIT_ADMIN_EMAIL:?}" \
|
||||
--skip-email
|
||||
|
||||
sleep 0.5
|
||||
|
||||
# Check if WordPress is already installed
|
||||
if wp core is-installed 2>&1; then
|
||||
echo "WordPress installed successfully at ${WORDPRESS_INIT_SITE_URL}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Error: WordPress installation failed"
|
||||
return 1
|
||||
}
|
||||
main
|
||||
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-install-wordpress/up
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-install-wordpress/up
Normal file
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-install-wordpress/run
|
||||
64
rootfs/etc/s6-overlay/s6-rc.d/init-verify-wordpress/run
Executable file
64
rootfs/etc/s6-overlay/s6-rc.d/init-verify-wordpress/run
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
# Designed to replace original, overcomplicated entrypoint script from official wordpress docker repository
|
||||
# Why not use already available tools instead?!
|
||||
|
||||
# Register exit handler
|
||||
trap scriptExitHandler EXIT
|
||||
|
||||
function scriptExitHandler() {
|
||||
local lastExitCode=$?
|
||||
if [ "${lastExitCode}" = "0" ]; then
|
||||
echo "Script finished successfully"
|
||||
exit "${lastExitCode}"
|
||||
fi
|
||||
|
||||
echo "Script finished with an error"
|
||||
exit "${lastExitCode}"
|
||||
}
|
||||
|
||||
function reportUnhealthy() {
|
||||
echo "${1:?REASON is required}" >"/tmp/.wp-unhealthy"
|
||||
}
|
||||
|
||||
# init-verify-wordpress main
|
||||
function main() {
|
||||
|
||||
exec > >(while read -r line; do echo "[init-verify-wordpress] ${line}"; done) 2>&1
|
||||
|
||||
local wpCurrentVersion
|
||||
local wpInstalledVersion
|
||||
|
||||
# Removes trailing zero if found
|
||||
# This is required due to inconsistencies between WodPress docker image versioning and wp-cli core download
|
||||
# If patch version is 0, it is not considered by wp-cli.
|
||||
wpCurrentVersion=$(echo "${WP_VERSION:?}" | sed --expression='s/.0$//g')
|
||||
|
||||
echo "Verifying 'WordPress ${wpCurrentVersion}' installation..."
|
||||
wpInstalledVersion="$(wp core version)"
|
||||
|
||||
set -e
|
||||
|
||||
rm -f "/tmp/.wp-unhealthy"
|
||||
if [ -z "${wpInstalledVersion}" ]; then
|
||||
echo "Error: WordPress installation does not seem to be present or valid. Continuing anyway..."
|
||||
|
||||
reportUnhealthy "WP_NOT_PRESENT"
|
||||
return 0
|
||||
elif [ "${wpInstalledVersion}" != "${wpCurrentVersion}" ]; then
|
||||
echo "WARNING! WordPress version mismatch"
|
||||
echo " Expected version: ${wpCurrentVersion}"
|
||||
echo " Detected version: ${wpInstalledVersion}"
|
||||
echo "Seems like WordPress installation got updated outside image scope"
|
||||
echo " - This is dangerous as changes will not persist when container is recreated which might lead to inconsistencies between installation and the database."
|
||||
echo " - You should assume that recreating the container will render the website inoperable."
|
||||
echo " - Please make sure that you're running image: nlss/wordpress:${wpCurrentVersion}"
|
||||
reportUnhealthy "WP_VERSION_MISMATCH"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Identified 'WordPress ${wpCurrentVersion}'"
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-verify-wordpress/type
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-verify-wordpress/type
Normal file
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-verify-wordpress/up
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-verify-wordpress/up
Normal file
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-verify-wordpress/run
|
||||
35
rootfs/etc/s6-overlay/s6-rc.d/init-webuser-permissions/run
Executable file
35
rootfs/etc/s6-overlay/s6-rc.d/init-webuser-permissions/run
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
fix_permissions() {
|
||||
/usr/local/bin/attr /var/www true www-data:www-data 0770 2771 &
|
||||
/usr/local/bin/attr /var/www/html/wp-content true www-data:www-data 2755 2755 &
|
||||
}
|
||||
|
||||
run_process() {
|
||||
local counter=1
|
||||
local wait_pid="${1}"
|
||||
|
||||
# Print status message every ~5 seconds
|
||||
while kill -0 $wait_pid 2>/dev/null; do
|
||||
if [ $((counter % 5)) -eq 0 ]; then
|
||||
echo "Process hasn't finished yet [${counter}]"
|
||||
fi
|
||||
|
||||
counter=$((counter + 1))
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
# init-webuser-permissions main
|
||||
main() {
|
||||
# This will prepend service name to all output from here
|
||||
exec > >(while read line; do echo "[init-webuser-permissions] ${line}"; done) 2>&1
|
||||
|
||||
fix_permissions &
|
||||
pid=$!
|
||||
|
||||
echo "Running fix_permissions with PID ${pid} in foreground..."
|
||||
run_process "${pid}" &
|
||||
}
|
||||
main
|
||||
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-webuser-permissions/run
|
||||
85
rootfs/etc/s6-overlay/s6-rc.d/init-wpconfig-verify/run
Executable file
85
rootfs/etc/s6-overlay/s6-rc.d/init-wpconfig-verify/run
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
checkSaltsEnv() {
|
||||
if [ -z "${WORDPRESS_AUTH_KEY}" ]; then
|
||||
echo "- WORDPRESS_AUTH_KEY is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_SECURE_AUTH_KEY}" ]; then
|
||||
echo "- WORDPRESS_SECURE_AUTH_KEY is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_LOGGED_IN_KEY}" ]; then
|
||||
echo "- WORDPRESS_LOGGED_IN_KEY is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_NONCE_KEY}" ]; then
|
||||
echo "- WORDPRESS_NONCE_KEY is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_AUTH_SALT}" ]; then
|
||||
echo "- WORDPRESS_AUTH_SALT is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_SECURE_AUTH_SALT}" ]; then
|
||||
echo "- WORDPRESS_SECURE_AUTH_SALT is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_LOGGED_IN_SALT}" ]; then
|
||||
echo "- WORDPRESS_LOGGED_IN_SALT is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_NONCE_SALT}" ]; then
|
||||
echo "- WORDPRESS_NONCE_SALT is not set"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
checkDatabaseEnv() {
|
||||
if [ -z "${WORDPRESS_DB_HOST}" ]; then
|
||||
echo "- WORDPRESS_DB_HOST is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_DB_USER}" ]; then
|
||||
echo "- WORDPRESS_DB_USER is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_DB_PASSWORD}" ]; then
|
||||
echo "- WORDPRESS_DB_PASSWORD is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "${WORDPRESS_DB_NAME}" ]; then
|
||||
echo "- WORDPRESS_DB_NAME is not set"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# init-wpconfig-verify main
|
||||
main() {
|
||||
# This will prepend service name to all output from here
|
||||
exec > >(while read -r line; do echo "[init-wpconfig-verify] ${line}"; done) 2>&1
|
||||
|
||||
echo "Checking salts..."
|
||||
if ! checkSaltsEnv; then
|
||||
echo "^^^ Some or all of the salts are not set. Cannot continue."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Checking database configuration..."
|
||||
if ! checkDatabaseEnv; then
|
||||
echo "^^^ Some or all of the database configuration not set. Cannot continue."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
main
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpconfig-verify/type
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpconfig-verify/type
Normal file
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpconfig-verify/up
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpconfig-verify/up
Normal file
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-wpconfig-verify/run
|
||||
24
rootfs/etc/s6-overlay/s6-rc.d/init-wpcontent/run
Executable file
24
rootfs/etc/s6-overlay/s6-rc.d/init-wpcontent/run
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
# init-wpcontent main
|
||||
main() {
|
||||
# This will prepend service name to all output from here
|
||||
exec > >(while read -r line; do echo "[init-wpcontent] ${line}"; done) 2>&1
|
||||
|
||||
local wpContentDir="/var/www/html/wp-content"
|
||||
local wpThemesDir="${wpContentDir}/themes"
|
||||
|
||||
# If themes directory is empty
|
||||
if [ ! -d "${wpThemesDir}" ] || [ -z "$(ls -A "${wpThemesDir}")" ]; then
|
||||
if [ "${WORDPRESS_INIT_NO_SYNC_THEMES:-false}" = "true" ]; then
|
||||
echo "Warning: Themes directory is empty, but sync is disabled"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Themes directory is empty, copying default themes"
|
||||
rsync -a --ignore-existing --stats /usr/src/wordpress/wp-content/themes "${wpContentDir}/"
|
||||
return
|
||||
fi
|
||||
}
|
||||
main
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpcontent/type
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpcontent/type
Normal file
@@ -0,0 +1 @@
|
||||
oneshot
|
||||
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpcontent/up
Normal file
1
rootfs/etc/s6-overlay/s6-rc.d/init-wpcontent/up
Normal file
@@ -0,0 +1 @@
|
||||
/etc/s6-overlay/s6-rc.d/init-wpcontent/run
|
||||
@@ -1,40 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name {{ getenv "VIRTUAL_HOST" | strings.ReplaceAll "," " " }};
|
||||
set $base /var/www;
|
||||
root $base/{{ getenv "WEB_ROOT" }};
|
||||
|
||||
# security
|
||||
include nginxconfig.io/security.conf;
|
||||
|
||||
# logging
|
||||
access_log /var/log/nginx/app-access.log;
|
||||
error_log /var/log/nginx/app-error.log warn;
|
||||
|
||||
# index.php
|
||||
index index.php;
|
||||
|
||||
# index.php fallback
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
#Add trailing slash to */wp-admin requests.
|
||||
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
|
||||
|
||||
# handle .php
|
||||
location ~ \.php$ {
|
||||
fastcgi_intercept_errors on;
|
||||
include nginxconfig.io/php_fastcgi.conf;
|
||||
}
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
|
||||
expires max;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# additional config
|
||||
include nginxconfig.io/general.conf;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
/usr/local/bin/wp-cli --allow-root --path="/var/www/${WEB_ROOT}" "$@"
|
||||
3
rootfs/var/www/html/index.php
Normal file
3
rootfs/var/www/html/index.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
echo 'Hello World!';
|
||||
51
src/init-utils/init-wp
Executable file
51
src/init-utils/init-wp
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
get-repository-root() {
|
||||
git rev-parse --show-toplevel
|
||||
}
|
||||
|
||||
generate-secrets-password() {
|
||||
set -e
|
||||
local length="${1:?}"
|
||||
local secret="${2:?}"
|
||||
|
||||
# Set path to the secret file
|
||||
local secretPath="${SCRIPT_ROOT}/.secrets/${secret}.txt"
|
||||
|
||||
if [ -f "${secretPath}" ] && [ -s "${secretPath}" ]; then
|
||||
echo "> Not overwritting already existing secret ${secret}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
export LC_ALL=C
|
||||
|
||||
local randomString
|
||||
randomString="$(tr -dc 'a-zA-Z0-9!@#$%^&*()-=_+[]{};:,.<>?`~' </dev/urandom | head -c "${length}")"
|
||||
|
||||
echo "> Writting ${#randomString} bytes to ${secretPath}"
|
||||
echo -n "${randomString}" >"${secretPath}"
|
||||
}
|
||||
|
||||
main() {
|
||||
SCRIPT_ROOT="$(get-repository-root)"
|
||||
export SCRIPT_ROOT
|
||||
|
||||
mkdir -p "${SCRIPT_ROOT}/.secrets" &
|
||||
mkdir -p "${SCRIPT_ROOT}/data" &
|
||||
wait
|
||||
|
||||
generate-secrets-password 32 wordpress_database_password &
|
||||
generate-secrets-password 32 database_root_password &
|
||||
wait
|
||||
|
||||
{
|
||||
echo "WORDPRESS_DB_USER='wordpress'"
|
||||
echo "WORDPRESS_DB_NAME='wordpress'"
|
||||
echo "WORDPRESS_DB_PASSWORD='$(cat "${SCRIPT_ROOT}/.secrets/wordpress_database_password.txt")'"
|
||||
echo "WORDPRESS_DB_HOST='database'"
|
||||
} >"${SCRIPT_ROOT}/.secrets/wp-database.env"
|
||||
|
||||
echo "Rewrote ${SCRIPT_ROOT}/.secrets/wp-database.env file"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
7
src/utils/random-string
Executable file
7
src/utils/random-string
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
main() {
|
||||
local length="${1:?}"
|
||||
tr -dc 'a-zA-Z0-9!@#$%^&*()-=_+[]{};:,.<>?`~' </dev/urandom | head -c "${length}"
|
||||
}
|
||||
main "${@}"
|
||||
21
src/wp-utils/healthcheck
Executable file
21
src/wp-utils/healthcheck
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function main() {
|
||||
local fullCheck="${1:-false}"
|
||||
|
||||
if [ -f "/tmp/.wp-unhealthy" ]; then
|
||||
echo "Error: WordPress health is compromised: $(cat "/tmp/.wp-unhealthy")"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# If fullCheck is not requested, site functionality check with curl is skipped
|
||||
if [ "${fullCheck}" = "false" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
curl -sSf --output "/dev/null" "http://localhost/"
|
||||
return $?
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
exit $?
|
||||
3
src/wp-utils/wp
Executable file
3
src/wp-utils/wp
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
/usr/local/bin/wp-cli --allow-root --path="/var/www/html" "$@"
|
||||
36
src/wp-utils/wp-apply-patch
Executable file
36
src/wp-utils/wp-apply-patch
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# Applies patch for preventing WordPress updates
|
||||
main() {
|
||||
local patchFile="${1:?PATCH_FILE is required}"
|
||||
local targetFile="${2:?TARGET_FILE is required}"
|
||||
|
||||
if [ ! -f "${patchFile}" ]; then
|
||||
echo "> No such file [PATCH]: ${patchFile}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${targetFile}" ]; then
|
||||
echo "> No such file [TARGET]: ${targetFile}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "> Loading patch ${patchFile}"
|
||||
echo " Patching '${targetFile}'..."
|
||||
patch --verbose "${targetFile}" <"${patchFile}"
|
||||
|
||||
local markReadOnly="${3:-true}"
|
||||
if [ "${markReadOnly}" = "true" ]; then
|
||||
# This is done in order to prevent WordPress overwriting the file
|
||||
echo " Marking the patched file read-only..."
|
||||
chmod 0440 "${targetFile}"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Usage: main /etc/wp-mods/wp-admin-update-core.patch /var/www/html/wp-admin/update-core.php ?true|false
|
||||
main "${@}"
|
||||
exit $?
|
||||
6
src/wp-utils/wp-generate-salt
Executable file
6
src/wp-utils/wp-generate-salt
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
main() {
|
||||
src/utils/random-string "${@}"
|
||||
}
|
||||
main "${@}"
|
||||
23
src/wp-utils/wp-generate-salts
Executable file
23
src/wp-utils/wp-generate-salts
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
main() {
|
||||
local secretsDir="${DOCKER_SECRETS_DIR:-./.secrets}"
|
||||
local keys=("AUTH_KEY" "SECURE_AUTH_KEY" "LOGGED_IN_KEY" "NONCE_KEY" "AUTH_SALT" "SECURE_AUTH_SALT" "LOGGED_IN_SALT" "NONCE_SALT")
|
||||
|
||||
mkdir -p "${secretsDir}"
|
||||
|
||||
for key in "${keys[@]}"; do
|
||||
value="$(src/wp-utils/wp-generate-salt 64)"
|
||||
secretName="wordpress_${key,,}"
|
||||
secretFile="${secretsDir}/${secretName}"
|
||||
|
||||
if [ -f "${secretFile}" ]; then
|
||||
printf "Warning: Secret %s already exists and will be overwritten\n" "${secretName}"
|
||||
fi
|
||||
|
||||
printf "Secret %s: Wrote %d bytes to %s\n" "${secretName}" "${#value}" "${secretFile}"
|
||||
printf "%s" "${value}" > "${secretFile}"
|
||||
done
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
120
src/wp-utils/wp-plugin
Executable file
120
src/wp-utils/wp-plugin
Executable file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Download plugin (curl)
|
||||
# $1 - plugin slug
|
||||
# $2 - plugin version (optional)
|
||||
# Returns 0 on success, X on failure
|
||||
download() {
|
||||
local pluginSlug="${1:?download: PLUGIN_SLUG is required}"
|
||||
local pluginVersion="${2:-}"
|
||||
local pluginFilename="${pluginSlug}.zip"
|
||||
|
||||
if [ -n "${pluginVersion}" ]; then
|
||||
pluginFilename="${pluginSlug}.${pluginVersion}.zip"
|
||||
fi
|
||||
|
||||
curl --fail -gsO "https://downloads.wordpress.org/plugin/${pluginFilename}" || return $?
|
||||
echo "${pluginFilename}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Unpack plugin (unzip)
|
||||
# $1 - plugin slug
|
||||
# $2 - plugin version (optional)
|
||||
# $3 - target directory (optional)
|
||||
# Returns 0 on success, 1 on failure
|
||||
unpack() {
|
||||
local pluginsDir="${TARGET_PLUGINS_DIR:?check: TARGET_PLUGINS_DIR is required}"
|
||||
local pluginSlug="${1:?unpack: PLUGIN_SLUG is required}"
|
||||
local pluginVersion="${2:-}"
|
||||
local pluginFilename="${pluginSlug}.zip"
|
||||
|
||||
if [ -n "${pluginVersion}" ]; then
|
||||
pluginFilename="${pluginSlug}.${pluginVersion}.zip"
|
||||
fi
|
||||
|
||||
if [ -f "${pluginFilename}" ]; then
|
||||
unzip -qq -d "${pluginsDir}" "${pluginFilename}" || return $?
|
||||
rm "${pluginFilename}" -f
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if plugin is installed
|
||||
# $1 - plugin slug
|
||||
# Returns 0 if plugin is installed, 1 otherwise
|
||||
check() {
|
||||
local pluginsDir="${TARGET_PLUGINS_DIR:?check: TARGET_PLUGINS_DIR is required}"
|
||||
local pluginSlug="${1:?check: PLUGIN_SLUG is required}"
|
||||
local pluginPath="${pluginsDir}/${pluginSlug}"
|
||||
|
||||
# Check if plugin directory exists
|
||||
if [ ! -d "${pluginPath}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if plugin file exists - if yes, plugin is probably installed successfully
|
||||
if [ -f "${pluginPath}/${pluginSlug}.php" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if plugin directory is empty - if not, plugin is probably installed successfully
|
||||
if [ "$(ls -A "${pluginPath}")" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# If we got here, then plugin is not installed
|
||||
return 1
|
||||
}
|
||||
|
||||
# Delete plugin
|
||||
# $1 - plugin slug
|
||||
# Returns 0 on success, X on failure
|
||||
delete() {
|
||||
local pluginsDir="${TARGET_PLUGINS_DIR:?delete: TARGET_PLUGINS_DIR is required}"
|
||||
local pluginSlug="${1:?delete: PLUGIN_SLUG is required}"
|
||||
local pluginPath="${pluginsDir}/${pluginSlug}"
|
||||
|
||||
# Check if plugin directory exists
|
||||
if [ ! -d "${pluginPath}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -rf "${pluginPath}"
|
||||
return $?
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
TARGET_PLUGINS_DIR="${WP_PLUGINS_PATH:?WP_PLUGINS_PATH is required}"
|
||||
export TARGET_PLUGINS_DIR
|
||||
|
||||
local action="${1:?ACTION is required}"
|
||||
|
||||
# Execute command by calling function with the same name
|
||||
case "${action}" in
|
||||
download)
|
||||
download "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
unpack)
|
||||
unpack "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
check)
|
||||
check "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
delete)
|
||||
delete "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unknown action '${action}'"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
129
src/wp-utils/wp-theme
Executable file
129
src/wp-utils/wp-theme
Executable file
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Download theme (curl)
|
||||
# $1 - theme slug
|
||||
# $2 - theme version (optional)
|
||||
# Returns 0 on success, X on failure
|
||||
download() {
|
||||
local themeSlug="${1:?download: THEME_SLUG is required}"
|
||||
local themeVersion="${2:-}"
|
||||
local themeFilename="${themeSlug}.zip"
|
||||
|
||||
if [ -n "${themeVersion}" ]; then
|
||||
themeFilename="${themeSlug}.${themeVersion}.zip"
|
||||
fi
|
||||
|
||||
curl --fail -gsO "https://downloads.wordpress.org/theme/${themeFilename}" || return $?
|
||||
echo "${themeFilename}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Unpack theme (unzip)
|
||||
# $1 - theme slug
|
||||
# $2 - theme version (optional)
|
||||
# Returns 0 on success, 1 on failure
|
||||
unpack() {
|
||||
local themesDir="${TARGET_THEMES_DIR:?check: TARGET_THEMES_DIR is required}"
|
||||
local themeSlug="${1:?unpack: THEME_SLUG is required}"
|
||||
local themeVersion="${2:-}"
|
||||
local themeFilename="${themeSlug}.zip"
|
||||
|
||||
if [ -n "${themeVersion}" ]; then
|
||||
themeFilename="${themeSlug}.${themeVersion}.zip"
|
||||
fi
|
||||
|
||||
if [ -f "${themeFilename}" ]; then
|
||||
unzip -qq -d "${themesDir}" "${themeFilename}" || return $?
|
||||
rm "${themeFilename}" -f
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if theme is installed
|
||||
# $1 - theme slug
|
||||
# Returns 0 if theme is installed, 1 otherwise
|
||||
check() {
|
||||
local themesDir="${TARGET_THEMES_DIR:?check: TARGET_THEMES_DIR is required}"
|
||||
local themeSlug="${1:?check: THEME_SLUG is required}"
|
||||
local themePath="${themesDir}/${themeSlug}"
|
||||
|
||||
# Check if theme directory exists - If it doesn't we know immediately that the theme is not installed
|
||||
if [ ! -d "${themePath}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if theme style.css exists - if yes, theme is probably installed successfully
|
||||
if [ -f "${themePath}/style.css" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if theme theme.json exists - if yes, theme is probably installed successfully
|
||||
if [ -f "${themePath}/theme.json" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if theme index.php exists - if yes, theme is probably installed successfully
|
||||
if [ -f "${themePath}/index.php" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if theme directory is empty - if not, theme is probably installed successfully
|
||||
if [ "$(ls -A "${themePath}")" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# If we got here, then theme is not installed
|
||||
return 1
|
||||
}
|
||||
|
||||
# Delete theme
|
||||
# $1 - theme slug
|
||||
# Returns 0 on success, X on failure
|
||||
delete() {
|
||||
local themesDir="${TARGET_THEMES_DIR:?delete: TARGET_THEMES_DIR is required}"
|
||||
local themeSlug="${1:?delete: THEME_SLUG is required}"
|
||||
local themePath="${themesDir}/${themeSlug}"
|
||||
|
||||
# Check if theme directory exists
|
||||
if [ ! -d "${themePath}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -rf "${themePath}"
|
||||
return $?
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
TARGET_THEMES_DIR="${WP_THEMES_PATH:?WP_THEMES_PATH is required}"
|
||||
export TARGET_THEMES_DIR
|
||||
|
||||
local action="${1:?ACTION is required}"
|
||||
|
||||
# Execute command by calling function with the same name
|
||||
case "${action}" in
|
||||
download)
|
||||
download "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
unpack)
|
||||
unpack "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
check)
|
||||
check "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
delete)
|
||||
delete "${@:2}"
|
||||
return $?
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unknown action '${action}'"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
113
wp-config.php
113
wp-config.php
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The base configuration for WordPress
|
||||
* Adapted for docker environment
|
||||
* @author Aleksandar Puharic <xzero@elite7hackers.net>
|
||||
*
|
||||
* The wp-config.php creation script uses this file during the
|
||||
* installation. You don't have to use the web site, you can
|
||||
* copy this file to "wp-config.php" and fill in the values.
|
||||
*
|
||||
* This file contains the following configurations:
|
||||
*
|
||||
* * MySQL settings
|
||||
* * Secret keys
|
||||
* * Database table prefix
|
||||
* * ABSPATH
|
||||
*
|
||||
* @link https://codex.wordpress.org/Editing_wp-config.php
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
/** Not needed behind the nginx-proxy */
|
||||
define('FORCE_SSL_ADMIN', false);
|
||||
define('FORCE_SSL_LOGIN', false);
|
||||
|
||||
/** Disable cron (will be run by system crond) */
|
||||
define('DISABLE_WP_CRON', true);
|
||||
|
||||
/** Makes it easier to control in docker environment */
|
||||
define('WP_CONTENT_DIR', $_ENV['WORDPRESS_CONTENT_DIR'] ?? (__DIR__ . '/wp-content'));
|
||||
|
||||
/**
|
||||
* Redis Cache
|
||||
*/
|
||||
define('WP_REDIS_HOST', $_ENV['WORDPRESS_REDIS_HOST'] ?? null);
|
||||
define('WP_CACHE', (bool)($_ENV['WORDPRESS_CACHE'] ?? false));
|
||||
define('WP_CACHE_KEY_SALT', $_ENV['WORDPRESS_CACHE_KEY_SALT'] ?? null);
|
||||
|
||||
// ** MySQL settings - You can get this info from your web host ** //
|
||||
/** The name of the database for WordPress */
|
||||
define('DB_NAME', $_ENV['WORDPRESS_DB_NAME'] ?? 'wordpress');
|
||||
|
||||
/** MySQL database username */
|
||||
define('DB_USER', $_ENV['WORDPRESS_DB_USER'] ?? 'wordpress');
|
||||
|
||||
/** MySQL database password */
|
||||
define('DB_PASSWORD', $_ENV['WORDPRESS_DB_PASSWORD'] ?? '');
|
||||
|
||||
/** MySQL hostname */
|
||||
define('DB_HOST', $_ENV['WORDPRESS_DB_HOST'] ?? 'localhost');
|
||||
|
||||
/** Database Charset to use in creating database tables. */
|
||||
define('DB_CHARSET', $_ENV['WORDPRESS_DB_CHARSET'] ?? 'utf8mb4');
|
||||
|
||||
/** The Database Collate type. Don't change this if in doubt. */
|
||||
define('DB_COLLATE', $_ENV['WORDPRESS_DB_COLLATION'] ?? '');
|
||||
|
||||
/**#@+
|
||||
* Authentication Unique Keys and Salts.
|
||||
*
|
||||
* Change these to different unique phrases!
|
||||
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
|
||||
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
define('AUTH_KEY', $_ENV['WORDPRESS_AUTH_KEY'] ?? '');
|
||||
define('SECURE_AUTH_KEY', $_ENV['WORDPRESS_SECURE_AUTH_KEY'] ?? '');
|
||||
define('LOGGED_IN_KEY', $_ENV['WORDPRESS_LOGGED_IN_KEY'] ?? '');
|
||||
define('NONCE_KEY', $_ENV['WORDPRESS_NONCE_KEY'] ?? '');
|
||||
define('AUTH_SALT', $_ENV['WORDPRESS_AUTH_SALT'] ?? '');
|
||||
define('SECURE_AUTH_SALT', $_ENV['WORDPRESS_SECURE_AUTH_SALT'] ?? '');
|
||||
define('LOGGED_IN_SALT', $_ENV['WORDPRESS_LOGGED_IN_SALT'] ?? '');
|
||||
define('NONCE_SALT', $_ENV['WORDPRESS_NONCE_SALT'] ?? '');
|
||||
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* WordPress Database Table prefix.
|
||||
*
|
||||
* You can have multiple installations in one database if you give each
|
||||
* a unique prefix. Only numbers, letters, and underscores please!
|
||||
*/
|
||||
$table_prefix = $_ENV['WORDPRESS_TABLE_PREFIX'] ?? 'wp_';
|
||||
|
||||
/**
|
||||
* For developers: WordPress debugging mode.
|
||||
*
|
||||
* Change this to true to enable the display of notices during development.
|
||||
* It is strongly recommended that plugin and theme developers use WP_DEBUG
|
||||
* in their development environments.
|
||||
*
|
||||
* For information on other constants that can be used for debugging,
|
||||
* visit the Codex.
|
||||
*
|
||||
* @link https://codex.wordpress.org/Debugging_in_WordPress
|
||||
*/
|
||||
define('WP_DEBUG', (bool)($_ENV['WORDPRESS_DEBUG'] ?? false));
|
||||
|
||||
/**
|
||||
* Other settings
|
||||
*/
|
||||
define('FS_METHOD', 'direct');
|
||||
|
||||
/* That's all, stop editing! Happy blogging. */
|
||||
|
||||
/** Absolute path to the WordPress directory. */
|
||||
if ( !defined('ABSPATH') )
|
||||
define('ABSPATH', __DIR__ . '/');
|
||||
|
||||
/** Sets up WordPress vars and included files. */
|
||||
require_once(ABSPATH . 'wp-settings.php');
|
||||
Reference in New Issue
Block a user