How to install WordPress with Docker on OS Sierra

With individual Docker commands

  1. Install Docker for Mac
  2. $ docker run –name mysql-latest -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
  3. $ docker run –name wordpress -p 8000:80 –link mysql-latest:mysql -d wordpress:4.7.3-php7.1-apache
  4. Visit http://0.0.0.0:8000 and configure WordPress

With a Docker compose file

  1. Install Docker for Mac
  2. Save the following text to a ´~/dev /wordpress /website /docker-compose.yml´ file:
    version: '2'
    
    services:
      dbms:
        image: mysql:5.7
        volumes:
          - db_data:/var/lib/mysql
        ports:
          - 32768:3306
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: wordpress
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wordpress
          MYSQL_PASSWORD: wordpress
    
      wordpress:
        depends_on:
          - dbms
        build: ./docker/wordpress
        image: wordpress:xdebug
        volumes:
          - .:/var/www/html
        ports:
          - 8000:80
        restart: always
        environment:
          WORDPRESS_DB_HOST: dbms:3306
          WORDPRESS_DB_PASSWORD: wordpress
          XDEBUG_CONFIG: remote_host=192.168.1.33
    
    volumes:
        db_data:
  3. Save the following text to a ´~/dev /wordpress /website /docker /wordpress /Dockerfile´ file
    FROM wordpress:4.7.3-php7.1-apache
    
    RUN yes | pecl install xdebug 
        && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini 
        && echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini 
        && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini
  4. Run everything: ´$ docker-compose up´
  5. Visit http://0.0.0.0:8000 and configure WordPress

Connect to the running dbms server from SequelPro

  1. Select the Standard tab
  2. Configure:
    Name: Docker for WordPress
    Host: 0.0.0.0
    Port: 32768
    Username: wordpress
    Password: wordpress
  3. Connect

Connect to a running server from a terminal

Example relative to connecting to the running dbms server.

  1. Find out the name of the server:
    $ docker-compose ps
           Name                      Command               State            Ports
    --------------------------------------------------------------------------------------
    website_dbms_1        docker-entrypoint.sh mysqld      Up      0.0.0.0:32768->3306/tcp
    website_wordpress_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:8000->80/tcp
  2. Connect to the ´website_dbms_1´ server:
    $ docker exec -it website_dbms_1 bash
    root@7d36d19c7df4:/#
  3. Then, for example, find out the server IP:
    root@7d36d19c7df4:/# hostname -I
    172.18.0.2

How canActivate works for multiple guards

Angular 2 lets developers forbid routes activation by means of a list of guards assigned to the canActivate property of a route definition.

{ 
  path: 'vip-lounge', 
  component: 'VipLoungeComponent', 
  canActivate: [ IfUserIsLoggedIn, 
    AndSpendsEnough,
    AndMembershipIsCurrent ]
}

Those guards are classes which implement the CanActivate interface, and the implementation can be a promise, for example when it entails a roundtrip to the server.

The way Angular 2 treats this list of guards is by applying .every(...) to the values of a merge-mapped list of observables.

  checkGuards(): Observable<boolean> {
    if (this.checks.length === 0) return of (true);
    const checks$ = from(this.checks);
    const runningChecks$ = mergeMap.call(checks$, (s: any) => {
      if (s instanceof CanActivate) {
        return andObservables(
            from([this.runCanActivateChild(s.path), this.runCanActivate(s.route)]));
      } else if (s instanceof CanDeactivate) {
        // workaround https://github.com/Microsoft/TypeScript/issues/7271
        const s2 = s as CanDeactivate;
        return this.runCanDeactivate(s2.component, s2.route);
      } else {
        throw new Error('Cannot be reached');
      }
    });
    return every.call(runningChecks$, (result: any) => result === true);
  }

The list of guards is conceptually the same as a list of promises, and in fact all the guards could be promises because, as we see above, .from(...) is used to initialise check$.

Merge-mapping is exactly what we did in How to convert promises to an observable.

var source = Rx.Observable.from(promises.map(function (promise) { 
  return Rx.Observable.from(promise); 
})).mergeAll(); 
/* 
 
true 
"Next: true" 
true 
"Next: true" 
true 
"Next: true" 
false 
"Next: false" 
true 
"Next: true" 
"Completed" 
 
*/

var source = Rx.Observable.from(promises).mergeMap(function (promise) {
  return Rx.Observable.from(promise);
});
/* 
 
true 
"Next: true" 
true 
"Next: true" 
true 
"Next: true" 
false 
"Next: false" 
true 
"Next: true" 
"Completed" 
 
*/

If we now apply .every(...) to that merge-mapped list of promises, we can see how canActivate works for multiple guards.

var source = Rx.Observable
  .from(promises)
  .mergeMap(promise => Rx.Observable.from(promise))
  .every(value => value === true);
/*

true
true
true
false
"Next: false"
"Completed"
true

*/

Notice that the subscription is notified only once, as soon as the resolved promises make it clear what the result would be: the observable emits a false soon after getting the first false, or a true after getting all true-s. So, as expected, canActivate works as a short-circuit-ed AND of each guard of the list, according to the arrival order of values.

Also notice that the values of all the promises keep arriving as promises get resolved, even after the observable has completed. This means that guards intended to be used together in a list of guards should never have side effects (to avoid race conditions). If guard G1 had a side effect of activating route R1, and G2 had another for R2, then canActivate: [G1, G2] would unpredictably activate R1 or R2, depending on which guard completes later.

How to convert promises to an observable

