How to update wordpress on docker - wordpress

I'm running a php-fpm wordpress container.
The wordpress source files are mounted in a named volume "wordpress" shared with the Nginx container.
Everything is running well except when i need to update wordpress to a new version. The code inside the named volume persists. It is normal for a named volume...
I could manually delete the volume but there must be a better way.
My dockerfile:
FROM wordpress:4.9.5-php5.6-fpm-alpine
My docker-compose.yml
version: '3.1'
services:
php:
build: ./docker/php/
restart: unless-stopped
volumes:
- wordpress:/var/www/html
- ./web/wp-content/:/var/www/html/wp-content/
- ./web/wp-config.php:/var/www/html/wp-config.php
environment:
- DEBUG=${DEBUG:-0}
- MYSQL_USER=$MYSQL_USER
- MYSQL_PASSWORD=$MYSQL_PASSWORD
- MYSQL_DATABASE=$MYSQL_DATABASE
nginx:
image: nginx:1-alpine
restart: unless-stopped
expose:
- 80
volumes:
- wordpress:/var/www/html
- ./web/wp-content/:/var/www/html/wp-content/
- ./docker/nginx/site.conf:/etc/nginx/conf.d/default.conf
- ./docker/nginx/wordpress.conf:/etc/nginx/wordpress.conf
environment:
- VIRTUAL_HOST=localhost
mysql:
image: mysql:5.6
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
- MYSQL_USER=$MYSQL_USER
- MYSQL_PASSWORD=$MYSQL_PASSWORD
- MYSQL_DATABASE=$MYSQL_DATABASE
volumes:
- mysql:/var/lib/mysql
volumes:
wordpress: {}
mysql: {}
networks:
default:
external:
name: wordpress
Looking forward to reading your suggestions
Thank you

When the wordpress container comes up it checks for the existence of files at /var/www/html and copies only if not present. So in your case may you can update the entrypoint script to check the wordpress version in the wp-includes/version.php in the /var/www/html and the files in the container and then make a decision to replace the new files.
Edit:
According to this just deletion of index.php or wp-includes/version.php should copy the files from container again. Or may you can update your entrypoint script to copy files to /var/www/html all the time, but that may cause issues if you choose to scale the wordpress layer.

Thank you for your help.
It worked.
Here is the code i'm using.
I overriden the entrypoint in dockerfile
COPY check-wordpress-version.sh /usr/local/bin/
ENTRYPOINT ["check-wordpress-version.sh"]
Here is the content of check-wordpress-version.sh to check wordpress current version.
VOLUME_VERSION="$(php -r 'require('"'"'/var/www/html/wp-includes/version.php'"'"'); echo $wp_version;')"
echo "Volume version : "$VOLUME_VERSION
echo "WordPress version : "$WORDPRESS_VERSION
if [ $VOLUME_VERSION != $WORDPRESS_VERSION ]; then
echo "Forcing WordPress code update..."
rm -f /var/www/html/index.php
fi
docker-entrypoint.sh php-fpm

Wordpress seems to have addressed this under this issue.
I notice you are using a custom wp-config.php. Most likely, you can use the WORDPRESS_CONFIG_EXTRA for this rather than mounting wp-config.php.
Theoretically (per the link above), updating the image should update the database, but I have not confirmed.
Based on this, my stack.yml/docker-compose.yml looks like this:
environment:
WORDPRESS_CONFIG_EXTRA: |
define( 'AUTOMATIC_UPDATER_DISABLED', true );
volumes:
- "./themes:/var/www/html/wp-content/themes/"
- "./plugins:/var/www/html/wp-content/plugins/"
- "./uploads:/var/www/html/wp-content/uploads/"

It's easier solution.
You have to edit wp-config.php file by add define('FS_METHOD','direct'); to the end of file.
Save the file and run update. From now, you don't need FTP server to update your WordPress.
Remember! Before update make a backup :)

