When I’m running WordPress inside a docker container, I usually only mirror the wp-content directory from the container to the host. You shouldn’t change anything in the other WordPress directories anyway and you avoid many volume syncs. The problem with this approach is that you can’t run the wp-command from the host, you have to run WP-CLI inside Docker, that means logging in to the container running the commands and logging out again. Assuming your container is called wp-container the following commands would do that:

docker exec -ti wp-container bash
wp plugin list

It’s just a little inconvenience, but why not save some command when we can?

I’m using gulp as task-manager for most of my projects, and added a task which forwards all commands to WP-CLI inside Docker. It even checks if the container is running and if WP-CLI is installed inside the container. If not it will be automatically installed.

var gulp = require('gulp');
var spawn = require('child_process').spawn;

var checkContainers = function(names, done) {
  var exec = require('child_process').exec;
  exec('docker ps --format {{.Names}}', function(error, stdout, stderr) {
    done(names.map(function(name) {
      return stdout.split("\n").indexOf(name) >= 0;
    }).reduce(function(running, next) {
      return running && next;
    }, true));

var checkWPCli = function(container, done) {
  var exec = require('child_process').exec;
  exec('docker exec ' + container + ' bash -c \'wp\'', function(error, stdout, stderr) {}).on('exit', function(code) {
    done(127 !== code);

var installWPCli = function(container, done) {
  var exec = require('child_process').exec;
  exec('docker exec ' + container + ' bash -c \'apt-get update && apt-get install -y less && 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 && wp --allow-root cli\'', function(error, stdout, stderr) {}).on('exit', function(code) {
    done(0 === code);

var runWPCli = function(container, done) {
  var command = process.argv.slice(process.argv.indexOf('-c') + 1);

  if (!command.length) {
    console.log('ERROR: Provide a valid wp-cli command!');
    return done();

  var exec = require('child_process').exec;
  exec('docker exec ' + container + ' bash -c \'wp --allow-root ' + command.join(' ') + '\'', function(error, stdout, stderr) {
  }).on('exit', function(code) {

gulp.task( 'wp', function(done) {

  checkContainers(['wp-container'], function(containerRunning) {

    if (!containerRunning) {
      console.log('ERROR: wp-container container is not running. Try "docker-compose up -d"')
      return done();

    checkWPCli('wp-container', function(wpCliRunning) {
      if (!wpCliRunning) {

        console.log('WARNING: wp cli not installed, trying auto install ...');

        installWPCli('wp-container', function(wpCliRunning) {

          console.log('SUCCESS: wp cli installed!');
          runWPCli('wp-container', done);

      } else {

        runWPCli('wp-container', done);



So, with that gulp task in place, you will be able to run the following commands and every other WP-CLI command as well:

gulp wp -c "plugin list"
gulp wp -c "plugin install advanced-custom-fields"

What do you think?

Is that to much hassle for running some wp-commands or would you use the gulp forward in your daily work? Let me know!

In the last couple of months I’ve worked a great deal with WordPress as backend system, providing data to a JavaScript frontend via the Rest API. As I couldn’t find a complete solution for my favorite frontend-framework, my “getting started” process always repeated the following steps

  • set up WordPress development environment (docker)
  • integrate Javascript frontend in the code
  • setup environment for the frontend (docker)
  • make the two environments talk to each other (not always as easy as you think)
  • setup a simple JavaScript framework to query the WordPress API from the frontend

As that procedure eats up a whole lot of project hours, the time was ready for an easier solution. So, together with my colleague Oliwer at Northosts and much appreciated input and testing from my friend Samuel, I started working on a WordPress/Nuxt.js hybrid development environment. Our goal was to provide a one-command-installation, which makes you ready to go in 5 minutes.

Now we are finally ready for our first release, so say hello to WUXT!

WUXT Components

WUXT combines a couple of components you almost certainly already know from other projects, adds some convenient new functionality and solves a handfull of configuration problems. Following a short overview of all components

Docker containers: To provide a consistent development experience on all platforms, we use Docker (what else?). Three containers are needed, one for the WordPress database (mysql.wuxt), one for WordPress (wp.wuxt) and one for nuxt.js (front.wuxt). Everything is set up with docker-compose. We were extra careful to base everything on the official images (mysql, wordpress and node) and skip custom docker-files, which should make it a lot easier to upgrade the environment. The relevant files from the container are mirrored to the host with volumes, which makes the database persistent (_db folder), lets you access everything important in WordPress (wp-content directory) and nuxt.js (nuxt folder).

WordPress Rest API extensions: The WordPress API is awesome, but to use WordPress full strength in our nuxt.js frontend, we needed some additional functionality. Activating our WUXT-theme adds endpoints for menus, the front-page settings, getting pages and posts by slug and includes meta-data from well known plugins. We are constantly adding new endpoints to support even more use-cases.

WordPress connector in nuxt.js: It’s not difficult to setup some requests to the WordPress API from nuxt.js, but we wanted a standardized way. That’s why we included the wpapi node module into our nuxt application (you have always access via the $wp object). Even here we did some adjustments, to make sure the connection to the WordPress Rest API can be established both from the nuxt-container to the wp-container and from the client application to the wp-container. Of course, we also added some shortcuts to support our new endpoints for menus, front-page, custom post types etc.

Development tools: Docker is so great, but sometimes it makes developer lives a little bit more difficult. Logging in to the container to run a wp-cli command can be a hassle, file permissions when working with volumes might be another. To make that a little bit more easy we added gulp tasks to give you access to wp-cli or installing new node-modules inside the container, without accessing it. We even provide a post-type generator for gulp, which lets you create automatically loaded, API-ready post-types in seconds.

Nothing of the above is rocket-science, but I think the combination and packaging into one, complete environment should make a difference for everyone developing with WordPress and nuxt.js. Please try it out and give us feedback, issues or some of your spare-time to make WUXT better.

Getting started

First clone the repository to a directory you want, then change to that directory and simply start your containers (you need to have a running Docker installation of course):

docker-compose up -d

That starts the following containers:

  • MySql (mysql.wuxt) 
  • WordPress (wp.wuxt)
  • nuxt.js (front.wuxt)

Your containers are available at

  • Frontend: http://localhost:3000
  • Backend: http://localhost:3080http://localhost:3080/wp-admin
  • Database: docker exec -ti mysql.wuxt bash

Setup WordPress

After starting the containers the first time you have to do a common WordPress installation at http://localhost:3080/install.php. Then log in to wp-admin and select the wuxt theme to activate all the API extensions. Additionally you might want to activate the ACF plugin to make your meta work easier. Last but not least you have to set the permalink structure to “Post Name” in the WordPress settings.

To check if everything is running, visit http://localhost:3080 and verify that the WUXT info screen is showing.

Then check that the Rest API at http://localhost:3080/wp-json is returning a JSON-object and you are good to go.

Setup nuxt.js

Nuxt should have been started automatically inside the docker container. The command we use for running the nuxt.js server is yarn dev. Check if the frontend is running by opening http://localhost:3000. You should be greeted by the Wuxt intro-screen.

Finally check if BrowserSync is running, by doing a minor change to the front-page. The change should directly be visible on the front-page as well.


Please let us know what you think about WUXT, what you did with it and what you couldn’t do. Please clone, fork, open issues, comment or contribute, it’s much appreciated.

Since 5.0 the Gutenberg block-editor is here and it seems like curiosity about what you can do with it, slowly surpasses the panic about what Gutenberg could do to all your beloved projects. To get the block-editor into one of your existing projects, there are some hurdles to take:

  • getting to know Gutenbergs editing experience
  • building at least one block-ready template
  • deactivating classic editor (not really a hurdle)
  • and … convincing your client

Say you tackled all these problems and your Gutenberg migration project is good to go: how do you start?

Step by Step: Gutenberg for specific posts or pages

In my (very humble) experience of one finished and one ongoing block-editor migration project, if you can’t start from scratch, you should do it step by step, post by post and page by page. First group your posts and pages by special features and make a plan about how you can build them in Gutenberg. Which blocks do you need, can you apply an own color scheme, what about forms, custom fields and short-codes etc.

With that plan in place, you can now get to one pilot post and start to shape it in the Gutenberg-way. At the same time you don’t want to interfere with your clients possible changes to other posts and you want to give them the chance to get to know the block-editor in a limited playground. So now you have to do some coding.

  1. Deactivate Gutenberg everywhere. I know, you just activated it. But remember, you basically want to preserve the classic experience on the entire site, so that has to be the default. This time, we don’t use the plugin, though. We use this line of code in the functions.php file:
    // Disable Gutenberg for all posts
    add_filter('use_block_editor_for_post', '__return_false', 5);
  2. Next step is to activate the Gutenberg block-editor for specific posts and pages. I think the best way is to use a special meta field, which I called use_gutenberg. If that field is true, you just activate the Gutenberg block-editor with the appropriate filter (use_block_editor_for_post).
    function theme_enable_gutenberg_post_meta($can_edit, $post) {
    	if (empty($post->ID)) return $can_edit;
    	if (get_post_meta($post->ID, 'use_gutenberg', true)) return true;
    	return $can_edit;
    add_filter('use_block_editor_for_post', 'theme_enable_gutenberg_post_meta', 10, 2);

If you add the meta-field with ACF, like I did, it might look like that:

Now you can transfer the group of pages and finally the entire site to Gutenberg in a very controlled and fail-safe way. Your clients will thank you!

Do you have thought about Gutenberg migrations or other experience of transferring the block-editor to existing sites, please let me know in the comments.


Today it’s my special honor to introduce a new WordPress-blog of a friend of mine: wpahead.com. It’s main focus is WP front-end building and I know there is a ton of expertise behind these well written tips, articles and tutorials.

I’ve got a lot of great ideas from the tutorial about building Gutenberg-blocks with the new Advanced Custom Fields beta-version, will use that setup in many of my future projects.

Good luck to our new star in the WordPress blogging community!

Some days ago I proudly had my first WordCamp talk about ElasticSearch and how to integrate it in WordPress. It’s in Swedish (with a slightly embarrassing German accent) and I think it’s worth listening to. Here is the video:

For you, who don’t understand Swedish, there are some code-slides about ElasticPress features and integration of WP-Query. Check out all slides here.

Thanks to my very supportive “hejarklack” from Wilson Creative: @pixelcrook, @sofievingstedt, @wilsonrobin and Martin Carstedt. Many thanks even to Andreas Ek (@elseifab) for a much appreciated peptalk (Andreas had a really interesting talk about MVC in WordPress as well!).

Last but not least thanks to everyone who made this awesome WordCamp happen!