For various reasons (the primary one being that I am lazy) I want to mount my wordpress files to /var/www/html/blog rather than /var/www/html and then use the sidecar pattern to have nginx and wordpress-fpm share a directory. I mounted an emptydir to /var/www/html which I expected to be empty (Duh!) and then copy in my files to /var/www/html/blog
My Dockerfile:
FROM wordpress:5.7.2-fpm-alpine
LABEL author="wayne@...co.uk"
COPY public/wordpress /app/blog
Wordpress's dockerfile:
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM php:7.4-fpm-alpine
# persistent dependencies
RUN set -eux; \
apk add --no-cache \
# in theory, docker-entrypoint.sh is POSIX-compliant, but priority is a working, consistent image
bash \
# BusyBox sed is not sufficient for some of our sed expressions
sed \
# Ghostscript is required for rendering PDF previews
ghostscript \
# Alpine package for "imagemagick" contains ~120 .so files, see: https://github.com/docker-library/wordpress/pull/497
imagemagick \
;
# install the PHP extensions we need (https://make.wordpress.org/hosting/handbook/handbook/server-environment/#php-extensions)
RUN set -ex; \
\
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
freetype-dev \
imagemagick-dev \
libjpeg-turbo-dev \
libpng-dev \
libzip-dev \
; \
\
docker-php-ext-configure gd \
--with-freetype \
--with-jpeg \
; \
docker-php-ext-install -j "$(nproc)" \
bcmath \
exif \
gd \
mysqli \
zip \
; \
pecl install imagick-3.4.4; \
docker-php-ext-enable imagick; \
rm -r /tmp/pear; \
\
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-network --virtual .wordpress-phpexts-rundeps $runDeps; \
apk del --no-network .build-deps
# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN set -eux; \
docker-php-ext-enable opcache; \
{ \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
# https://wordpress.org/support/article/editing-wp-config-php/#configure-error-logging
RUN { \
# https://www.php.net/manual/en/errorfunc.constants.php
# https://github.com/docker-library/wordpress/issues/420#issuecomment-517839670
echo 'error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR'; \
echo 'display_errors = Off'; \
echo 'display_startup_errors = Off'; \
echo 'log_errors = On'; \
echo 'error_log = /dev/stderr'; \
echo 'log_errors_max_len = 1024'; \
echo 'ignore_repeated_errors = On'; \
echo 'ignore_repeated_source = Off'; \
echo 'html_errors = Off'; \
} > /usr/local/etc/php/conf.d/error-logging.ini
RUN set -eux; \
version='5.7.2'; \
sha1='c97c037d942e974eb8524213a505268033aff6c8'; \
\
curl -o wordpress.tar.gz -fL "https://wordpress.org/wordpress-$version.tar.gz"; \
echo "$sha1 *wordpress.tar.gz" | sha1sum -c -; \
\
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
tar -xzf wordpress.tar.gz -C /usr/src/; \
rm wordpress.tar.gz; \
\
# https://wordpress.org/support/article/htaccess/
[ ! -e /usr/src/wordpress/.htaccess ]; \
{ \
echo '# BEGIN WordPress'; \
echo ''; \
echo 'RewriteEngine On'; \
echo 'RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]'; \
echo 'RewriteBase /'; \
echo 'RewriteRule ^index\.php$ - [L]'; \
echo 'RewriteCond %{REQUEST_FILENAME} !-f'; \
echo 'RewriteCond %{REQUEST_FILENAME} !-d'; \
echo 'RewriteRule . /index.php [L]'; \
echo ''; \
echo '# END WordPress'; \
} > /usr/src/wordpress/.htaccess; \
\
chown -R www-data:www-data /usr/src/wordpress; \
# pre-create wp-content (and single-level children) for folks who want to bind-mount themes, etc so permissions are pre-created properly instead of root:root
# wp-content/cache: https://github.com/docker-library/wordpress/issues/534#issuecomment-705733507
mkdir wp-content; \
for dir in /usr/src/wordpress/wp-content/*/ cache; do \
dir="$(basename "${dir%/}")"; \
mkdir "wp-content/$dir"; \
done; \
chown -R www-data:www-data wp-content; \
chmod -R 777 wp-content
VOLUME /var/www/html
COPY --chown=www-data:www-data wp-config-docker.php /usr/src/wordpress/
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["php-fpm"]
My Deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
spec:
replicas: 1
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
selector:
matchLabels:
app: wordpress
revisionHistoryLimit: 5
template:
metadata:
labels:
app: wordpress
spec:
volumes:
- name: shared
emptyDir: {}
containers:
- name: nginx
image: nginx
volumeMounts:
- name: shared
mountPath: /var/www/html
- name: wordpress
image: redacted/imagename:0.0.1
volumeMounts:
- name: shared
mountPath: /var/www/html
# Important! After this container has started, the PHP files
# in our Docker image aren't in the shared volume.
# If we tried to write directly to this volume from our Docker image
# the files wouldn't appear in the nginx container.
# So, after the container has started, copy the PHP files from this
# container's local filesystem
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "cp -r /app/. /var/www/html"]
imagePullSecrets:
- name: regcred
Now here comes the weird bit... buckle up...
When I kubectl exec into the container and list the contents of /var/www/html I get:
/var/www/html# ls
blog readme.html wp-blog-header.php wp-content wp-links-opml.php wp-mail.php wp-trackback.php
index.php wp-activate.php wp-comments-post.php wp-cron.php wp-load.php wp-settings.php xmlrpc.php
license.txt wp-admin wp-config-sample.php wp-includes wp-login.php wp-signup.php
There is my blog folder but there are also loads of wordpress files as well, like it has copied the files from /var/lib/docker/volumes into my emptydir... but this isn't how the docs say emptydir is supposed to work. The documentation says:
emptyDir
An emptyDir volume is first created when a Pod is assigned to a node, and exists as long as that Pod is running on that node. As the name says, the emptyDir volume is initially empty. All containers in the Pod can read and write the same files in the emptyDir volume, though that volume can be mounted at the same or different paths in each container. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted permanently.