skip to Main Content

Having an issue with a Docker WordPress container for phpunit, configured with Docker Compose.

When the two services have been started:

Error: Error establishing a database connection. This either means that the username and password information in your `wp-config.php` file is incorrect or that contact with the database server at `mysql` could not be established. This could mean your host’s database server is down.

In docker logs <phpunit>:

Error: This does not seem to be a WordPress installation.
Pass --path=`path/to/wordpress` or run `wp core download`.
WordPress not found in /var/www/html - copying now...
Complete! WordPress has been successfully copied to /var/www/html
No 'wp-config.php' found in /var/www/html, but 'WORDPRESS_...' variables supplied; copying 'wp-config-docker.php' (WORDPRESS_DB_HOST WORDPRESS_DB_NAME WORDPRESS_DB_PASSWORD WORDPRESS_DB_USER)
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.224.3. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 192.168.224.3. Set the 'ServerName' directive globally to suppress this message
[Thu Sep 29 23:44:27.069217 2022] [mpm_prefork:notice] [pid 9] AH00163: Apache/2.4.54 (Debian) PHP/7.4.30 configured -- resuming normal operations
[Thu Sep 29 23:44:27.069275 2022] [core:notice] [pid 9] AH00094: Command line: 'apache2 -D FOREGROUND'

In docker logs <mariadb>:

2022-09-29 23:44:21+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.2.41+maria~bionic started.
2022-09-29 23:44:22+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-09-29 23:44:22+00:00 [Note] [Entrypoint]: Entrypoint script for MariaDB Server 1:10.2.41+maria~bionic started.
2022-09-29 23:44:22 140603371800256 [Note] mysqld (mysqld 10.2.41-MariaDB-1:10.2.41+maria~bionic) starting as process 1 ...
2022-09-29 23:44:22 140603371800256 [Warning] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Uses event mutexes
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Compressed tables use zlib 1.2.11
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Using Linux native AIO
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Number of pools: 1
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Using SSE2 crc32 instructions
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Initializing buffer pool, total size = 256M, instances = 1, chunk size = 128M
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Completed initialization of buffer pool
2022-09-29 23:44:22 140602643797760 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2022-09-29 23:44:22 140603371800256 [Note] InnoDB: Highest supported file format is Barracuda.
2022-09-29 23:44:23 140603371800256 [Note] InnoDB: 128 out of 128 rollback segments are active.
2022-09-29 23:44:23 140603371800256 [Note] InnoDB: Creating shared tablespace for temporary tables
2022-09-29 23:44:23 140603371800256 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2022-09-29 23:44:23 140603371800256 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2022-09-29 23:44:23 140603371800256 [Note] InnoDB: 5.7.36 started; log sequence number 27875465
2022-09-29 23:44:23 140602482071296 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2022-09-29 23:44:23 140603371800256 [Note] Plugin 'FEEDBACK' is disabled.
2022-09-29 23:44:23 140603371800256 [Note] Server socket created on IP: '::'.
2022-09-29 23:44:23 140603371800256 [Warning] 'proxies_priv' entry '@% root@4b93ba700d61' ignored in --skip-name-resolve mode.
2022-09-29 23:44:23 140603371800256 [Note] Reading of all Master_info entries succeeded
2022-09-29 23:44:23 140603371800256 [Note] Added new Master_info '' to hash table
2022-09-29 23:44:23 140603371800256 [Note] mysqld: ready for connections.
Version: '10.2.41-MariaDB-1:10.2.41+maria~bionic'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
2022-09-29 23:44:23 140602482071296 [Note] InnoDB: Buffer pool(s) load completed at 220929 23:44:23
2022-09-29 23:50:33 140603073754880 [Warning] Access denied for user 'example username'@'192.168.240.3' (using password: YES)
2022-09-30 18:18:50 140603073754880 [Warning] Access denied for user 'example username'@'192.168.240.3' (using password: YES)
2022-09-30 18:18:56 140603073754880 [Warning] Access denied for user 'example username'@'192.168.240.3' (using password: YES)

Have tried various configurations of the following, to no avail:

version: "3.1"

services:
  wordpress_phpunit:
    build:
      context: .
      dockerfile: Dockerfile-phpunit
    volumes:
      - "./my-plugin:/app"
      - "testsuite:/tmp"
    depends_on:
      - mysql_phpunit
    environment:
      WORDPRESS_DB_HOST: mysql_phpunit:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WP_PLUGIN_FOLDER: app
      PHPUNIT_DB_HOST: "mysql_phpunit"
    restart: always
  mysql_phpunit:
    image: mariadb:10.2
    restart: always
    environment:
        MYSQL_ROOT_PASSWORD: rootpass
        MYSQL_DATABASE: wordpress
        MYSQL_USER: wordpress
        MYSQL_PASSWORD: wordpress
