How to run wp cli in docker-compose.yml

18,942

Solution 1

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 [email protected]
      '
    # 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.

Solution 2

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

Solution 3

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:

Share:
18,942

Related videos on Youtube

Jplus2
Author by

Jplus2

Web Developer

Updated on June 26, 2022

Comments

  • Jplus2
    Jplus2 about 2 years

    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 [email protected]
    
    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
    Jplus2 about 6 years
    Thank you very much mate! Tried on Docker CE 18.03 on Windows 10 pro and it worked! Great detailed explanation, appreciate it!
  • Jplus2
    Jplus2 about 6 years
    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.
  • vstm
    vstm about 6 years
    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.
  • Don't Panic
    Don't Panic about 5 years
    @vstm Is version: "2.3" a typo, should that be 3.3?
  • vstm
    vstm about 5 years
    @Don'tPanic: Ah indeed - thank you for pointing that out. I fixed my answer.
  • v3nt
    v3nt almost 5 years
    just getting into this and wondering how we run that command ? Is it automatic? thanks and sorry of its obvious!
  • Shakeel
    Shakeel about 4 years
    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.
  • vstm
    vstm about 4 years
    @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).
  • HairLessDude
    HairLessDude almost 4 years
    With the wordpress:latest I started getting this error: /bin/sh: EbXKjxP5G4#: not found. Any ideas?
  • vstm
    vstm almost 4 years
    @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.
  • Vito Bryliano
    Vito Bryliano about 2 years
    How command move to Dockerfile in wordpress-cli service?