To expend on #Bigbenny's answer, my Dockerfile looked like the following:
FROM wordpress:latest
WORKDIR /var/www/html
COPY . /var/www/html
COPY check-wordpress-version.sh /usr/local/bin/
RUN chmod 755 /usr/local/bin/check-wordpress-version.sh
ENTRYPOINT ["/usr/local/bin/check-wordpress-version.sh"]
Two things to notice here:
I had to chmod 755 the file or I would get a permissions denied error
I placed the script inside the /usr/local/bin because for some reason when I would just use ENTRYPOINT["check-wordpress-version.sh"], the file wouldn't be found by the container.
I also, slightly tweaked the script to look like:
#!/bin/sh
VOLUME_VERSION="$(php -r 'require('"'"'/var/www/html/wp-includes/version.php'"'"'); echo $wp_version;')"
echo "Volume version : "$VOLUME_VERSION
echo "WordPress version : "$WORDPRESS_VERSION
if [ $VOLUME_VERSION != $WORDPRESS_VERSION ]; then
echo "Forcing WordPress code update..."
rm -f /var/www/html/index.php
rm -f /var/www/html/wp-includes/version.php
fi
docker-entrypoint.sh apache2-foreground
For my use-case, I had to use apache2-foreground rather than php-fpm; I also deleted the /var/www/html/wp-includes/version.php file.
Finally, in my docker-compose, instead of the using the image directive; I used build: ./wordpress.
I hope this helps!😁

My answer applied to the official docker wordpress image. So
probably off topic but might help someone.
If you are using docker-compose you can pull the latest image using this command.
docker pull wordpress
I believe this will update your core docker image. Any other local project which you docker-compose up -d with this yml image setting as this will use the latest update.
services:
wordpress:
image: wordpress:latest
If you currently running the image will you need to docker-compose down and docker-compose up -d to invoke the update.

Related

How to copy local wp-content files to Wordpress container using Dockerfile

I have a Wordpress container that I would like to copy local folders (with files) to at startup
I have local files in folders:
/html/wp-content/plugins
/html/wp-content/themes
/html/wp-content/uploads
I have a Dockerfile with:
FROM wordpress
COPY ./html/wp-content/plugins/ /var/www/html/wp-content/plugins
COPY ./html/wp-content/themes/ /var/www/html/wp-content/themes
COPY ./html/wp-content/uploads/ /var/www/html/wp-content/uploads
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["apache2-foreground"]
Although the COPY is succeeding (the build passes), the files are not showing up in these destination folders.
If I change the destination folders to be on any path before /html, eg if I put the destination to be /var or /var/www, then the files copy and I can see them in the container.
I checked out this old post here, which mentions that the /html folder is actually mounted as a volume at startup, and so I need to copy the files into this folder first
/usr/src/wordpress/wp-content
and then at startup these folders will be automatically copied across to /var/www/html/wp-content/. (This would explain why copying directly does not seem to work)
I tried that too, and while my local folders are indeed copied into these folders (I can see them in the container), they are then not copied across to /var/www/html/content at startup!
Is it possible to copy the local files directly into the /var/www/html folders via the dockerfile?
If not, how can I ensure that if copying to /usr/src/wordpress/wp-content, the folders will be copied across to /var/www/html/wp-content/ at startup?
(Some posts I've looked through that don't work, as this seems to be particular to Wordpress, and not Dockerfile COPY on its own:)
Dockerfile copy keep subdirectory structure
Docker is not copying subdirectory into Container
How to copy folders to docker image from Dockerfile?
https://www.serverlab.ca/tutorials/containers/docker/how-to-host-your-wordpress-site-with-docker/
Wordpress docker copy theme into exposed folder
Today I ran into the same problem. I wanted to add theme when building the image by using COPY. However, it did not work. This was because I already set my wp-content folder as a volume. It seems you cannot COPY into a volume.
The discussion in the following link helped me realise this:
https://github.com/docker-library/wordpress/issues/146
Below I have added my WordPres Dockerfile and docker-compose file. After commenting out the volume everything worked as expected.
I sure hope you do not need it anymore after two years, haha.
Reference: https://docs.docker.com/samples/wordpress/
Dockerfile
FROM wordpress:latest
WORKDIR /var/www/html
COPY ./wp-content/ ./wp-content/
RUN chmod -R 755 ./wp-content/
docker-compose.yml
version: "3"
services:
db:
build:
context: .
dockerfile: ./compose/local/db/Dockerfile
image: new_db_image_name
container_name: new_db_image_name
command: '--default-authentication-plugin=mysql_native_password'
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=somewordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
expose:
- 3306
- 33060
wordpress:
build:
context: .
dockerfile: ./compose/local/wordpress/Dockerfile
image: new_wordpress_image_name
container_name: new_wordpress_image_name
# volumes:
# - wp-content:/var/www/html/wp-content
ports:
- 80:80
restart: always
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=wordpress
- WORDPRESS_DB_NAME=wordpress
volumes:
db_data:
# wp-content:

