Marinus Klasen

Marinus Klasen

  • WordStress
  • Development
  • Consultancy
  • Developer Resources
  • Blog
  • Contact

January 1, 2022

Adding and using WP-CLI in a docker-compose setup

Marinus Klasen

For most of my WordPress projects I use my own Alcedo WordPress workflow. With some extra scripts, creating a new site is as easy as running 'create site.c7'in the terminal. This sets up a full WordPress install with local domains and certificates.

But, in this case i’m using a different setup in which I use the default wordpress:php8.0 docker image. As i’m using the standard setup, I also wanted to use the default wordpress:cli docker image.

How does that work?

As they say, an image says more then a thousands words. But, since text in images can’t be copied, I’ll copy/paste the two services below:

  wp:
    container_name: ${NAME}-wp
    depends_on:
      - db
    image: wordpress:php8.0
    user: 1000:1000
    volumes:
      - ./app/www/content/plugins:/var/www/html/wp-content/plugins
      - ./app/www/content/mu-plugins:/var/www/html/wp-content/mu-plugins
      - ./app/www/content/themes:/var/www/html/wp-content/themes
      - uploads:/var/www/html/wp-content/uploads:rw
      - wordpress:/var/www/html
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: ${NAME}-db:3306
      WORDPRESS_DB_USER: ${DB_USER}
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
      WORDPRESS_DB_NAME: ${DB_NAME}
      WORDPRESS_DEBUG: 1
      VIRTUAL_HOST: "${SITE_DOMAIN}" # Used for nginx-proxy
      VIRTUAL_PORT: 80 # Used for nginx-proxy
      LETSENCRYPT_HOST: "${SITE_DOMAIN}" # Used for nginx-proxy
      WORDPRESS_CONFIG_EXTRA: |
        /* Multisite */
        define( 'MULTISITE', true );
        define( 'SUBDOMAIN_INSTALL', true );
        define( 'DOMAIN_CURRENT_SITE', 'sitec7' );
        define( 'PATH_CURRENT_SITE', '/' );
        define( 'SITE_ID_CURRENT_SITE', 1 );
        define( 'BLOG_ID_CURRENT_SITE', 1 );
    expose:
      - "80"
  
  wpcli:
    container_name: ${NAME}-cli
    depends_on:
      - wp
    image: wordpress:cli
    user: 1000:1000
    command: tail -f /dev/null
    volumes:
      - wordpress:/var/www/html
    environment:
      WORDPRESS_DB_HOST: ${NAME}-db:3306
      WORDPRESS_DB_USER: ${DB_USER}
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
      WORDPRESS_DB_NAME: ${DB_NAME}
    profiles:
      - dev

As you see, both images use the same volume and environment setup. This allows you to run commands like:

docker exec site-cli wp --info

and

docker exec site-cli wp search-replace "test" "test1" --dry-run

Want to make it even easier? Set an alias for docker exec site-cli wp so that you can run something like sitewp --info. In my own development environment, my folders are named the same as my container. When you change directory, and the directory has an .env file, an alias is set for wp and links to the correct container.

Happy developing!

About Marinus Klasen

Marinus has been working in software/web development for more than a decade. Since 2020 his attention shifted on sharing knowledge and developing products and tools for sharing knowledge.

Marinus Klasen on Twitter

Looking for a WordPress expert?
Hire top notch developers on Codeable!

Consult an expert