A promise is a future value. An observable is a flow of past and future values. So it makes sense to convert a list of promises into an observable. Then we can do nice things on it, like .every(...), which will result in a single boolean observable according to whether all the promises satisfy a given condition or not.

Understanding observables requires some time, plus the latest RxJs library, plus an interactive dev tool like JS Bin.

I’m now going to share what I just learned. But first, let me introduce some snippets I’ll be using later on.

Creating promises that resolve.

function resolvePromise(value, delay) {
  return new Promise(function(resolve, reject) {
    setTimeout(function(){
      console.log(value);
      resolve(value);
    }, delay);
  });
}

resolvePromise(true, 500).then(
  function(val){console.log('resolved: ' + val);}
, function(err){console.log('rejected: ' + err);}
);
/*

[object Promise] { ... }
true
"resolved: true"

*/

Subscribing to a source.

source.subscribe(
    function (x) {
        console.log('Next: ' + x);
    },
    function (err) {
        console.log('Error: ' + err);   
    },
    function () {
        console.log('Completed');   
    }
);

Getting to the right observable

Starting with no promises at all

Let’s see how the source and subscription work for the simplest case, when no promises at all are involved.

var booleans = [true, false, true, true, true];
var source = Rx.Observable.of.apply(null, booleans);
/*

"Next: true"
"Next: false"
"Next: true"
"Next: true"
"Next: true"
"Completed"

*/

Notice that above and in the next snippets I’m going to show the console output corresponding to the subscription defined earlier and using the last source.

Passing from values to promises of values

With a simple .map(...) we can convert our booleans to promises.

var promises = booleans.map(function (x, i) {
  return resolvePromise(x, 1000*(5-i));
});
/*

true
true
true
false
true

*/

Notice that we are now getting reversed logs because, to get a better sense of promises, we are creating them so that they will resolve in reversed order.

Passing from promises to observable: 1/3

Unfortunately the .from(...) applied to a list of promises doesn’t really do much:

var source = Rx.Observable.from(promises);
/*

"Next: [object Promise]"
"Next: [object Promise]"
"Next: [object Promise]"
"Next: [object Promise]"
"Next: [object Promise]"
"Completed"
true
true
true
false
true

*/

Notice that the subscription is notified all at once with the pending promises, without waiting for them to (slowly) resolve.

Passing from promises to observable: 2/3

We could transform each to an observable, applying.from(...) to each.

var source = Rx.Observable.from(promises.map(function (promise) {
  return Rx.Observable.from(promise);
}));
/*

"Next: [object Object]"
"Next: [object Object]"
"Next: [object Object]"
"Next: [object Object]"
"Next: [object Object]"
"Completed"
true
true
true
false
true

*/

Notice that the only difference is that now the subscription is notified with the pending observables, still without waiting.

Passing from promises to observable: 3/3

Wait a moment… that is an observable of observables… a higher-order observable then (by definition)!

Yes, and there are many ways to bring a higher order back to the first one.

combineAll

Converts a higher-order Observable into a first-order Observable by waiting for the outer Observable to complete, then applying combineLatest.

var source = Rx.Observable.from(promises.map(function (promise) {
  return Rx.Observable.from(promise);
})).combineAll();
/*

true
true
true
false
true
"Next: true,false,true,true,true"
"Completed"

*/

Notice how the subscription is notified only once, after all the promises have resolved, with a combination that respects the order of the booleans.

concatAll

Converts a higher-order Observable into a first-order Observable by concatenating the inner Observables in order.

var source = Rx.Observable.from(promises.map(function (promise) {
  return Rx.Observable.from(promise);
})).concatAll();
/*

true
true
true
false
true
"Next: true"
"Next: false"
"Next: true"
"Next: true"
"Next: true"
"Completed"

*/

Notice how the subscription is notified once per resolved promise, but only after all the promises have resolved. Also notice that the notification order respects the order of the booleans.

exhaust

Converts a higher-order Observable into a first-order Observable by dropping inner Observables while the previous inner Observable has not yet completed.

var source = Rx.Observable.from(promises.map(function (promise) {
  return Rx.Observable.from(promise);
})).exhaust();
/*

true
true
true
false
true
"Next: true"
"Completed"

*/

Notice how the subscription is notified only once, with the resolved value of the first promise (i.e. the first boolean here, not the first promise to resolve, which would be the last boolean). That’s because the first boolean is associated to the longer running promise, which exhausts the processing capacity of the resulting observable until it gets resolved (and completed). Also notice that the fact that the notification happens only after all the promises have resolved, is coincidental (because we made it happen by forcing each promise to complete sooner than the previous one).

mergeAll

mergeAll(concurrent: number): Observable

Converts a higher-order Observable into a first-order Observable which concurrently delivers all values that are emitted on the inner Observables.

var source = Rx.Observable.from(promises.map(function (promise) {
  return Rx.Observable.from(promise);
})).mergeAll();
/*

true
"Next: true"
true
"Next: true"
true
"Next: true"
false
"Next: false"
true
"Next: true"
"Completed"

*/

Notice how the subscription is notified once per resolved promise, as soon as each promise is resolved.

switch

Converts a higher-order Observable into a first-order Observable by subscribing to only the most recently emitted of those inner Observables.

var source = Rx.Observable.from(promises.map(function (promise) {
  return Rx.Observable.from(promise);
})).switch();
/*

true
"Next: true"
"Completed"
true
true
false
true

*/

Notice how the subscription is notified only once, as soon as the first promise is resolved.

References