volumes:
  testsuite: {}

The Dockerfile:

#1. Docker base image
FROM wordpress:php7.4
#2. Install WP-cli and dependencies to run it
RUN apt-get update 
    && apt-get install -y 
      less 
      vim 
      subversion 
      sudo 
      default-mysql-client-core 
    && curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o /usr/local/bin/wp 
    && chmod +x /usr/local/bin/wp

#3. Create the files for the testing environment
RUN 
    #3.1 Install phpunit
    curl -L https://phar.phpunit.de/phpunit-7.phar -o /tmp/phpunit 
    && chmod a+x /tmp/phpunit 
    #3.2 Install wordpress
    && cp -r /usr/src/wordpress /tmp/wordpress 
    && curl https://raw.github.com/markoheijnen/wp-mysqli/master/db.php -o /tmp/wordpress/wp-content/db.php 
    #3.3 Install the testing libraries
    && svn co --quiet https://develop.svn.wordpress.org/tags/5.3.2/tests/phpunit/includes/ /tmp/wordpress-tests-lib/includes 
    && svn co --quiet https://develop.svn.wordpress.org/tags/5.3.2/tests/phpunit/data/ /tmp/wordpress-tests-lib/data 
    #3.4 set owner and permissions
    && chown -R www-data:www-data /tmp/wordpress 
    && chown -R www-data:www-data /tmp/wordpress-tests-lib

#4. Copy the script to create the testing environment when the container is started
COPY init-testing-environment.sh /usr/local/bin/

#5. Run the script and send as an argument the command to run the apache service
ENTRYPOINT ["init-testing-environment.sh"]
CMD ["apache2-foreground"]

Will include the file for initiating the tests, below, but I think that the database connection needs to work before that file can run successfully.

Succeeding in docker-compose up -d and then connecting to the container:

docker-compose -f docker-compose.phpunit.yml exec wordpress_phpunit bash

Then this command returns the mysql error:

sudo -u www-data wp core is-installed

The wp-config.php file contains:

define( 'DB_NAME', getenv_docker('WORDPRESS_DB_NAME', 'wordpress') );
define( 'DB_USER', getenv_docker('WORDPRESS_DB_USER', 'example username') );
define( 'DB_PASSWORD', getenv_docker('WORDPRESS_DB_PASSWORD', 'example password') );
define( 'DB_HOST', getenv_docker('WORDPRESS_DB_HOST', 'mysql') )

Not sure what a good next step in debugging is.

Here’s the shell script for setting up the tests.

#!/bin/bash

cd /var/www/html/

#1. check if wordpress is already installed/configured
if (sudo -u www-data -- wp core is-installed)
then

    #2. check if the database is ready
    if ! (sudo -u www-data -- wp db check)
    then
        # wait a moment for the database container
        sleep 1
        exit 1;
    fi

    #3. init the testing instance
    sudo -u www-data -- wp scaffold plugin-tests $WP_PLUGIN_FOLDER --force
    cd wp-content/plugins/$WP_PLUGIN_FOLDER && sudo -u www-data -- bash -c "./bin/install-wp-tests.sh $WORDPRESS_DB_NAME $WORDPRESS_DB_USER $WORDPRESS_DB_PASSWORD $WORDPRESS_DB_HOST latest true"

fi

#4. back to the root WP folder
cd /var/www/html/

#5. execute the entrypoint of the parent image
bash docker-entrypoint.sh "$@"

2

