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

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:

Related

Docker doesn't copy new images

I have a problem regarding Docker.
When I'm deploying a new version of my app image, the images i have added to the images folder in my wwwroot folder aren't copied..
My Dockerfile looks like this:
FROM microsoft/aspnetcore-build:1.0-projectjson
WORKDIR /app-src
COPY . .
RUN dotnet restore
RUN dotnet publish src/Test -o /app
EXPOSE 5000
WORKDIR /app
ENTRYPOINT ["dotnet", "Test.dll"]
And my docker-compose:
version: '3.8'
services:
app:
image: <dockeruser>/<imagename>:<tag>
links:
- db
environment:
ConnectionStrings__Dataconnection: "Host=db;Username=Username;Password=Password;Database=db"
ports:
- "5000:5000"
volumes:
- ~/data/images:/app/wwwroot/images
db:
image: postgres:9.5
ports:
- "31337:5432"
volumes:
- ~/data/db:/var/lib/postgresql/data/pgdata
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: db
PGDATA: /var/lib/postgresql/data/pgdata
My current version of docker is:
Docker version 18.09.7, build 2d0083d and docker-compose docker-compose version 1.26.2, build eefe0d31
The exact same files (except for the docker-compose version was set to 2 in docker-compose.yml) worked previously on docker version Docker version 17.03.0-ce, build 60ccb22 and docker-compose version docker-compose version 1.9.0, build 2585387
I store my new images in my repos wwwroot/images folder, and then push them to the repo, and then dockerhub automatically builds an image from the new commit. On the server i then pull the new docker-image and run the docker-compose down -v command followed by docker-compose up -d but the images is not available in the app afterwards.
Disclaimer: This is a project I have overtaken and I'm aware of some of the very old software versions.
Your images may be in your container image, but since you are doing a bind mount whatever is in your server’s “~/data/images” directory will basically “override/replace” what’s in your image when the container is created.
Try removing the volume from the app service, basically remove this:
volumes:
- ~/data/images:/app/wwwroot/images
The other thing you can try is to manually copy the images to the “~/data/images” directory on the server.

How to update wordpress on docker

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.

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.

COPY doesn't work on Docker prod

My Dockerfile looks like this:
FROM nginx
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/
My docker-compose.yml file looks like this:
version: '2'
services:
portfolio:
build: .
ports:
- "80:80"
When I run docker-compose up -d on my Mac, Im able to verify that the nginx.conf gets copied into the container.
However, when I run docker-compose up -d on my digital ocean prod machine, the nginx.conf file doesn't get copied over! Instead, I find the default nginx.conf file in /etc/nginx.
What am I missing here?
OK, the following worked:
clearing all images and containers, docker-compose down, then running docker-compose up worked! Docker now copies over my nginx.conf file just file!
To anyone else who is stuck with the same scenario follow this guide

Docker permissions development environment using a host mounted volume

I'm using docker-compose to set up a portable development environment for a bunch of symfony2 applications (though nothing I want to do is specific to symfony). I've decided to have the source files on the local machine exposed as a data volume with all the other dependencies in docker. This way developers can edit on the local file-system.
Everything works great, except that after running the app my cache and log files and the files created by composer in the /vendor directory are now owned by root.
I've read about this problem and some possible approaches here:
Changing permissions of added file to a Docker volume
But I can't quite quite tease out what changes I have to make in my docker-compose.yml file so that when my symphony container starts with docker-compose up any files that are created have the permissions of the user on the host machine.
I'm posting the file for reference, worker is where php, etc. live:
source:
image: symfony/worker-dev
volumes:
- $PWD:/var/www/app
mongodb:
image: mongo:2.4
ports:
- "27017:27017"
volumes_from:
- source
worker:
image: symfony/worker-dev
ports:
- "80:80"
- mongodb
volumes_from:
- source
volumes:
- "tmp/:/var/log/nginx"
One of the solutions is to execure the commands inside your container. I've tried multiple workarounds for the same issue I faced in the past. I find executing the command inside the container the most user-friendly.
Example command: docker-compose run CONTAINER_NAME php bin/console cache:clear. You may use make, ant or any modern tool to keep the commands short.
Example with Makefile:
all: | build run test
build: | docker-compose-build
run: | composer-install clear-cache
############## docker compose
docker-compose-build:
docker-compose build
############## composer
composer-install:
docker-compose run app composer install
composer-update:
docker-compose run app composer update
############## cache
clear-cache:
docker-compose run app php bin/console cache:clear
docker-set-permissions:
docker-compose run app chown -R www-data:www-data var/logs
docker-compose run app chown -R www-data:www-data var/cache
############## test
test:
docker-compose run app php bin/phpunit
Alternatively, you may introduce a .env file which contains a environment variables and then user one of the variables to run usermod command in the Docker container.

Resources