Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Docker for WordPress developers - WordCamp Antw...

Docker for WordPress developers - WordCamp Antwerp 2018

Thijs Feryn

March 03, 2018
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. A container image is a lightweight, stand-alone, executable package of

    a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings. Available for both Linux and Windows based apps, containerized software will always run the same, regardless of the environment. Containers isolate software from its surroundings, for example differences between development and staging environments and help reduce conflicts between teams running different software on the same infrastructure.
  2. Build image Push image to registry Pull image from registry

    Run image Registry Docker build Docker push Docker pull Docker run Dockerfile
  3. FROM debian:stretch WORKDIR /var/www/html RUN apt-get update \ && apt-get

    install -y apache2 php7.0 libapache2-mod-php7.0 CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] EXPOSE 80
  4. Fatal error: Uncaught Error: Call to undefined function mysql_connect() in

    /var/www/html/wp- includes/wp-db.php:1564 Stack trace: #0 /var/www/ html/wp-includes/wp-db.php(592): wpdb->db_connect() #1 /var/www/html/wp-includes/load.php(404): wpdb- >__construct('wordpress', 'wordpress', 'wordpress', 'db:3306') #2 /var/www/html/wp-settings.php(106): require_wp_db() #3 /var/www/html/wp-config.php(101): require_once('/var/www/html/w...') #4 /var/www/html/ wp-load.php(37): require_once('/var/www/html/w...') #5 /var/www/html/wp-blog-header.php(13): require_once('/var/www/html/w...') #6 /var/www/html/ index.php(17): require('/var/www/html/w...') #7 {main} thrown in /var/www/html/wp-includes/wp- db.php on line 1564
  5. $ docker run -e MYSQL_ROOT_PASSWORD=somewordpress -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e

    MYSQL_PASSWORD=wordpress --name some-mysql -p 3306:3306 -d -v "$PWD/../db/data:/var/lib/mysql" -v "$PWD/../db/sql:/docker- entrypoint-initdb.d" mysql:5.7
  6. version: '3.3' services: db: image: mysql:5.7 volumes: - ../db/data:/var/lib/mysql -

    ../db/sql:/docker-entrypoint-initdb.d environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest volumes: - ../code:/var/www/html ports: - "80:80" docker-compose.yml
  7. Attaching to docker_wordpress_1, docker_db_1 wordpress_1 | AH00558: apache2: Could not

    reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message wordpress_1 | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message wordpress_1 | [Mon Feb 26 16:14:54.498385 2018] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Debian) PHP/7.2.2 configured -- resuming normal operations wordpress_1 | [Mon Feb 26 16:14:54.498549 2018] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND' db_1 | 2018-02-26T16:14:54.133816Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use -- explicit_defaults_for_timestamp server option (see documentation for more details). db_1 | 2018-02-26T16:14:54.146003Z 0 [Note] mysqld (mysqld 5.7.21) starting as process 1 ... db_1 | 2018-02-26T16:14:54.152600Z 0 [Warning] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive db_1 | 2018-02-26T16:14:54.154772Z 0 [Note] InnoDB: PUNCH HOLE support available db_1 | 2018-02-26T16:14:54.154830Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins db_1 | 2018-02-26T16:14:54.154839Z 0 [Note] InnoDB: Uses event mutexes db_1 | 2018-02-26T16:14:54.154848Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier db_1 | 2018-02-26T16:14:54.154856Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3 db_1 | 2018-02-26T16:14:54.154863Z 0 [Note] InnoDB: Using Linux native AIO db_1 | 2018-02-26T16:14:54.155374Z 0 [Note] InnoDB: Number of pools: 1 db_1 | 2018-02-26T16:14:54.155508Z 0 [Note] InnoDB: Using CPU crc32 instructions db_1 | 2018-02-26T16:14:54.157423Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M db_1 | 2018-02-26T16:14:54.164871Z 0 [Note] InnoDB: Completed initialization of buffer pool db_1 | 2018-02-26T16:14:54.167964Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority(). db_1 | 2018-02-26T16:14:54.201936Z 0 [Note] InnoDB: Highest supported file format is Barracuda. db_1 | 2018-02-26T16:14:54.389809Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables db_1 | 2018-02-26T16:14:54.391076Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
  8. $ docker-compose top docker_db_1 PID USER TIME COMMAND ---------------------------- 8190

    999 0:00 mysqld docker_wordpress_1 PID USER TIME COMMAND ----------------------------------------- 8410 0 0:00 apache2 -DFOREGROUND 8570 33 0:00 apache2 -DFOREGROUND 8571 33 0:00 apache2 -DFOREGROUND 8572 33 0:00 apache2 -DFOREGROUND 8573 33 0:00 apache2 -DFOREGROUND 8574 33 0:00 apache2 -DFOREGROUND
  9. version: '3.3' services: db: image: mysql:5.7 volumes: - ../db/data:/var/lib/mysql -

    ../db/sql:/docker-entrypoint-initdb.d environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest volumes: - ../code:/var/www/html ports: - "80:80" cli: depends_on: - wordpress image: wordpress:cli volumes: - ../code:/var/www/html entrypoint: wp redis: image: redis:4
  10. MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on:

    - db image: wordpress:latest volumes: - ../code:/var/www/html ports: - "80:80" cli: depends_on: - wordpress image: wordpress:cli volumes: - ../code:/var/www/html entrypoint: wp redis: image: redis:4
  11. $ docker-compose run --rm cli plugin list +------------------+----------+--------+---------+ | name

    | status | update | version | +------------------+----------+--------+---------+ | akismet | inactive | none | 4.0.3 | | hello | inactive | none | 1.6 | | redis-cache | inactive | none | 1.3.5 | | wordpress-seo | inactive | none | 6.3.1 | | object-cache.php | dropin | none | | +------------------+----------+--------+---------+
  12. test "`curl -s localhost | pup 'title text{}'`" = "Docker

    – Just another WordPress sites" Parse DOM elements Call Docker container String assertion
  13. image: wordpress:latest stages: - test services: - name: mysql:5.7 alias:

    db variables: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress test:integration: before_script: - apt-get update - apt-get install -y git golang-go mysql-client - GOPATH="$HOME/go" go get github.com/ericchiang/pup - cat sql/wordpress.sql | mysql --user="$MYSQL_USER" --password="$MYSQL_PASSWORD" --host=db "$MYSQL_DATABASE" - cp -R wp-* index.php .htaccess /var/www/html - apachectl start stage: test script: - test "`curl -s http://localhost | $HOME/go/bin/pup 'title text{}'`" = "Docker – Just another WordPress site" allow_failure: false .gitlab-ci.yml Uses Docker for job runners
  14. FROM debian:stretch WORKDIR /var/www/html RUN apt-get update \ && apt-get

    install -y apache2 php7.0 libapache2-mod-php7.0 php7.0-mysql \ && rm index.html \ CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] EXPOSE 80
  15. $ docker run --name=my-wordpress -p 80:80 -d -v "$PWD:/var/www/ html"

    git.domain.com:4567/thijsferyn/wordpress-docker
  16. $ docker stack deploy -c docker-compose.yml wordpress Stack wordpress was

    created Waiting for the stack to be stable and running... - Service redis has one container running - Service db has one container running - Service wordpress has one container running Stack wordpress is stable and running
  17. $ docker service ls ID NAME REPLICAS IMAGE PORTS jvyxfqthji4v

    wordpress_db 1/1 mysql:5.7 8fuv862hdqea wordpress_redis 1/1 redis:4 es3x49n9hvx2 wordpress_wordpress 1/1 wordpress:latest *:80->80/tcp
  18. $ docker stack deploy -c docker-compose.yml wordpress Stack wordpress was

    created Waiting for the stack to be stable and running... - Service redis has one container running - Service db has one container running - Service wordpress has one container running Stack wordpress is stable and running
  19. MySQL pod MySQL container MySQL service Wordpress pod Wordpress container

    Wordpress service Wordpress PVC MySQL PVC MySQL Volume Wordpress Volume Ingress Internet
  20. $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE

    db 1 1 1 1 36s redis 1 1 1 1 36s wordpress 1 1 1 1 36s
  21. $ kubectl get po NAME READY STATUS RESTARTS AGE db-69d9b64b67-x76b4

    1/1 Running 0 1m redis-854d68cff7-bwdsg 1/1 Running 0 1m wordpress-895dd96f9-kcdgq 1/1 Running 0 1m
  22. $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

    db ClusterIP None <none> 55555/TCP 1m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d redis ClusterIP None <none> 55555/TCP 1m wordpress ClusterIP None <none> 55555/TCP 1m wordpress-published LoadBalancer 10.98.180.147 localhost 80:31351/TCP 1m
  23. apiVersion: v1 kind: Service metadata: name: wordpress-mysql labels: app: wordpress

    spec: ports: - port: 3306 selector: app: wordpress tier: mysql clusterIP: None
  24. --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim labels: app:

    wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
  25. apiVersion: apps/v1 kind: Deployment metadata: name: wordpress-mysql labels: app: wordpress

    spec: selector: matchLabels: app: wordpress tier: mysql strategy: type: Recreate template: metadata: labels: app: wordpress tier: mysql spec: containers: - image: mysql:5.7 name: mysql env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef:
  26. spec: containers: - image: mysql:5.7 name: mysql env: - name:

    MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-root-pass key: password - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password - name: MYSQL_DATABASE value: wordpress - name: MYSQL_USER value: wordpress ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim
  27. --- apiVersion: v1 kind: Service metadata: name: wordpress labels: app:

    wordpress spec: ports: - port: 80 selector: app: wordpress tier: frontend type: LoadBalancer
  28. --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wp-pv-claim labels: app:

    wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
  29. --- apiVersion: apps/v1 kind: Deployment metadata: name: wordpress labels: app:

    wordpress spec: selector: matchLabels: app: wordpress tier: frontend strategy: type: Recreate template: metadata: labels: app: wordpress tier: frontend spec: containers: - image: wordpress:latest name: wordpress env: - name: WORDPRESS_DB_HOST value: wordpress-mysql
  30. spec: containers: - image: wordpress:latest name: wordpress env: - name:

    WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_USER value: wordpress - name: WORDPRESS_DB_NAME value: wordpress - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password ports: - containerPort: 80 name: wordpress volumeMounts: - name: wordpress-persistent-storage mountPath: /var/www/html volumes: - name: wordpress-persistent-storage persistentVolumeClaim: claimName: wp-pv-claim
  31. $ kubectl create secret generic mysql-pass --from-literal=password=wordpress $ kubectl create

    secret generic mysql-root-pass --from- literal=password=somewordpress
  32. $ kubectl apply -f wordpress.yml service "wordpress-mysql" created persistentvolumeclaim "mysql-pv-claim"

    created deployment "wordpress-mysql" created service "wordpress" created persistentvolumeclaim "wp-pv-claim" created deployment "wordpress" created
  33. $ kubectl get po NAME READY STATUS RESTARTS AGE wordpress-8d5dd96ff-7f9nx

    0/1 ContainerCreating 0 3s wordpress-mysql-7b4c776bc8-lwz5f 0/1 ContainerCreating 0 4s $ kubectl get po NAME READY STATUS RESTARTS AGE wordpress-8d5dd96ff-gpqx5 1/1 Running 0 48s wordpress-mysql-7b4c776bc8-dzr9w 1/1 Running 0 49s
  34. $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

    kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d wordpress LoadBalancer 10.111.50.221 <pending> 80:30876/TCP 26s wordpress-mysql ClusterIP None <none> 3306/TCP 26s
  35. $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE

    wordpress 1 1 1 0 1s wordpress-mysql 1 1 1 0 2s $ kubectl scale deployment wordpress --replicas=2 deployment "wordpress" scaled $ kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE wordpress 2 2 2 2 13m wordpress-mysql 1 1 1 1 13m
  36. $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

    kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d wordpress LoadBalancer 10.111.50.221 <pending> 80:30876/TCP 15m wordpress-mysql ClusterIP None <none> 3306/TCP 15m $ minikube service --url wordpress http://192.168.64.3:30876 $ minikube service wordpress