3

I followed this giude to install wordpress in a container for test purposes but using mariadb and linux as a host. Here is my docker-compose:

version: '3.8'

services: 
    database:
        image: mariadb
        restart: always
        environment: 
            MYSQL_ROOT_PASSWORD: password
            MYSQL_DATABASE: wordpressDB
            MYSQL_USER: user
            MYSQL_PASSWORD: password
        volumes:
            - mysql:/var/lib/mysql
    
    wordpress:
        depends_on: 
            - database
        links: 
            - database
        image: wordpress:latest
        restart: always
        ports: 
            - '8000:80'
        environment: 
            WORDPRESS_DB_HOST: database:3306
            WORDPRESS_DB_USER: user
            WORDPRESS_DB_PASSWORD: password
            WORDPRESS_DB_NAME: wordpressDB
        volumes: 
            - ./wordpress:/var/www/html
            - ./wordpress/plugins:/var/www/html/wp-content/plugins
            - ./wordpress/themes:/var/www/html/wp-content/themes
            - ./wordpress/uploads:/var/www/html/wp-content/uploads
            - ./wordpress/wp-content:/var/www/html/wp-content

volumes: 
    mysql: {}

For now I can access the wp-admin dashboard but can't update/install any plugin with error:

Could not create directory.

As mentioned here I've tried to change the permissions of the folders but with no success:

$ mkdir /var/www/html/wp-content/plugins
$ mkdir /var/www/html/wp-content/uploads
$ chown -R www-data:www-data /var/www
$ find /var/www/ -type d -exec chmod 0755 {} \;
$ find /var/www/ -type f -exec chmod 644 {} \;

Here is the output from ls -l

-rwxrwxr-x 1 1000 985   405 Jul 12 06:30 index.php
-rwxrwxr-x 1 1000 985 19915 Jul 12 06:30 license.txt
drwxrwxr-x 1 1000 985     0 Jul 12 06:30 plugins
-rwxrwxr-x 1 1000 985  7345 Jul 12 06:30 readme.html
drwxrwxr-x 1 1000 985     0 Jul 12 06:30 themes
drwxrwxr-x 1 1000 985     0 Jul 12 06:30 uploads
-rwxrwxr-x 1 1000 985  7165 Jul 12 06:30 wp-activate.php
drwxrwxr-x 1 1000 985 20480 Jul 12 06:30 wp-admin
-rwxrwxr-x 1 1000 985   351 Jul 12 06:30 wp-blog-header.php
-rwxrwxr-x 1 1000 985  2328 Jul 12 06:30 wp-comments-post.php
-rwxrwxr-x 1 1000 985  5456 Jul 12 06:30 wp-config-docker.php
-rwxrwxr-x 1 1000 985  2913 Jul 12 06:30 wp-config-sample.php
-rwxrwxr-x 1 1000 985  5592 Jul 12 07:03 wp-config.php
drwxrwxr-x 1 1000 985     0 Jul 12 06:30 wp-content
-rwxrwxr-x 1 1000 985  3939 Jul 12 06:30 wp-cron.php
drwxrwxr-x 1 1000 985 40960 Jul 12 06:30 wp-includes
-rwxrwxr-x 1 1000 985  2496 Jul 12 06:30 wp-links-opml.php
-rwxrwxr-x 1 1000 985  3313 Jul 12 06:30 wp-load.php
-rwxrwxr-x 1 1000 985 44994 Jul 12 06:30 wp-login.php
-rwxrwxr-x 1 1000 985  8509 Jul 12 06:30 wp-mail.php
-rwxrwxr-x 1 1000 985 21125 Jul 12 06:30 wp-settings.php
-rwxrwxr-x 1 1000 985 31328 Jul 12 06:30 wp-signup.php
-rwxrwxr-x 1 1000 985  4747 Jul 12 06:30 wp-trackback.php
-rwxrwxr-x 1 1000 985  3236 Jul 12 06:30 xmlrpc.php

Where am I mistaken?

Tony
  • 618
  • 12
  • 27
  • 1
    It might be permissions on the host directory, i.e. `./wordpress`. – Hans Kilian Jul 12 '21 at 07:55
  • @HansKilian Isn't the `chown -R www-data:www-data /var/www` command for the `./wordrepss` folder permissions? I tried with `chmod 777 /var/` the result is the same. – Tony Jul 12 '21 at 08:05
  • 1
    in wordpress container you need to volume `wordpress_data:/var/www/html` it's enough. other volume is not necessary. – rezshar Jul 12 '21 at 08:49
  • 1
    @rezshar thanks, I added the other volumes because I thought that may change the permissions – Tony Jul 12 '21 at 08:51
  • @rezshar updated with solution. – Tony Jul 15 '21 at 09:01

3 Answers3

8

get docker container name

sudo docker ps
// output wordpress

interactive with container shell

docker exec -it wordpress /bin/bash

give permission to the user

chown -R www-data:www-data /var/www/html

exit the shell

exit
Ahmed Elsayed
  • 338
  • 2
  • 11
  • This actually worked correctly for me and allowed me to download plugins, update core, etc..many thanks! Can you explain your 3rd step more in detail? i.e. who is the user in that case? – klewis Sep 01 '23 at 23:28
3

After a bit of digging, the problem is with this line that I added in my config.php that removed the missing FTP error when I started the container:

define('FS_METHOD', 'direct');

After that I tried many times to chown the directories of the site, with no success. Which is strange because I used the root account to change them. However they remained to group users.

In the end I added the www-data user to users and root (just in case) groups and that solved the problem.