Comments

  1. Mauricio says

    May 7, 2023 at 10:34 pm

    Hey,
    I added your wp-cli snippet to my docker-compose.yml but it didn’t work.
    It runs with no error but there’s no wpcli container.

    services:
    db:
    image: mariadb:latest
    command: ‘–default-authentication-plugin=mysql_native_password’
    volumes:
    – ./db_data:/var/lib/mysql
    restart: always
    environment:
    – MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
    – MYSQL_DATABASE=${DB_NAME}
    – MYSQL_USER=gpuser${DB_USER}
    – MYSQL_PASSWORD=${DB_PASSWORD}
    networks:
    – backend

    redis:
    image: redis:alpine
    restart: always
    volumes:
    – ./redis_data:/data
    networks:
    – backend

    pma:
    image: phpmyadmin/phpmyadmin
    environment:
    PMA_PORT: 3306
    PMA_ARBITRARY: 1 # To allow fill db credentials
    restart: always
    depends_on:
    – db
    networks:
    – backend
    – frontend

    wp:
    image: wordpress:latest
    container_name: wp-${NAME}
    user: ${UID}:${GID} # echo $UID
    volumes:
    – ./wp_data:/var/www/html:rw
    – ./wordpress.ini:/usr/local/etc/php/conf.d/wordpress.ini
    restart: always
    environment:
    – WORDPRESS_DB_HOST=db
    – WORDPRESS_DB_NAME=${DB_NAME}
    – WORDPRESS_DB_USER=${DB_USER}
    – WORDPRESS_DB_PASSWORD=${DB_PASSWORD}
    – DISABLE_WP_CRON=true
    – WP_REDIS_HOST=redis
    – WP_CACHE_KEY_SALT=${SALT_KEY}
    networks:
    – backend
    – frontend

    wpcli:
    image: wordpress:cli
    container_name: wpcli-${NAME}
    depends_on:
    – wp
    – db
    user: ${UID}:${GID}
    command: tail -f /dev/null
    volumes:
    – ./wp_data:/var/www/html
    environment:
    – WORDPRESS_DB_HOST=db
    – WORDPRESS_DB_NAME=${DB_NAME}
    – WORDPRESS_DB_USER=${DB_USER}
    – WORDPRESS_DB_PASSWORD=${DB_PASSWORD}
    profiles:
    – dev
    networks:
    – backend
    – frontend

    networks:
    frontend:
    external: true
    backend:
    external: true

    volumes:
    db_data:
    wp_data:

    Reply
    • Marinus Klasen says

      May 8, 2023 at 8:26 am

      You might want to try removing this part;
      “`
      profiles:
      – dev
      “`

      Reply
  2. Vilasamuni says

    May 6, 2024 at 3:20 pm

    Thanks for your post, very helpful!
    On the wp-cli service, the ‘command: tail -f /dev/null’ line seems to be necessary to prevent the container from immediately dying, but I’ve read lots of other tutorials and I haven’t seen this done anywhere else. How come no one else does this? How do they use the WP CLI image?

    Reply
    • Marinus Klasen says

      May 8, 2024 at 2:28 pm

      I like to keep them running, but I think others use (start and stop) the container by running commands on it directly

      Reply
  3. Mauricio says

    October 10, 2024 at 9:41 pm

    It worked like a charm! Thank you, Marinus!

    Reply
  4. Indi says

    December 6, 2024 at 9:59 pm

    why do you make this my brother I don’t understend why you put the cli on the new conrainer then you can using the cli into the first container wp I can show you

    execute this in your wp container my brother

    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

    Reply
  5. Albert says

    December 14, 2024 at 9:07 am

    Hello, does the alias take the name of the current directory?

    Reply
  6. Albert says

    December 14, 2024 at 9:07 am

    Does the alias take the name of the current directory?

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Get in touch

Contact me using the details below

Marinus Klasen

Wilhelmina van Pruisenweg 35, 2595 AN Den Haag

marinus@mklasen.com
twitter.com/marinusklasen
linkedin.com/in/marinusklasen

  • GitHub
  • LinkedIn
  • Twitter

Have you read?

  • Elementor Widget UsageMarch 27, 2025
  • Programmatically showing popups with ElementorMarch 25, 2025
  • The Elementor sanitize_settings errorSeptember 12, 2024
  • Announcing.. Wooping Shop Health!June 13, 2024
  • Swiper setup when using wp-scriptsMarch 14, 2024

Copyright © 2025 · Marinus Klasen | Webdesign by Team Rood