Answers


  1. Chosen as BEST ANSWER

    First of all, just learned that wp_env provides a dockerized phpunit.

    Of course I learned that after hours of becoming less ignorant about Docker, wp scaffold and PHPUnit.

    What ended up working is this:

    1. Nearly identical copy of the docker-compose.yml from the Docker-Wordpress Docs, with the main wordpress image pulled in via a Dockerfile:
      wp_phpunit:
        build:
          context: .
          dockerfile: Dockerfile-phpunit
    

    The Dockerfile:

    #1. Docker base image
    FROM wordpress:php7.4
    #2. Install WP-cli and dependencies to run it
    RUN apt-get update 
        && apt-get install -y 
          less 
          vim 
          subversion 
          sudo 
          default-mysql-client-core 
        && curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -o /usr/local/bin/wp 
        && chmod +x /usr/local/bin/wp
    
    #3. Create the files for the testing environment
    RUN 
        #3.1 Install phpunit
        curl -L https://phar.phpunit.de/phpunit-7.phar -o /usr/local/bin/phpunit 
        && chmod a+x /usr/local/bin/phpunit 
        #3.2 Install wordpress
        && cp -r /usr/src/wordpress /tmp/wordpress 
        && curl https://raw.github.com/markoheijnen/wp-mysqli/master/db.php -o /tmp/wordpress/wp-content/db.php 
        #3.3 Install the testing libraries
        && svn co --quiet https://develop.svn.wordpress.org/tags/5.3.2/tests/phpunit/includes/ /tmp/wordpress-tests-lib/includes 
        && svn co --quiet https://develop.svn.wordpress.org/tags/5.3.2/tests/phpunit/data/ /tmp/wordpress-tests-lib/data 
        #3.4 set owner and permissions
        && chown -R www-data:www-data /tmp/wordpress 
        && chown -R www-data:www-data /tmp/wordpress-tests-lib
    
    #4. Copy the script to create the testing environment when the container is started
    COPY init-testing-environment.sh /usr/local/bin/
    
    #5. Run the script and send as an argument the command to run the apache service
    ENTRYPOINT ["init-testing-environment.sh"]
    CMD ["apache2-foreground"]
    

    With an entrypoint installing the wp-test-suite:

    #!/bin/bash
    
    # Not sure if this is necessary
    cd /var/www/html/
    
    ./bin/install-wp-tests.sh $WORDPRESS_DB_NAME $WORDPRESS_DB_USER $WORDPRESS_DB_PASSWORD $WORDPRESS_DB_HOST latest true
    
    #Execute the entrypoint of the parent image
    bash docker-entrypoint.sh "$@"
    

    In this case, since there are two related plugins I'm developing, some of the PHPUnit files are at top level, so mapping is like this in the docker-compose file:

        volumes:
          - "./plugin_one:/var/www/html/wp-content/plugins/plugin_one"
          - "./plugin_two:/var/www/html/wp-content/plugins/plugin_two"
          - "./phpunit.xml.dist:/var/www/html/phpunit.xml.dist"
          - "./bootstrap.php:/var/www/html/bootstrap.php"
          - "./bin:/var/www/html/bin"
    

    The bootstrap file:

    <?php
    /**
     * PHPUnit bootstrap file.
     *
     * @package My_Plugin
     */
    
    $_tests_dir = getenv( 'WP_TESTS_DIR' );
    
    if ( ! $_tests_dir ) {
        $_tests_dir = rtrim( sys_get_temp_dir(), '/\' ) . '/wordpress-tests-lib';
    }
    
    // Forward custom PHPUnit Polyfills configuration to PHPUnit bootstrap file.
    $_phpunit_polyfills_path = getenv( 'WP_TESTS_PHPUNIT_POLYFILLS_PATH' );
    if ( false !== $_phpunit_polyfills_path ) {
        define( 'WP_TESTS_PHPUNIT_POLYFILLS_PATH', $_phpunit_polyfills_path );
    }
    
    if ( ! file_exists( "{$_tests_dir}/includes/functions.php" ) ) {
        echo "Could not find {$_tests_dir}/includes/functions.php, have you run bin/install-wp-tests.sh ?" . PHP_EOL; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        exit( 1 );
    }
    
    // Give access to tests_add_filter() function.
    require_once "{$_tests_dir}/includes/functions.php";
    
    /**
     * Manually load the plugin being tested.
     */
    function _manually_load_plugins() {
        require dirname( __FILE__ ) . '/wp-content/plugins/plugin_one/plugin_one.php';
        //require dirname( __FILE__ ) . '/wp-content/plugins/plugin_two/plugin_two.php';
    }
    
    tests_add_filter( 'muplugins_loaded', '_manually_load_plugins' );
    
    // Start up the WP testing environment.
    require_once "{$_tests_dir}/includes/bootstrap.php";
    

    And phpunit.xml.dist:

    <phpunit
        bootstrap="bootstrap.php"
        backupGlobals="false"
        colors="true"
        convertErrorsToExceptions="true"
        convertNoticesToExceptions="true"
        convertWarningsToExceptions="true"
        >
        <testsuites>
            <testsuite name="Main">
                <directory prefix="test-" suffix=".php">wp-content/plugins/plugin_one</directory>
                <exclude>wp-content/plugins/plugin_one/tests/test-sample.php</exclude>
            </testsuite>
            <testsuite name="Access">
                <directory prefix="test-" suffix=".php">wp-content/plugins/plugin_two</directory>
                <exclude>wp-content/plugins/plugin_two/tests/test-sample.php</exclude>
            </testsuite>
        </testsuites>
    </phpunit>
    

    The install-wp-tests.sh file:

    #!/usr/bin/env bash
    
    if [ $# -lt 3 ]; then
        echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
        exit 1
    fi
    
    DB_NAME=$1
    DB_USER=$2
    DB_PASS=$3
    DB_HOST=${4-localhost}
    WP_VERSION=${5-latest}
    SKIP_DB_CREATE=${6-false}
    
    WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
    WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
    
    download() {
        if [ `which curl` ]; then
            curl -s "$1" > "$2";
        elif [ `which wget` ]; then
            wget -nv -O "$2" "$1"
        fi
    }
    
    if [[ $WP_VERSION =~ [0-9]+.[0-9]+(.[0-9]+)? ]]; then
        WP_TESTS_TAG="tags/$WP_VERSION"
    elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
        WP_TESTS_TAG="trunk"
    else
        # http serves a single offer, whereas https serves multiple. we only want one
        download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
        grep '[0-9]+.[0-9]+(.[0-9]+)?' /tmp/wp-latest.json
        LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
        if [[ -z "$LATEST_VERSION" ]]; then
            echo "Latest WordPress version could not be found"
            exit 1
        fi
        WP_TESTS_TAG="tags/$LATEST_VERSION"
    fi
    
    set -ex
    
    install_wp() {
    
        if [ -d $WP_CORE_DIR ]; then
            return;
        fi
    
        mkdir -p $WP_CORE_DIR
    
        if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
            mkdir -p /tmp/wordpress-nightly
            download https://wordpress.org/nightly-builds/wordpress-latest.zip  /tmp/wordpress-nightly/wordpress-nightly.zip
            unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
            mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
        else
            if [ $WP_VERSION == 'latest' ]; then
                local ARCHIVE_NAME='latest'
            else
                local ARCHIVE_NAME="wordpress-$WP_VERSION"
            fi
            download https://wordpress.org/${ARCHIVE_NAME}.tar.gz  /tmp/wordpress.tar.gz
            tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
        fi
    
        download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
    }
    
    install_test_suite() {
        # portable in-place argument for both GNU sed and Mac OSX sed
        if [[ $(uname -s) == 'Darwin' ]]; then
            local ioption='-i .bak'
        else
            local ioption='-i'
        fi
    
        # set up testing suite if it doesn't yet exist
        if [ ! -d $WP_TESTS_DIR ]; then
            # set up testing suite
            mkdir -p $WP_TESTS_DIR
            svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
            svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
        fi
    
        if [ ! -f wp-tests-config.php ]; then
            download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
            # remove all forward slashes in the end
            WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/+$::")
            sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
            sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
            sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
            sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
            sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
        fi
    
    }
    
    install_db() {
    
        if [ ${SKIP_DB_CREATE} = "true" ]; then
            return 0
        fi
    
        # parse DB_HOST for port or socket references
        local PARTS=(${DB_HOST//:/ })
        local DB_HOSTNAME=${PARTS[0]};
        local DB_SOCK_OR_PORT=${PARTS[1]};
        local EXTRA=""
    
        if ! [ -z $DB_HOSTNAME ] ; then
            if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]{1,}$') ]; then
                EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
            elif ! [ -z $DB_SOCK_OR_PORT ] ; then
                EXTRA=" --socket=$DB_SOCK_OR_PORT"
            elif ! [ -z $DB_HOSTNAME ] ; then
                EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
            fi
        fi
    
        # create database
        mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
    }
    
    install_wp
    install_test_suite
    install_db
    

    Lastly, this little helper script was useful in the container development process:

    #!/bin/bash
    docker-compose -f docker-compose.phpunit.yml down --remove-orphans
    docker image prune -af # Clear out ALL docker images.
    docker-compose -f docker-compose.phpunit.yml up -d
    

  2. You could try after add below code in custom shell file.

    wpEnvs=( "${!WORDPRESS_@}" )
    if [ ! -s wp-config.php ] && [ "${#wpEnvs[@]}" -gt 0 ]; then
        for wpConfigDocker in 
            wp-config-docker.php 
            /usr/src/wordpress/wp-config-docker.php 
        ; do
            if [ -s "$wpConfigDocker" ]; then
                echo >&2 "No 'wp-config.php' found in $PWD, but 'WORDPRESS_...' variables supplied; copying '$wpConfigDocker' (${wpEnvs[*]})"
                # using "awk" to replace all instances of "put your unique phrase here" with a properly unique string (for AUTH_KEY and friends to have safe defaults if they aren't specified with environment variables)
                awk '
                    /put your unique phrase here/ {
                        cmd = "head -c1m /dev/urandom | sha1sum | cut -d\  -f1"
                        cmd | getline str
                        close(cmd)
                        gsub("put your unique phrase here", str)
                    }
                    { print }
                ' "$wpConfigDocker" > wp-config.php
                if [ "$uid" = '0' ]; then
                    # attempt to ensure that wp-config.php is owned by the run user
                    # could be on a filesystem that doesn't allow chown (like some NFS setups)
                    chown "$user:$group" wp-config.php || true
                fi
                break
            fi
        done
    fi
    

    or

    This link full-stack-nginx-wordpress-for-everyone-with-docker-compose is ready to install full stack docker compose wordpress. I suggest you try, tried and it is work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search