Docker for WordPress slow

Problem:
I have a problem with WordPress & Docker because the slow loading time (+- 7 seconds) of my website. I am not sure why this happends but I think it has something to do with the external database or the shared volumes.
Setup:
I have a custom Dockerfile built on WordPress with XDebug and Mailhog. This Dockerfile is included within my docker-compose.yml, the other services my docker-compose contains are WP-CLI and Mailhog. My Database is hosted on an Amazon RDS so I can share it with my colleagues.
Code:
My Dockerfile looks like this:
FROM wordpress:latest
# Plugins & Media
RUN mkdir -p /var/www/html/wp-content/plugins
RUN mkdir -p /var/www/html/wp-content/uploads
RUN chown -R www-data:www-data /var/www
RUN find /var/www/ -type d -exec chmod 0755 {} \;
RUN find /var/www/ -type f -exec chmod 644 {} \;
# Mailhog
RUN curl --location --output /usr/local/bin/mhsendmail https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 && \
chmod +x /usr/local/bin/mhsendmail
RUN echo 'sendmail_path="/usr/local/bin/mhsendmail --smtp-addr=mailhog:1025 --from=noreply#examle.com"' > /usr/local/etc/php/conf.d/mailhog.ini
# Xdebug
ENV XDEBUG_PORT 9000
RUN yes | pecl install xdebug \
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.remote_autostart=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.profiler_enable=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.profiler_output_name=cachegrind.out.%t" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.profiler_output_dir=/tmp" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "max_input_vars=2000" >> /usr/local/etc/php/conf.d/custom.ini \
&& rm -rf /usr/local/etc/php/conf.d/opcache-recommended.ini
EXPOSE 9000
My Docker-compose.yml looks like this:
version: "3.7"
services:
wordpress:
container_name: "${PROJECT_NAME}_wordpress"
restart: always
build:
context: ./
dockerfile: ./Dockerfile
ports:
- "8888:80"
- "443:443"
environment:
WORDPRESS_DB_NAME: "${PROJECT_NAME}"
WORDPRESS_DB_HOST: "${MYSQL_HOST}"
WORDPRESS_DB_USER: "${MYSQL_USER}"
WORDPRESS_DB_PASSWORD: "${MYSQL_PASSWORD}"
WORDPRESS_DEBUG: 1
XDEBUG_CONFIG: remote_host=host.docker.internal
WORDPRESS_CONFIG_EXTRA: |
define('FS_METHOD', 'direct');
volumes:
- "wordpress:/var/www/html"
- "./build/uploads:/var/www/html/wp-content/uploads:cached"
- "./build/plugins:/var/www/html/wp-content/plugins:cached"
- "./build/themes:/var/www/html/wp-content/themes:cached"
cli:
container_name: "${PROJECT_NAME}_cli"
image: "wordpress:cli"
volumes:
- "wordpress:/var/www/html"
- "./build/plugins:/var/www/html/wp-content/plugins:cached"
depends_on:
- wordpress
mailhog:
container_name: "${PROJECT_NAME}_mailhog"
image: mailhog/mailhog
depends_on:
- wordpress
ports:
- "1025:1025"
- "8025:8025"
volumes:
wordpress: null
But I can't find out why it is so slow; I got version 2.1.09.3 of Docker Desktop and working on a fast Mac or Windows.
Can someone help me or point me in the right direction?
Edits
If I look in the docker stats my CPU is around 0.01% and my MEM is around 2.73% so that can't be the problem.
Found out the biggest problem is connecting to the external database. If I move over to a local database the loading time is a lot faster (+- 1 sec).
There some issues for Mac & Windows Volume performance.
Link for more details:
Docker Wordpress super slow
In Mac and Windows there are some volumes performance issues that we should consider.
I made change in my docker-compose.yml
Note as I changed the short syntax to long syntax.
This notation permits add consistency option.
I added wp-content and php-conf (to get php.ini) because they are files directory most frequently called every time when a Wordpress page is loaded in browser.
services:
wordpress:
...
volumes:
- ./data:/data
- ./scripts:/docker-entrypoint-initwp.d
#- ./wp-content:/app/wp-content
- type: bind
source: ./wp-content
target: /app/wp-content
consistency: cached
#- ./php-conf:/usr/local/etc/php
- type: bind
source: ./php-conf
target: /usr/local/etc/php
consistency: cached

