wordpressdockerdocker-compose

Docker compose php-fpm, nginx, MySQL and use wp-cli on nginx


I linked 3 separate containers together:

my goal is to run wp-cli installation before the source code being copied into the nginx container.

issues:

  1. trying to run installation script of wp-cli from Dockerfile (my-nginx image) works fine, but when I try running any wp-cli commands it returns error: env: can't execute 'php': No such file or directory
  2. wp-cli installation script (with the right dependencies) works also on dockerfile.php-fpm (my-php image), it returns an error as well : Error: YIKES! It looks like you're running this as root. You probably meant to run this as the user that your WordPress install exists under. and offers me to run this command with the flag --allow-root, which is bad in this case because I want to use wp user permissions. or to run this command as another user.

#core configurations

docker-compose.yml:

version: '2'
services:

my-nginx:
    build: .
    volumes:
      - .:/var/www/html
    ports:
      - "8080:80"
    links:
      - my-php
      - my-mysql
  my-php:
    build:
      context: .
      dockerfile: Dockerfile.php-fpm
    volumes:
      - .:/var/www/html
    ports:
      - "9000:9000"
  my-mysql:
    image: mariadb:5.5
    volumes:
      - /var/lib/mysql
 

nginx.conf:

server {
  server_name _;
  listen 80 default_server;

  root   /var/www/html;
  index  index.php index.html;

  access_log /dev/stdout;
  error_log /dev/stdout info;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ .php$ {
    include fastcgi_params;
    fastcgi_pass my-php:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }
}

wp-cli integration is cloned from : https://github.com/conetix/docker-wordpress-wp-cli

#option 1
Dokerfile:

FROM nginx:1.10-alpine

# add root dir
RUN mkdir -p /var/www/html
WORKDIR /var/www/html
ENV WP_ROOT /var/www/html

# Install requirements for wp-cli support
RUN apk update \
  && apk add less mysql-client sudo curl


# copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
   
    
# Add WP-CLI 
RUN curl -o /bin/wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
COPY wp-su.sh /bin/wp
RUN chmod +x /bin/wp-cli.phar \
    && sudo mv /bin/wp-cli.phar /usr/local/bin/wp

RUN  wp core download --allow-root
   
# copy all files for current dir (should be theme or plugin folder)
COPY . ./

Dockergile.php-fpm

FROM php:7.0.6-fpm-alpine  

VOLUME /var/www/html
RUN docker-php-ext-install -j $(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1)  iconv gd mbstring fileinfo curl xmlreader xmlwriter mysqli

#option 2
Dokerfile:

FROM nginx:1.10-alpine

# add root dir
RUN mkdir -p /var/www/html
WORKDIR /var/www/html

RUN apk update \
  && apk add less mysql-client sudo


# copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
   
   
# copy all files for current dir (should be theme or plugin folder)
COPY . ./

Dockergile.php-fpm

FROM php:7.0.6-fpm-alpine  

VOLUME /var/www/html
RUN docker-php-ext-install -j $(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1)  iconv gd mbstring fileinfo curl xmlreader xmlwriter mysqli

# Install requirements for wp-cli support
RUN apk update \
    && apk add curl sudo less
ENV WP_ROOT /var/www/html

# Add WP-CLI 
RUN curl -o /bin/wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
COPY wp-su.sh /bin/wp
RUN chmod +x /bin/wp-cli.phar \
    && sudo mv /bin/wp-cli.phar /usr/local/bin/wp

RUN  wp core download

general questions:

  1. what is the best practice for users permissions inside dockers?
  2. wp-cli integration from https://github.com/conetix/docker-wordpress-wp-cli/blob/master/wp-su.sh uses www-data user - should I add this user to my docker, and if so - to which one? ngnix or php-fpm and why.
  3. running wp download core from php-fpm container appears as if it download the files but when I try to exec when its running, none of this files shown at /var/www/html . is there a certain way to order images file mounting?
  4. why does 'php' isn't available command from my-nginx if I volume
    my-php image? I must install php also on this image?

Solution

  • PHP isn't installed in your nginx container. I'd argue that it should not be installed there either. Use your php fpm container to run WP CLI. Here's how I get WP CLI running using a similar setup:

    docker-compose.yml:

    version: '2'
    services:
      mysql:
        image: mysql:latest
        volumes:
          - "../.data/db:/var/lib/mysql"
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: my_database
          MYSQL_USER: my_user
          MYSQL_PASSWORD: password
      phpfpm:
        depends_on:
          - mysql
        image: my/phpfpm:latest
        build: ./docker/php-fpm
        volumes:
          - ".:/var/www/html"
          - "./docker/php-fpm/php.ini:/usr/local/etc/php/php.ini"
          - "./docker/php-fpm/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini"
        links:
          - mysql
        restart: always
        extra_hosts:
          - "mysite.dev:172.18.0.1" # Use the gateway address for your docker network for the ip address. This is so that PHP FPM can find nginx for the postback to do things like cron jobs with WordPress
      nginx:
        depends_on:
          - phpfpm
        ports:
          - "80:80"
        image: nginx:latest
        volumes:
          - ".:/var/www/html"
          - "./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf"
        links:
          - phpfpm
        restart: always
    

    docker/php-fpm/Dockerfile:

    FROM php:5.5-fpm
    
    ARG INSTALL_XDEBUG=true
    ENV INSTALL_XDEBUG ${INSTALL_XDEBUG}
    RUN if [ ${INSTALL_XDEBUG} = true ]; then \
        pecl install xdebug && \
        docker-php-ext-enable xdebug \
    ;fi
    
    RUN apt-get update && apt-get install -y libz-dev libmemcached-dev libjpeg-dev libpng-dev \
        && pecl install memcached \
        && docker-php-ext-enable memcached \
        && docker-php-ext-install -j$(nproc) pdo pdo_mysql mysqli gd \
        && docker-php-ext-enable pdo pdo_mysql mysqli gd
    
    RUN docker-php-ext-install zip \
        && docker-php-ext-enable zip
    
    RUN curl https://getcomposer.org/download/1.2.0/composer.phar > /tmp/composer.phar \
        && chmod +x /tmp/composer.phar \
        && mv /tmp/composer.phar /usr/local/bin/composer \
        && apt-get update && apt-get install -y less \
        && curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar > /tmp/wp-cli.phar \
        && chmod +x /tmp/wp-cli.phar \
        && mv /tmp/wp-cli.phar /usr/local/bin/wp
    
    CMD ["php-fpm"]
    
    EXPOSE 9000
    

    I also use a memcached container, so that's why the dockerfile is also installing the memcached extension. The important parts are where it installs WP CLI and moves it into place. You can also modify the version of PHP that's installed by changing it in that dockerfile. Once you have your cluster up and running with WP CLI installed on PHP, you can run the following command to run wp cli commands inside the container:

    docker exec -u www-data <container_name> wp ... # whatever command after that
    

    I have aliases for different projects that already have the container names:

    alias mywp="docker exec -u www-data mysite_phpfpm_1 wp"
    

    and that lets me run wp commands like this:

    mywp core update-db --network
    mywp post meta list 2119