usermod -a -G users www-data
usermod -a -G root www-data

Update

Another solution I found is instead of using a bind volume ./wordpress to use normal volume wordpress with read/write permissions. Here is the new docker-compose:

wordpress:
        depends_on: 
            - database
        links: 
            - database
        image: wordpress:latest
        restart: always
        read_only: false
        ports: 
            - '8000:80'
        environment: 
            WORDPRESS_DB_HOST: database:3306
            WORDPRESS_DB_USER: user
            WORDPRESS_DB_PASSWORD: password
            WORDPRESS_DB_NAME: database
        volumes: 
            - wordpress:/var/www/html:rw

After the mentioned change the output of ls -l for the folders is like this:

-rw-r--r-- 1 www-data www-data   405 Feb  6  2020 index.php
-rw-r--r-- 1 www-data www-data 19915 Jan  1  2021 license.txt
-rw-r--r-- 1 www-data www-data  7345 Dec 29  2020 readme.html
-rw-r--r-- 1 www-data www-data  7165 Jan 21 01:37 wp-activate.php
drwxr-xr-x 1 www-data www-data  2668 May 12 23:49 wp-admin
-rw-r--r-- 1 www-data www-data   351 Feb  6  2020 wp-blog-header.php
-rw-r--r-- 1 www-data www-data  2328 Feb 17 13:08 wp-comments-post.php
-rw-rw-r-- 1 www-data www-data  5456 Jul  2 02:02 wp-config-docker.php
-rw-r--r-- 1 www-data www-data  2913 Feb  6  2020 wp-config-sample.php
-rw-r--r-- 1 www-data www-data  5560 Jul 15 07:30 wp-config.php
drwxr-xr-x 1 www-data www-data    54 May 12 23:49 wp-content
-rw-r--r-- 1 www-data www-data  3939 Jul 30  2020 wp-cron.php
drwxr-xr-x 1 www-data www-data  8378 May 12 23:49 wp-includes
-rw-r--r-- 1 www-data www-data  2496 Feb  6  2020 wp-links-opml.php
-rw-r--r-- 1 www-data www-data  3313 Jan 10  2021 wp-load.php
-rw-r--r-- 1 www-data www-data 44994 Apr  4 18:34 wp-login.php
-rw-r--r-- 1 www-data www-data  8509 Apr 14  2020 wp-mail.php
-rw-r--r-- 1 www-data www-data 21125 Feb  2 00:10 wp-settings.php
-rw-r--r-- 1 www-data www-data 31328 Jan 27 21:03 wp-signup.php
-rw-r--r-- 1 www-data www-data  4747 Oct  8  2020 wp-trackback.php
-rw-r--r-- 1 www-data www-data  3236 Jun  8  2020 xmlrpc.php

Now wordpress updates/installs plugins and the update of wordpress itself is working flawlessly.

Tony
  • 618
  • 12
  • 27
1

You should make your volumes like shown below:

    volumes:
      - ./wp-content/uploads:/usr/src/wordpress/wp-content/uploads
      - ./wp-content/plugins:/usr/src/wordpress/wp-content/plugins
      - ./wp-content/themes:/usr/src/wordpress/wp-content/themes
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini

I found this solution in a discussion at:

https://github.com/docker-library/wordpress/issues/341

The WordPress image copies every file/folder found in /usr/src/worpress folder to the /var/www/html/ folder. When the copy begins it also changes the user and group permissions of the file so that the WordPress application can use it.

Hope this helps. You might also want to look at the links below.

https://salzam.com/dockerize-wordpress-with-themes-plugins-and-common-configuration/

docker/wordpress: seperate default plugins from own plugins

EDIT 30-08-2022

Adding WordPress Themes, Plugins, and/or Media files.

Always add new things through the WordPress Application directly when installing new features. This is needed to save the state of the features within the database correctly.

When altering files within the binding mount the containers must be recreated. You should make your volumes like shown below. This is because of the following:

db:
    volumes:
      # This volume will make your database persistent and thus will
      # be reloaded when recreating a container.
      - ./db:/var/lib/mysql:delegated

wordpress:
    volumes:
      # These binding mounts makes sure everything from the OS comes into
      # the container with the correct rights.
      - ./wp-content/uploads:/usr/src/wordpress/wp-content/uploads
      - ./wp-content/plugins:/usr/src/wordpress/wp-content/plugins
      - ./wp-content/themes:/usr/src/wordpress/wp-content/themes
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
      
      # The wordpress image then copies everything from
      # /usr/src/wordpress to /var/www/html/ 
      # including the correct rights
      
      # These binding mounts make sure everything that is added through
      # the WordPress application also comes back to your project repository.
      - ./wp-content/uploads:/var/www/html/wp-content/uploads
      - ./wp-content/plugins:/var/www/html/wp-content/plugins
      - ./wp-content/themes:/var/www/html/wp-content/themes

When altering the files on ones own OS one first must change ownership again or use root. For example, you uploaded a new plugin using the plugin manager of WordPress. It gets installed correctly and is activated. In the database a boolean is made and saved in the wp-options tables to ensure it is activated. Now when changing a file within the plugin or theme files the application will not break or give errors (other than errors from incorrect code that has been added).

  • `./wp-content/uploads:/usr/src/wordpress/wp-content/uploads` `- ./wp-content/plugins:/usr/src/wordpress/wp-content/plugins` `- ./wp-content/themes:/usr/src/wordpress/wp-content/themes` are doing nothing because you are overriding them immediately below. You only need `./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini` to fix the upload permissions. – joshmoto Aug 31 '22 at 17:30