Copy file from host to Docker container by using Docker file error

I am new to Docker. I know there are lot of answers out there. I tried this link host to container But I can't solve my issue with that. I am creating a docker for WordPress with WordPress cli image.
Here it is:
version: '3.1'
services:
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_files:/var/www/html
ports:
- "8080:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: user
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpressdb
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_DATABASE: wordpressdb
MYSQL_USER: user
MYSQL_PASSWORD: password
volumes:
wordpress_files:
db_data:
In above code, I am using a official WordPress image which is connected with MySQL and it was created successfully. Next I want to install WordPress cli in that WordPress image. Here are the commands I found to install WordPress cli.
echo "Installing WP-CLI"
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
I tried in the direct way by putting the above commands in the command section in Docker file. But it failed. So I saved the contents in the install.sh file in the host.
Next I want to transfer the file to WordPress image and the file should be triggered after installing the WordPress image and it should install cli in that image by using the file.
Here the code I modified:
version: '3.1'
services:
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_files:/var/www/html
ports:
- "8080:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: user
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpressdb
COPY /files/install.sh /var/www/html/ =>modified
command: =>modified
/var/www/html/files/install.sh =>modified
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_DATABASE: wordpressdb
MYSQL_USER: user
MYSQL_PASSWORD: password
volumes:
wordpress_files:
db_data:
Error:
ERROR: yaml.scanner.ScannerError: while scanning a simple key
in "./word_press_docker_file.yml", line 18, column 6
could not find expected ':'
in "./word_press_docker_file.yml", line 19, column 6
But it again fails. I tried several Stack Overflow answers but unable to figure it out. I tried the COPY command but it fails.
One way of achieving this is via Dockerfile.
A sample Dockerfile for your case may look like this:
FROM wordpress:latest
RUN cd /tmp && echo "Installing WP-CLI" && curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp
Then you can build this as a new Custom Image and use in your YAML File.
Edit:
Use of Local images is no longer permitted. So, you can use the docker tag command to tag the image and then use in YAML file.
You can read more about this here:
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
One other way of doing this is mentioned here:
https://hub.docker.com/_/wordpress/
This image variant does not contain WordPress itself, but instead contains WP-CLI.
The simplest way to use it with an existing WordPress container would be something similar to the following:
$ docker run -it --rm \
--volumes-from some-wordpress \
--network container:some-wordpress \
wordpress:cli user list
Generally speaking, for WP-CLI to interact with a WordPress install, it needs access to the on-disk files of the WordPress install, and access to the database (and the easiest way to accomplish that such that wp-config.php does not require changes is to simply join the networking context of the existing and presumably working WordPress container, but there are many other ways to accomplish that which will be left as an exercise for the reader).
You can try using the RUN instruction as follows:
RUN echo "Installing WP-CLI" \
&& curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \
&& chmod +x wp-cli.phar \
&& mv wp-cli.phar /usr/local/bin/wp

docker-compose not behaving in compliance with dockerfiles

