34

Just starting in docker here

So I got this in my docker-compose.yml

version: '3.3'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - 8000:80
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_TABLE_PREFIX: "wp_"
      WORDPRESS_DEBUG: 1

  wordpress-cli:
    depends_on:
      - db
      - wordpress
    image: wordpress:cli
    command: wp core install --path="/var/www/html" --url=localhost --title="Local Wordpress By Docker" --admin_user=admin --admin_password=secret --admin_email=foo@bar.com

volumes:
  db_data:

So I wanted to run the wp core install so that I won't have to go through the process of manually setting up my test wordpress site.

However when I run docker-compose up, this does not seem to work, I got this error on the console

enter image description here

What am I missing here? Anyone can help me accomplish my goal of automating the of setting up wordpress install?

Thanks in advance

Jplus2
  • 2,216
  • 2
  • 28
  • 49

3 Answers3

62

Well there are a couple of problems. The first one is that those two containers (wordpress and wordpress-cli) don't share a volume. So while wordpress has a wordpress installation ready, the wordpress-cli doesn't.

So you can add volumes to both containers, and then wordpress-cli will find the wordpress installation.

Then there's a second problem: the wordpress:latest and wordpress:cli images both run with the user www-data, but the problem is that the individual www-data users have different user-id's:

$ docker run --rm wordpress:latest grep www-data /etc/passwd 
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
$ docker run --rm wordpress:cli grep www-data /etc/passwd   
www-data:x:82:82:Linux User,,,:/home/www-data:/bin/false

It seems they aren't exactly compatible here. So if you use a shared volume you have to make sure they both use the same user-id. I solved this by having the wordpress:cli run with the user xfs which also has the user id 33.

The last problem is that your containers have dependencies on each other. Wordpress needs a running MySQL instance and the wordpress-cli needs also the MySQL and the Wordpress to be ready. To make sure MySQL is ready for the wordpress cli installation you either use something like "wait-for-it" or in a simple case you can just wait a couple of seconds and then try it.

I have tested all those changes and came up with the following docker-compose.yml. I have annotated all the changes I've made with "vstm":

version: "3.3"
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - 8000:80
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_TABLE_PREFIX: "wp_"
      WORDPRESS_DEBUG: 1
    # vstm: add shared volume
    volumes:
      - wp_data:/var/www/html

  wordpress-cli:
    depends_on:
      - db
      - wordpress
    image: wordpress:cli
    # vstm: This is required to run wordpress-cli with the same
    # user-id as wordpress. This way there are no permission problems
    # when running the cli
    user: xfs
    # vstm: The sleep 10 is required so that the command is run after
    # mysql is initialized. Depending on your machine this might take
    # longer or it can go faster.
    command: >
      /bin/sh -c '
      sleep 10;
      wp core install --path="/var/www/html" --url="http://localhost:8000" --title="Local Wordpress By Docker" --admin_user=admin --admin_password=secret --admin_email=foo@bar.com
      '
    # vstm: add shared volume
    volumes:
      - wp_data:/var/www/html

volumes:
  db_data:
  # vstm: add shared volume
  wp_data:

It uses a docker-volume but you can also map it to a filesystem. Depends on how you plan to use your docker-compose.

