I have created a repo for setting up WP with Docker on PHP7.3, latest WordPress on php-fpm and I get the same issue: https://github.com/dingo-d/wordpress-docker
You can check it out to see what could be an issue. My guess is something with PHP-FPM has to be the issue (since restarting that container makes the changes propagate).
I have created a WordPress docker local dev environment by following the tutorial I found here .
Basically, all my docker stuff is located in the .docker
folder.
I have these files in the .docker
folder
|--project-folder
|____.docker
| |____php-fpm
| | |____php.ini
| | |____Dockerfile
| |____nginx
| | |____Dockerfile
| | |____logs
| | | |____error.log
| | | |____access.log
| | |____certs
| | | |____dev.project.com.key
| | | |____dev.project.com.crt
| | |____scripts
| | | |____docker-nginx-entrypoint.sh
| | |____nginx.conf
| |____.dockerignore
| |____.env
| |____docker-compose.yml
| |____.env.example
After trying to set everything up with the self signed SSL certificates, I can log in to https://localhost:8443
(I have some issues with setting the hosts file so that I can go to https://dev.project.com
but that's another issue).
The problem is that when I go and change something in my theme, say add a print_r
statement that should just print something out, I can see that change in the WP admin only after I restart my WordPress app container. The folders are mapped, and when I change things locally and exec to container, those changes are there immediately (and when I delete them while exec'd in the container they get deleted in my editor immediately).
I've tested if the same thing will happen with a super simple WordPress Docker setup I found online
version: '3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: user
MYSQL_PASSWORD: password
app:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
volumes:
- ./wp-content/:/var/www/html/wp-content
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: user
WORDPRESS_DB_PASSWORD: password
volumes:
db_data:
And when I start this up, and go to localhost:8000
I can see the changes immediately without restarting the container (when I edit files in the editor).
My docker-compose.yml
looks like this:
version: '3.7'
services:
wordpress:
build:
context: ..
dockerfile: .docker/php-fpm/Dockerfile
args:
WP_VERSION: ${WP_VERSION}
container_name: dev-project-wp
working_dir: /var/www/html
tty: true
depends_on:
- database
volumes:
- ../:/var/www/html
- ./php-fpm/php.ini:/usr/local/etc/php/conf.d/local.ini
environment:
DB_PORT: ${DB_PORT}
DB_HOST: ${DB_HOST}
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
AUTH_KEY: ${AUTH_KEY}
SECURE_AUTH_KEY: ${SECURE_AUTH_KEY}
LOGGED_IN_KEY: ${LOGGED_IN_KEY}
NONCE_KEY: ${NONCE_KEY}
AUTH_SALT: ${AUTH_SALT}
SECURE_AUTH_SALT: ${SECURE_AUTH_SALT}
LOGGED_IN_SALT: ${LOGGED_IN_SALT}
NONCE_SALT: ${NONCE_SALT}
DB_PREFIX: ${DB_PREFIX}
WP_VERSION: ${WP_VERSION}
ports:
- '9000'
expose:
- '80'
nginx:
build:
context: ..
dockerfile: .docker/nginx/Dockerfile
args:
DOCKER_IMAGE_NAME_PHP: 'docker_wordpress'
container_name: dev-project-nginx
working_dir: /var/www/html
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/certs/dev.project.com.crt:/etc/nginx/dev.project.com.crt
- ./nginx/certs/dev.project.com.key:/etc/nginx/dev.project.com.key
- ../:/var/www/html
- ./nginx/logs:/var/log/nginx
depends_on:
- wordpress
ports:
- "${NGINX_HOST_HTTP_PORT}:80"
- "${NGINX_HOST_HTTPS_PORT}:443"
database:
image: mariadb:10.3
volumes:
- projectdb:/var/lib/mysql
restart: always
container_name: ${DB_HOST}
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
ports:
- "${DB_HOST_PORT}:${DB_PORT}"
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: dev-project-phpmyadmin
external_links:
- database
depends_on:
- database
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_USERNAME: root
PMA_HOST: ${DB_HOST}
ports:
- "${PHPMYADMIN_HOST_PORT}:80"
mailhog:
image: mailhog/mailhog
container_name: dev-project-mailhog
ports:
- "${MAILHOG_HOST_PORT_SMTP}:1025"
- "${MAILHOG_HOST_PORT_WEB}:8025"
volumes:
projectdb:
I have an .env
that looks like this:
# required so we can reach the nginx server from other containers via that hostname
APP_HOST=dev.project.com
# nginx
NGINX_HOST_HTTP_PORT=8180
NGINX_HOST_HTTPS_PORT=8443
# database
DB_HOST_PORT=33060
DB_PORT=3306
DB_HOST=dev-project-db
DB_NAME=docker-project
DB_USER=wp
DB_PASSWORD=wp
#phpmyadmin
PHPMYADMIN_HOST_PORT=8088
# wordpress - https://api.wordpress.org/secret-key/1.1/salt/
AUTH_KEY=':1k7<tW.#pE-O%*nZv7qM@me.#PLE;7).#g<4_.]04,2cM|]:*r8|:osljhB]s*.'
SECURE_AUTH_KEY='N~?~Z0(ijZS%|cHe#~F!O.31N#;VQSI~QBL%~oWZFGfU6R`%k#(eD)2Mcm}wLh0a'
LOGGED_IN_KEY='y7T8hoW|Ik4eBUGWUs6j~O*j)k{hrZ`E.ujW+Za{`WPn9Xk.&g]*F(HsV~q0fL8g'
NONCE_KEY='V0aau(w+|CAW_.+ilIkYaIh]8Bz}@,DdX@yBi+!dD5Zy:,YO+<CF+oYwP+~jYE,r'
AUTH_SALT='_zQ C^rzH%wBmmyjO,KH`J-EIZm$.MIzK[b(ar2+TgO=P&hHQ7d*lPsd8*+xu{4u'
SECURE_AUTH_SALT='EL~r.88e=TYM>W&LP]BI(u_f,PLQY|m%+2(2TF%,|S,Wc4uYV)hVBpZ .KA$cGhY'
LOGGED_IN_SALT='hEoqqkkJO~f`|p~43>gZx$;u&% {qJLe$OnreM,dfR`H?an+q3g`&9>?-v3iSoJ&'
NONCE_SALT='jfEVaR]Od2,yDPN|$o+g7Hd=XIwM,ow#a,,u|~d+pf/<T#NBcm(u9v?qpr#g^q5k'
DB_PREFIX=wp_
WP_VERSION=5.2.2
# mailhog
MAILHOG_HOST_PORT_SMTP=1028
MAILHOG_HOST_PORT_WEB=8028
My php dockerfile looks like this
ARG WP_VERSION
# Stage 0, build app
FROM php:7.3-fpm-stretch as build-container
RUN curl -sS https://getcomposer.org/installer | php \
&& chmod +x composer.phar && mv composer.phar /usr/local/bin/composer
RUN apt-get update && apt-get install -y gnupg
RUN curl -sL https://deb.nodesource.com/setup_11.x | bash - && \
apt-get install -yq nodejs build-essential \
git unzip \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
pkg-config \
libmcrypt-dev \
libpng-dev \
&& pecl install mcrypt-1.0.2 \
&& docker-php-ext-enable mcrypt \
&& docker-php-ext-install bcmath \
&& docker-php-ext-install -j$(nproc) mysqli \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd
RUN npm install -g npm
WORKDIR /
WORKDIR /build
COPY . /build
RUN cp /build/wp-config.php.template /build/wp-config.php
# RUN bash /build/scripts/build-plugins.sh
# Stage 2, build app container
FROM php:7.3-fpm-stretch
ARG WP_VERSION
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
libzip-dev \
unzip \
mariadb-client \
libmagickwand-dev \
&& docker-php-ext-configure gd --with-png-dir=/usr/include/ --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) \
bcmath \
exif \
gd \
mysqli \
opcache \
zip \
pdo \
pdo_mysql \
mysqli \
&& docker-php-ext-install -j$(nproc) iconv \
&& export CFLAGS="$PHP_CFLAGS" CPPFLAGS="$PHP_CPPFLAGS" LDFLAGS="$PHP_LDFLAGS" \
&& rm -rf /var/lib/apt/lists/* \
&& pecl install imagick-3.4.4 \
&& docker-php-ext-enable imagick
ADD https://downloads.wordpress.org/release/wordpress-$WP_VERSION-no-content.zip /var/www/latest.zip
RUN cd /var/www && unzip latest.zip && rm latest.zip
RUN rm -rf /var/www/html
RUN mkdir -p /var/www/html \
&& mv /var/www/wordpress/* /var/www/html/
# Copy wp files
COPY --from=build-container /build/ /var/www/html/
RUN chown www-data:www-data /var/www/html/ -R
COPY .docker/php-fpm/php.ini /usr/local/etc/php/
WORKDIR /var/www/html/
CMD ["php-fpm"]
And the dockerfile for nginx looks like this
ARG DOCKER_IMAGE_NAME_PHP
FROM $DOCKER_IMAGE_NAME_PHP as php-image
FROM nginx:latest
COPY .docker/nginx/scripts/docker-nginx-entrypoint.sh /docker-nginx-entrypoint.sh
COPY .docker/nginx/nginx.conf /opt/nginx.conf
COPY --from=php-image /var/www/html/ /var/www/html/
CMD ["/bin/bash","/docker-nginx-entrypoint.sh"]
The nginx.conf
looks like this:
worker_processes auto;
events {
worker_connections 2048;
}
http {
include mime.types;
index index.php index.html index.htm;
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name dev.project.com;
ssl_certificate /etc/nginx/dev.project.com.crt;
ssl_certificate_key /etc/nginx/dev.project.com.key;
root /var/www/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
client_max_body_size 128M;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass wordpress:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
}
And the docker-nginx-entrypoint.sh
script looks like this
#!/bin/bash
set -e
cp /opt/nginx.conf /etc/nginx/conf.d/default.conf
exec nginx -g "daemon off;"
To start the docker I use
docker-compose -f .docker/docker-compose.yml --project-directory .docker up -d --build
I looked at the logs, and there is no error (in the wp container or nginx logs). The site works fine when I go to https://localhost:8443/wp-admin/
but the changes are propagated only on container reset. And it makes no sense (not to mention that it's basically an unusable dev environment).
PS
This is a bit more complicated setup, if you have any advice on simplifying it, the advice is welcomed.
I'm bundling the assets using webpack, and when they are bundled, the changes are visible. The changes to the PHP file are not...
I've used the official images for nginx and for wordpress, and the PHP part is again only changed on restart, so it's not the problem in the Dockerfiles.
So it turns out that the culprit was the opcache
. Or rather me finding some example on line and just adding it to my php.ini
without trying to understand what this actually means.
After reading this article and this excellent article that explains some opcache settings, I realised that my php.ini
file had
opcache.revalidate_freq=60
Which you shouldn't have on your local development environment!
When used with opcache.validate_timestamps
, PHP checks the revalidate_freq
setting and uses it as a timestamp - if you made a request within 60 seconds (like the above example), the code will be pulled from the opcache - and you won't see any change in your browser. Only after 60 seconds will this change be visible.
So setting it to 0 (checking code on every single request) solves the issue.
Point of the story: check everything and read about every settings that you use!
'Unfortunately' for me I was reading the nginx config because I thought I messed something up there 😁
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.