I'm a level 0 Docker user, so bear with me on this one:
I'm trying to create a shared container environment with docker-compose. The docker-compose.yaml looks like this:
# docker-compose.yml
#ubuntu(16.04) + python(3)
version: '3'
services:
ubuntu:
image: 434c03a615a2
build:
context: .
dockerfile: dockerfileBase
volumes:
- "./data/data_vol/:/app"
tty: true
#tensorflow
tensorflow:
image: tensorflow/tensorflow
build:
context: .
dockerfile: dockerfileTensorflow
ports:
- "8888:8888"
tty: true
#rstudio
rstudio:
image: rocker/rstudio
build:
context: .
dockerfile: dockerfileRstudio1
environment:
- PASSWORD=supersecret
ports:
- "8787:8787"
tty: true
As far as I can tell everything is working, but the dockerfile, with which I import Rstudio doesn't seem to get executed the same way inside the .yaml as it does outside of it. What I mean is that this Rstudio dockerfile:
#pull rstudio
FROM rocker/rstudio:3.4.3
LABEL maintainer="Landsense"
#set Env variables
ENV http_proxy=http://##.###.###.##:####
ENV https_proxy=http://##.###.###.##:####
ENV ftp_proxy=http://##.###.###.##:####
ENV TZ="Europe/Rome"
RUN apt-get update && \
apt-get install -y \
libgdal-dev \
libproj-dev \
libv8-dev \
ssh && \
apt-get clean all
RUN Rscript -e "install.packages('raster')"
installs packages when it's built on its own, but fails to do so when ran from the docker-compose.yaml . Can someone comment on this type of behavior? RSPKT!
When you have both image and build in a docker-compose service precedence is given to image. In your scenario your since you have image: rocker/rstudio in your compose file it will pull the rocker/rstudio:latest image from docker-hub. But what do you want is a image build on top of the rocker/rstudio image (In Dockerfile it has been used as the base image).
It is not a good practice to tag your image as with existing tag in docker-hub (You may face difficulties as wrong image is cached in your local docker images as you experienced here). First decide whether you really want to name your image (Otherwise compose will tag the image for you where tag include a part of your service name so you can easily identify). If you want use it as following with a prefix in image tag. Same goes with other two services.
image: localhost/rocker/rstudio
build:
context: .
dockerfile: dockerfileRstudio1

Docker Compose Link Containers for Phpunit with Wordpress, MySQL

I would like to use a docker-compose app to run unit tests on a wordpress plugin.
Following (mostly) this tutorial I have created four containers:
my-wpdb:
image: mariadb
ports:
- "8081:3306"
environment:
MYSQL_ROOT_PASSWORD: dockerpass
my-wp:
image: wordpress
volumes:
- ./:/var/www/html
ports:
- "8080:80"
links:
- my-wpdb:mysql
environment:
WORDPRESS_DB_PASSWORD: dockerpass
my-wpcli:
image: tatemz/wp-cli
volumes_from:
- my-wp
links:
- my-wpdb:mysql
entrypoint: wp
command: "--info"
my-phpunit:
image: phpunit/phpunit
volumes_from:
- my-wp
links:
- my-wpdb
This tutorial got me as far as creating the phpunit files (xml, tests, bin, .travis), with the exception that I had to install subversion manually:
docker exec wp_my-wp_1 apt-get update
docker exec wp_my-wp_1 apt-get install -y wget git curl zip vim
docker exec wp_my-wp_1 apt-get install -y apache2 subversion libapache2-svn libsvn-perl
And run the last part of bin/install-wp-tests.sh manually in the database container:
docker exec wp_my-wpdb_1 mysqladmin create wordpress_test --user=root --password=dockerpass --host=localhost --protocol=tcp
I can run phpunit: docker-compose run --rm my-wp phpunit --help.
I can specify the config xml file:
docker-compose run --rm my-wp phpunit --configuration /var/www/html/wp-content/plugins/my-plugin/phpunit.xml.dist
However, the test wordpress installation is installed in the my-wp container's /tmp directory: /tmp/wordpress-tests-lib/includes/functions.php
I think I have to link the my-phpunit containers /tmp to the one in my-wp?
This doesn't answer my question, but as a solution to the problem, there is a github repo for a Docker Image that provides the wanted features: https://github.com/chriszarate/docker-wordpress as well as a wrapper you can invoke it through: https://github.com/chriszarate/docker-wordpress-vip
I wonder if for the initial set-up (noted in the question), it might make more sense to add Phpunit to the Wordpress container, rather than making a separate container for it.

Resources