vstm
  • 12,407
  • 1
  • 51
  • 47
  • Thank you very much mate! Tried on Docker CE 18.03 on Windows 10 pro and it worked! Great detailed explanation, appreciate it! – Jplus2 Jun 24 '18 at 00:12
  • hey man if its not much of a bother, can you please elaborate on the **user:xfs** part? basically this command switches the active user to **xfs**? so **xfs** is a user created by **wordpress:cli** container? Thanks in advance. – Jplus2 Jun 24 '18 at 03:26
  • 2
    I already touched on the xfs part a bit in my answer, but the gist of it is that xfs user in the `wordpress:cli` image has the UID 33, which is the same UID as the www-data user in the `wordpress:latest` image. Having both commands run with the same UID is important so that they can read/write the shared volume (`wp_data`) without permission problems. – vstm Jun 24 '18 at 13:43
  • 1
    @vstm Is `version: "2.3"` a typo, should that be `3.3`? – Don't Panic May 07 '19 at 13:58
  • @Don'tPanic: Ah indeed - thank you for pointing that out. I fixed my answer. – vstm May 11 '19 at 07:38
  • just getting into this and wondering how we run that command ? Is it automatic? thanks and sorry of its obvious! – v3nt Jul 22 '19 at 08:58
  • 1
    It looks like this doesn't work anymore, copy & pasted the example verbatim and got `Error: This does not seem to be a WordPress installation.` – Shakeel Jun 10 '20 at 05:16
  • @Shakeel: sorry for my late response. I Just tested it with a clean install and it still semed to work on my machine. The error might indicate that the install script wasn't executed, the startup might have taken too long or there was an error during install. Can you do a `docker-compose up -d` and then `docker-compose up wordpress-cli` This should show for one re-run the install command and show errors during install (if there are any). – vstm Jun 16 '20 at 11:12
  • With the `wordpress:latest` I started getting this error: `/bin/sh: EbXKjxP5G4#: not found`. Any ideas? – HairLessDude Jun 28 '20 at 00:35
  • @HairLessDude: I tested it as well, works for me with a clean pull of `wordpress:latest` and `wordpress:cli` is it really the `wordpress` service that fails and not the `wordpress-cli` ? Check if there maybe a syntax error in the docker-compose under `command:` of `wordpress-cli`. – vstm Jun 29 '20 at 18:39
  • How command move to `Dockerfile` in `wordpress-cli` service? – Vito Bryliano Jun 24 '22 at 23:44
7

This one worked for me:

  wpcli:
    depends_on: 
      - mysql
      - wordpress
    image: wordpress:cli
    links:
      - mysql:db
    entrypoint: wp
    command: "--info"
    container_name: ${COMPOSE_PROJECT_NAME}_wpcli
    volumes:
      - ${WORDPRESS_DATA_DIR:-./wordpress}:/var/www/html
    working_dir: /var/www/html

Note that in the line:

links:
  - mysql:db

mysql = name of my service db = alias name I gave it, can be anything

Then you issue run wp like so:

docker-compose run --rm wpcli WORDPRESS_COMMAND

Source: https://medium.com/@tatemz/using-wp-cli-with-docker-21b0ab9fab79

csaborio
  • 111
  • 1
  • 7
4

this's my first answer at Stack Overflow :">

Actually, your question inspired me, and @vstm's answer guided me a bit.

You could try my piece of code:

1.wait-for-mysql.sh

#!/bin/bash -e

HOST=$(echo $WORDPRESS_DB_HOST | cut -d: -f1)
PORT=$(echo $WORDPRESS_DB_HOST | cut -d: -f2)

CMD=$@

until mysql -h $HOST -P $PORT -D $WORDPRESS_DB_NAME -u $WORDPRESS_DB_USER -p$WORDPRESS_DB_PASSWORD -e '\q'; do
  >&2 echo "Mysql is unavailable - sleeping..."
  sleep 2
done

>&2 echo "Mysql is up - executing command"
exec $CMD

2.compose.yml

version: '3.9'

services:

  wordpress:
    image: wordpress:5.7.0-php7.4-apache
    ports:
      - "80:80"
    volumes:
      - ./wp-data/:/var/www/html/
    networks:
      wp-net: {}

  wp-cli:
    image: wordpress:cli-2.4.0-php7.4
    depends_on:
      - wordpress
    volumes:
      - ./wait-for-mysql.sh:/wait-for-mysql.sh
      - ./wp-data:/var/www/html/ # shared with wordpress service
    user: "33"
    command: >
      /wait-for-mysql.sh
      wp core install
      --path="/var/www/html"
      --url="http://your-url-here"
      --title=your-title-here
      --admin_user=your-user-here
      --admin_password=your-password-here
      --admin_email=your-email-here}
      --skip-email
    networks:
      wp-net: {}

networks:
  wp-net: {}

For your reference:

Hino
  • 56
  • 3