├── data
├── README.md
└── db
│ └── README.md
├── wp-root
├── README.md
├── .htaccess
└── wp-config.php
├── wp-content
├── plugins
│ └── README.md
└── themes
│ └── README.md
├── php
├── php.ini
└── upload.ini
├── Dockerfile
├── tests
├── features
│ ├── homepage.feature
│ └── bootstrap
│ │ └── FeatureContext.php
├── behat.params.yml
├── behat.params.yml.sample
├── behat.yml
└── behat.local.yml.sample
├── scripts
└── htaccess-no-bot.sh
├── .gitignore
├── .ebextensions
└── project.config
├── nginx
├── conf.d
│ └── default.conf
└── conf
│ └── nginx.conf
├── composer.json
├── docker-compose.yml
└── README.md
/data/README.md:
--------------------------------------------------------------------------------
1 | SQL Data Folder
2 |
--------------------------------------------------------------------------------
/data/db/README.md:
--------------------------------------------------------------------------------
1 | SQL Data Folder
2 |
--------------------------------------------------------------------------------
/wp-root/README.md:
--------------------------------------------------------------------------------
1 | this folder is for root WP config file
2 |
--------------------------------------------------------------------------------
/wp-content/plugins/README.md:
--------------------------------------------------------------------------------
1 | this folder is for custom plugins
2 |
--------------------------------------------------------------------------------
/wp-content/themes/README.md:
--------------------------------------------------------------------------------
1 | this folder is for custom themes
2 |
--------------------------------------------------------------------------------
/php/php.ini:
--------------------------------------------------------------------------------
1 | log_errors = On
2 | error_log = /dev/stderr
3 | error_reporting = E_ALL
4 |
--------------------------------------------------------------------------------
/php/upload.ini:
--------------------------------------------------------------------------------
1 | file_uploads = On
2 | memory_limit = 64M
3 | upload_max_filesize = 64M
4 | post_max_size = 64M
5 | max_execution_time = 600
6 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:7.0-fpm
2 | RUN docker-php-ext-install mysqli && docker-php-ext-install pdo_mysql
3 | RUN sed -ri 's/^www-data:x:33:33:/www-data:x:1000:50:/' /etc/passwd
4 |
--------------------------------------------------------------------------------
/tests/features/homepage.feature:
--------------------------------------------------------------------------------
1 | @home
2 | Feature: As a visitor I should be able to load the home page
3 |
4 | Scenario: Home page loads
5 | Given I am on the homepage
6 | Then I should see "Hello world!"
7 |
--------------------------------------------------------------------------------
/tests/behat.params.yml:
--------------------------------------------------------------------------------
1 | # Local configuration.
2 | default:
3 | context:
4 | parameters:
5 | wp_users:
6 | editor-qa:
7 | 'password'
8 | another-user:
9 | 'password'
10 |
11 |
--------------------------------------------------------------------------------
/tests/behat.params.yml.sample:
--------------------------------------------------------------------------------
1 | # Local configuration.
2 | default:
3 | context:
4 | parameters:
5 | wp_users:
6 | editor-qa:
7 | 'password for editor-qa'
8 | another-user:
9 | 'password for another-user'
10 |
--------------------------------------------------------------------------------
/wp-root/.htaccess:
--------------------------------------------------------------------------------
1 | # BEGIN WordPress
2 |
3 | RewriteEngine On
4 | RewriteBase /
5 | RewriteRule ^index\.php$ - [L]
6 | RewriteCond %{REQUEST_FILENAME} !-f
7 | RewriteCond %{REQUEST_FILENAME} !-d
8 | RewriteRule . /index.php [L]
9 |
10 | # END WordPress
11 |
--------------------------------------------------------------------------------
/scripts/htaccess-no-bot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ "$environemt" = "staging" ]
4 | then
5 | if grep -Fxq "# NO-BOT" wp/.htaccess
6 | then
7 | echo "No-Bot already set"
8 | else
9 |
10 | cat <> wp/.htaccess
11 |
12 | # NO-BOT
13 | RewriteEngine On
14 |
15 | RewriteCond %{HTTP_USER_AGENT} (googlebot|bingbot|Baiduspider) [NC]
16 | RewriteRule .* - [R=403,L]
17 | # NO-BOT
18 | EOF
19 |
20 | fi
21 | fi
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | nbproject
2 | ._*
3 | .~lock.*
4 | .buildpath
5 | .DS_Store
6 | .idea
7 | .project
8 | .settings
9 | vendor/
10 | public/vendor/
11 | .vagrant
12 | build.local.properties
13 | phinx.yml
14 | composer.phar
15 | wp-admin/
16 | wp-includes/
17 | wp/*
18 | !wp-config.php
19 | xmlrpc.php
20 | license.txt
21 | readme.html
22 | wp/
23 | data/*.sql
24 | updraft
25 | wp-content/plugins
26 | wp-content/themes
27 | *.local.*
28 |
--------------------------------------------------------------------------------
/tests/behat.yml:
--------------------------------------------------------------------------------
1 | # behat.yml
2 | default:
3 | extensions:
4 | Behat\MinkExtension\Extension:
5 | base_url: http://localhost/
6 | browser_name: chrome
7 | goutte:
8 | guzzle_parameters:
9 | verify: false
10 | ssl.certificate_authority: false
11 | selenium2:
12 | wd_host: 'http://selenium:4444/wd/hub'
13 |
14 | imports:
15 | - behat.params.yml
16 |
--------------------------------------------------------------------------------
/.ebextensions/project.config:
--------------------------------------------------------------------------------
1 | files:
2 | "/etc/php.d/wordpress.ini" :
3 | mode: "000644"
4 | owner: root
5 | group: root
6 | content: |
7 | upload_max_filesize = 128M
8 | post_max_size = 64M
9 |
10 | files:
11 | "/opt/elasticbeanstalk/hooks/appdeploy/pre/99_wp_setup.sh":
12 | mode: "000755"
13 | owner: root
14 | group: root
15 | content: |
16 | #!/usr/bin/env bash
17 | su - webapp -s /bin/bash -c "env ; id ; cd /var/app/ondeck ; ./vendor/bin/phing setup"
18 | container_commands:
19 | SetupWp:
20 | command: "/opt/elasticbeanstalk/hooks/appdeploy/pre/99_wp_setup.sh"
21 | ignoreErrors: false
22 | leader_only: true
23 |
--------------------------------------------------------------------------------
/tests/behat.local.yml.sample:
--------------------------------------------------------------------------------
1 | # behat.yml
2 | default:
3 | extensions:
4 | Behat\MinkExtension\Extension:
5 | base_url: http://192.168.99.100/
6 | browser_name: 'chrome'
7 | show_cmd: /Applications/Firefox.app/Contents/MacOS/firefox %s
8 | javascript_session: 'selenium2'
9 | goutte:
10 | guzzle_parameters:
11 | verify: false
12 | ssl.certificate_authority: false
13 |
14 | selenium2:
15 | wd_host: http://192.168.99.100:4444/wd/hub
16 | capabilities: {"browserName":"chrome", "platform":"LINUX", "browserVersion":"9", "version": "", "browser": "chrome"}
17 |
18 | imports:
19 | - behat.params.yml
20 |
--------------------------------------------------------------------------------
/nginx/conf.d/default.conf:
--------------------------------------------------------------------------------
1 | upstream php {
2 | server php:9000;
3 | }
4 |
5 | server {
6 |
7 | root /var/www/html/wp;
8 | index index.php;
9 |
10 | location = /favicon.ico {
11 | log_not_found off;
12 | access_log off;
13 | }
14 |
15 | location = /robots.txt {
16 | allow all;
17 | log_not_found off;
18 | access_log off;
19 | }
20 |
21 | location / {
22 |
23 | try_files $uri $uri/ /index.php?$args;
24 | }
25 |
26 | location ~ \.php$ {
27 |
28 | include fastcgi.conf;
29 | fastcgi_intercept_errors on;
30 | fastcgi_pass php;
31 | }
32 |
33 | location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
34 | expires max;
35 | log_not_found off;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/nginx/conf/nginx.conf:
--------------------------------------------------------------------------------
1 | worker_processes 1;
2 |
3 | daemon off;
4 |
5 | events {
6 | worker_connections 1024;
7 | }
8 |
9 | error_log /var/log/nginx/error.log warn;
10 | pid /var/run/nginx.pid;
11 |
12 | http {
13 | include /etc/nginx/conf/mime.types;
14 | default_type application/octet-stream;
15 |
16 | log_format main '$remote_addr - $remote_user [$time_local] "$request" '
17 | '$status $body_bytes_sent "$http_referer" '
18 | '"$http_user_agent" "$http_x_forwarded_for"';
19 |
20 | access_log /var/log/nginx/access.log main;
21 |
22 | sendfile on;
23 | #tcp_nopush on;
24 |
25 | keepalive_timeout 65;
26 |
27 | gzip on;
28 | gzip_disable "msie6";
29 |
30 | gzip_vary on;
31 | gzip_proxied any;
32 | gzip_comp_level 6;
33 | gzip_buffers 16 8k;
34 | gzip_http_version 1.1;
35 | gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
36 | # tells the server to use on-the-fly gzip compression.
37 | client_max_body_size 64M;
38 | include /etc/nginx/conf.d/*.conf;
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "continuousphp/wordpress-eb-demo",
3 | "description": "Wordpress Elastic Beanstalk Demo",
4 | "repositories": [
5 | {
6 | "type": "composer",
7 | "url": "https://wpackagist.org"
8 | }
9 | ],
10 | "require": {
11 | "php": ">=7.0",
12 | "johnpbloch/wordpress": ">=4.7.2",
13 | "composer/installers": "~1.0",
14 | "wpackagist-plugin/contact-form-7": "4.7",
15 | "wpackagist-plugin/business-profile": "1.1.4",
16 | "wpackagist-plugin/updraftplus": "1.13.1",
17 | "wpackagist-plugin/w3-total-cache": "0.9.5.4",
18 | "wpackagist-theme/vanilla": "1.3.5",
19 | "robmorgan/phinx": "~0.6.0",
20 | "wp-cli/wp-cli": "^1.0",
21 | "phing/phing": "~2.14"
22 | },
23 | "require-dev": {
24 | "guzzlehttp/guzzle": "~5.0",
25 | "robmorgan/phinx": "~0.6.0",
26 | "phing/phing": "~2.14",
27 | "behat/behat": "2.5.*@stable",
28 | "behat/mink": "1.4.*@stable",
29 | "behat/mink-extension": "*",
30 | "behat/mink-goutte-driver": "*",
31 | "behat/mink-selenium2-driver": "*"
32 | },
33 | "minimum-stability": "stable",
34 | "extra": {
35 | "wordpress-install-dir": "wp",
36 | "installer-paths": {
37 | "wp/wp-content/plugins/{$name}/": ["type:wordpress-plugin"],
38 | "wp/wp-content/themes/{$name}/": ["type:wordpress-theme"]
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 | services:
3 | nginx:
4 | image: evild/alpine-nginx:1.11.2-libressl
5 | container_name: wordpress_nginx
6 | restart: always
7 | volumes:
8 | - .:/var/www/html/:rw
9 | - ./nginx/conf/nginx.conf:/etc/nginx/conf/nginx.conf:ro
10 | - ./nginx/conf.d:/etc/nginx/conf.d:ro
11 | ports:
12 | - 80:80
13 | - 443:443
14 | networks:
15 | - front
16 | php:
17 | build: .
18 | container_name: php
19 | restart: always
20 | volumes:
21 | - .:/var/www/html:rw
22 | - ./php/upload.ini:/usr/local/etc/php/conf.d/uploads.ini
23 | - ./php/php.ini:/usr/local/etc/php/php.ini
24 | depends_on:
25 | - db
26 | links:
27 | - db
28 | environment:
29 | - MYSQL_ADDON_DB=wordpress
30 | - MYSQL_ADDON_HOST=db
31 | - MYSQL_ADDON_USER=root
32 | - MYSQL_ADDON_PASSWORD=password
33 | - AUTH_KEY=''
34 | - SECURE_AUTH_KEY=''
35 | - LOGGED_IN_KEY=''
36 | - NONCE_KEY=''
37 | - AUTH_SALT=''
38 | - SECURE_AUTH_SALT=''
39 | - LOGGED_IN_SALT=''
40 | - NONCE_SALT=''
41 | networks:
42 | - front
43 | - back
44 | db:
45 | image: mariadb:10
46 | container_name: wordpress_mariadb
47 | restart: always
48 | ports:
49 | - 3306:3306
50 | environment:
51 | - MYSQL_ROOT_PASSWORD=password
52 | networks:
53 | - back
54 | hub:
55 | image: selenium/hub
56 | container_name: wordpress_selenium-hub
57 | ports:
58 | - "4444:4444"
59 | networks:
60 | - back
61 | chrome:
62 | container_name: selenium-chrome
63 | image: selenium/node-chrome
64 | restart: always
65 | links:
66 | - hub
67 | environment:
68 | - HUB_PORT_4444_TCP_ADDR=hub
69 | networks:
70 | - back
71 | networks:
72 | front:
73 | back:
74 |
--------------------------------------------------------------------------------
/wp-root/wp-config.php:
--------------------------------------------------------------------------------
1 | wp_users = $parameters['wp_users'];
30 | }
31 |
32 | /**
33 | * Authenticates a user.
34 | *
35 | * @Given /^I am logged in as "([^"]*)" with the password "([^"]*)"$/
36 | */
37 | public function iAmLoggedInAsWithThePassword($username, $passwd) {
38 | // Go to the Login page.
39 | $this->getSession()->visit($this->locatePath('/wp-login.php'));
40 | // Log in
41 | $element = $this->getSession()->getPage();
42 | if (empty($element)) {
43 | throw new Exception('Page not found');
44 | }
45 | $element->fillField('Username', $username);
46 | $element->fillField('Password', $passwd);
47 | $submit = $element->findButton('Log In');
48 | if (empty($submit)) {
49 | throw new Exception('No submit button at ' . $this->getSession()
50 | ->getCurrentUrl());
51 | }
52 | $submit->click();
53 | $link = $this->getSession()->getPage()->findLink("Dashboard");
54 | if (empty($link)) {
55 | throw new Exception('Login failed at ' . $this->getSession()
56 | ->getCurrentUrl());
57 | }
58 | return;
59 | }
60 |
61 | /**
62 | * Authenticates a user with password from configuration.
63 | *
64 | * @Given /^I am logged in as "([^"]*)"$/
65 | */
66 | public function iAmLoggedInAs($username) {
67 | $password = $this->fetchPassword($username);
68 | $this->iAmLoggedInAsWithThePassword($username, $password);
69 | }
70 |
71 |
72 |
73 | /**
74 | * Helper function to fetch user passwords stored in behat.local.yml.
75 | *
76 | * @param string $type
77 | * The user type, e.g. drupal or git.
78 | *
79 | * @param string $name
80 | * The username to fetch the password for.
81 | *
82 | * @return string
83 | * The matching password or FALSE on error.
84 | */
85 | public function fetchPassword($name) {
86 | $property_name = 'wp_users';
87 | try {
88 | $property = $this->$property_name;
89 | $password = $property[$name];
90 | return $password;
91 | } catch (Exception $e) {
92 | throw new Exception("Non-existent user/password for $property_name:$name please check behat.local.yml.");
93 | }
94 | }
95 |
96 | /**
97 | * Pauses the scenario until the user presses a key. Useful when debugging a scenario.
98 | *
99 | * @Then /^(?:|I )break$/
100 | */
101 | public function iPutABreakpoint()
102 | {
103 | fwrite(STDOUT, "\033[s \033[93m[Breakpoint] Press \033[1;93m[RETURN]\033[0;93m to continue...\033[0m");
104 | while (fgets(STDIN, 1024) == '') {}
105 | fwrite(STDOUT, "\033[u");
106 | return;
107 | }
108 |
109 |
110 | /**
111 | * @Then /^I wait for the message to appear$/
112 | */
113 | public function iWaitForTheMessageToAppear()
114 | {
115 | $this->getSession()->wait(5000,
116 | "jQuery('#message').children().length > 0"
117 | );
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://continuousphp.com/git-hub/continuousdemo/wordpress-eb-demo)
2 |
3 | # WordPress Docker Development with Deployment on AWS Elastic Beanstalk
4 |
5 | - [Introduction](#introduction)
6 | - [Requirements](#requirements)
7 | - [Set-up your Development environment](#set-up-your-development-environment)
8 | - [Prepare your WordPress Repository](#prepare-your-wordpress-repository)
9 | - [Dependencies management with composer](#dependencies-management-with-composer)
10 | - [Phing environment variables](#phing-environment-variables)
11 | - [Configuring Wordpress](#configuring-wordpress)
12 | - [Starting docker-compose](#starting-docker-compose)
13 | - [Initializing the Database](#initializing-the-database)
14 | - [WordPress Base Install](#wordpress-base-install)
15 | - [Configuring your development environment](#configuring-your-development-environment)
16 | - [Plugin Installation](#plugin-installation)
17 | - [Running the behat tests](#running-behat-tests)
18 | - [Themes Installation](#themes-installation)
19 | - [Developing a dumy plugin](#developing-a-dumy-plugin)
20 | - [Set-up AWS Elastic BeanStalk Staging environment](#set-up-aws-elastic-beanstalk-staging-environment)
21 | - [Set-up the AWS environment accounts](#set-up-the-aws-environment-accounts)
22 | - [Set-up the WordPress backup S3 bucket](#set-up-the-wordpress-backup-s3-bucket)
23 | - [Set-up the WordPress backup S3 bucket IAM policy](#set-up-the-wordpress-backup-s3-bucket-iam-policy)
24 | - [Configuring the UpdraftPlus WordPress plugin](#configuring-the-updraftplus-wordpress-plugin)
25 | - [Creating the EC2 Key Pair](#creating-the-ec2-key-pair)
26 | - [Creating the MySQL DB Instance](#creating-the-mysql-db-instance)
27 | - [Set-up your Elastic BeanStalk Application](#set-up-your-elastic-beanstalk-application)
28 | - [Create your Staging Application Environment](#create-your-staging-application-environment)
29 | - [Configuring the DocumentRoot](#configuring-the-documentroot)
30 | - [Configuring the WordPress Site URL](#configuring-the-wordpress-site-url)
31 | - [Adding the EC2 Security Group to your RDS Database](#Adding-the-ec2-security-group-to-your-rds-database)
32 | - [Set up the IAM permissions](#set-up-the-iam-permissions)
33 | - [Set-up continuousphp](#set-up-continuousphp)
34 | - [Application Project Set-up in continuousphp](#application-project-set-up-in-continuousphp)
35 | - [Deployment pipeline Configuration](#deployment-pipeline-configuration)
36 | - [Deploying Wordpress](#deploying-wordpress)
37 | - [Notes](#notes)
38 |
39 | ## Introduction
40 |
41 | Have you ever been scared on clicking on that WordPress or plugins update button ?
42 |
43 | Have you ever wanted to have a staging environement for the validation of your latest development by your customers and to update the production with one push upon validation ?
44 |
45 | Have you ever wanted to have automated test to ensure proper site function before deployments ?
46 |
47 | The goal of this project is to have a WordPress environment that let you develop, test, package and deploy an immutable WordPress on different environments like staging and production.
48 |
49 | It is based on docker-compose for the local development, [continuousphp](https://continuousphp.com) for building, testing and deploying on AWS Elastic BeanStalk Infrastructure environments.
50 |
51 | So let's start!
52 |
53 | ## Requirements
54 |
55 | * docker
56 | * docker-compose
57 | * composer
58 | * AWS account
59 |
60 | ## Set-up your Development environment
61 |
62 | ### Prepare your WordPress Repository
63 |
64 | Fork and clone the [WordPress Elastic BeanStalk Demo](https://github.com/continuousdemo/wordpress-eb-demo).
65 |
66 | Because we are going to configure continuousphp in staging environment, we need to create a develop branch, for which we will create a deployment pipeline.
67 |
68 | Create the **develop** branch:
69 |
70 | ```bash
71 | git checkout -B develop
72 | git push origin develop
73 | ```
74 |
75 | This WordPress Repository include the following files:
76 |
77 | * [composer.json](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/composer.json) with our WordPress dependencies
78 | * [build.xml](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/build.xml) with the phing targets
79 | * [build.properties](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/build.properties) with our Phing property file
80 | * [scripts](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/scripts/) with our provisioning scripts
81 | * [wp-content](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/wp-content/) with our custom WordPress content
82 | * [wp-root](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/wp-root/) with our root configuration WordPress content
83 | * [.ebextensions/project.config](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/.ebextensions/project.config) with the Elastic BeanStalk provisioning script.
84 | * [Dockerfile](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/Dockerfile) with our Docker file
85 | * [docker-compose.yml](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/docker-compose.yml) with docker-compose configuration file
86 | * [nginx](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/nginx/) with nginx configuration files
87 | * [php](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/php/) with php configuration files
88 | * [behat.yml](https://github.com/continuousdemo/wordpress-eb-demo/blob/master/tests/behat.yml) with the Behat configuration
89 |
90 | These are key files to set-up your WordPress installation, development and deployment environement. Feel free to take a look at them to get a better understanding.
91 |
92 | ### Dependencies management with composer
93 |
94 | Install Wordpress and plugins using composer like:
95 |
96 | ```
97 | composer.phar install
98 | ```
99 |
100 | ### Phing environment variables
101 |
102 | To set your local development environment copy the **build.local.properties.sample** to **build.local.properties**.
103 |
104 | ```
105 | cp build.local.properties.sample build.local.properties
106 | ```
107 |
108 | ### Create the develop symlinks
109 |
110 | Create the symlinks to enable plugins and themes in development mode:
111 |
112 | ```
113 | ./vendor/bin/phing wp-symlink-plugins
114 | ./vendor/bin/phing wp-symlink-themes
115 | ```
116 |
117 | Most of the WP plugins can be found on [wordpress packagist](https://wpackagist.org/), add them to your composer.json like:
118 |
119 | ```
120 | "require": {
121 | "php": ">=7.0",
122 | "johnpbloch/wordpress": ">=4.7.2",
123 | "composer/installers": "~1.0",
124 | "wpackagist-plugin/contact-form-7": "4.6.1",
125 | "wpackagist-plugin/business-profile": "1.1.1",
126 | "robmorgan/phinx": "~0.6.0",
127 | "wp-cli/wp-cli": "^1.0",
128 | "phing/phing": "~2.14"
129 | },
130 | ```
131 |
132 | ### Configuring Wordpress
133 |
134 | ```
135 | cp wp/wp-config-sample.php wp/wp-config.php
136 | ```
137 | Edit the wp/wp-config.php file and set WP configuration variables using $_SERVER environment variables as below, we do this to be able to provision the WP configuration for the differents environments like develop, staging and production.
138 |
139 | ```
140 | /** The name of the database for WordPress */
141 | define('DB_NAME', $_SERVER["MYSQL_ADDON_DB"]);
142 |
143 | /** MySQL database username */
144 | define('DB_USER', $_SERVER["MYSQL_ADDON_USER"]);
145 |
146 | /** MySQL database password */
147 | define('DB_PASSWORD', $_SERVER["MYSQL_ADDON_PASSWORD"]);
148 |
149 | /** MySQL hostname */
150 | define('DB_HOST', $_SERVER["MYSQL_ADDON_HOST"]);
151 |
152 | /** Database Charset to use in creating database tables. */
153 | define('DB_CHARSET', 'utf8');
154 |
155 | /** The Database Collate type. Don't change this if in doubt. */
156 | define('DB_COLLATE', '');
157 | ```
158 |
159 | and add:
160 |
161 | ```
162 | define('AUTH_KEY', $_SERVER["AUTH_KEY"]);
163 | define('SECURE_AUTH_KEY', $_SERVER["SECURE_AUTH_KEY"]);
164 | define('LOGGED_IN_KEY', $_SERVER["LOGGED_IN_KEY"]);
165 | define('NONCE_KEY', $_SERVER["NONCE_KEY"]);
166 | define('AUTH_SALT', $_SERVER["AUTH_SALT"]);
167 | define('SECURE_AUTH_SALT', $_SERVER["SECURE_AUTH_SALT"]);
168 | define('LOGGED_IN_SALT', $_SERVER["LOGGED_IN_SALT"]);
169 | define('NONCE_SALT', $_SERVER["NONCE_SALT"]);
170 | ```
171 |
172 | Once finished, copy the wp/wp-config.php in the wp-root/ folder, we will need it for the deployment provisioning.
173 |
174 | ```
175 | cp wp/wp-config.php wp-root/
176 | ```
177 |
178 | Let's export the environment variables for our development environment:
179 |
180 | ```
181 | export MYSQL_ADDON_HOST=192.168.99.100
182 | export MYSQL_ADDON_DB=wordpress
183 | export MYSQL_ADDON_PASSWORD=password
184 | export MYSQL_ADDON_USER=root
185 | export S3_BACKUP_URL=
186 | export S3_MEDIA_URL=
187 | export environment=develop
188 | ```
189 |
190 | If you plan to use the WordPress Security Keys (which we recommend), [generate the keys](https://api.wordpress.org/secret-key/1.1/salt/) and export them:
191 |
192 | ```
193 | export AUTH_KEY=""
194 | export SECURE_AUTH_KEY=""
195 | export LOGGED_IN_KEY=""
196 | export NONCE_KEY=""
197 | export AUTH_SALT=""
198 | export SECURE_AUTH_SALT=""
199 | export LOGGED_IN_SALT=""
200 | export NONCE_SALT=""
201 | ```
202 |
203 | Keep those keys in a safe place.
204 |
205 | ### Starting docker-compose
206 |
207 | ```
208 | docker-compose up
209 | ```
210 |
211 | Note: if you don't daemonize the docker-compose, you will need to open a new terminal, don't forget to export again your environment variables.
212 |
213 | #### Initializing the Database
214 |
215 | Now let's initialize our WP database.
216 |
217 | ```
218 | ./vendor/bin/phing reset-db
219 | ```
220 |
221 | #### WordPress Base Install
222 |
223 | Open in your browser http://192.168.99.100/wp-admin/install.php to install your WordPress.
224 |
225 | Complete the information:
226 |
227 | * Site Title: Your site title
228 | * Username: **admin**
229 | * Search Engine Visibility: Check discourage search engines from indexing this site
230 | * Click **Install WordPress**
231 |
232 | Your WordPress is now ready to be customized.
233 |
234 | Note: you may recieve a 500 Error because a phpmailerException, just refresh the page.
235 |
236 | ### Configuring your development environment
237 |
238 | ```
239 | ./vendor/bin/phing setup-dev
240 | ```
241 |
242 | Note: don't worry about the wp-get-s3-backup and wp-get-s3-media target that fail, we will use them later on.
243 |
244 | #### Plugin Installation
245 |
246 | We are going to add a few plugins.
247 |
248 | * Updraftplus to backup our wordpress assets on S3.
249 | * The w3-total-cache Search Engine and Performance Optimization plugin
250 |
251 | For this we add the "wpackagist-plugin/updraftplus" and "wpackagist-plugin/w3-total-cache" dependencies in our composer.json file like:
252 |
253 | ```
254 | "require": {
255 | "php": ">=7.0",
256 | "johnpbloch/wordpress": ">=4.7.2",
257 | "composer/installers": "~1.0",
258 | "wpackagist-plugin/contact-form-7": "4.6.1",
259 | "wpackagist-plugin/business-profile": "1.1.1",
260 | "wpackagist-plugin/updraftplus": "1.12.32",
261 | "wpackagist-plugin/w3-total-cache": "0.9.5.1",
262 | "robmorgan/phinx": "~0.6.0",
263 | "wp-cli/wp-cli": "^1.0",
264 | "phing/phing": "~2.14"
265 | },
266 | ```
267 |
268 | Edit the **build.properties** and add our new plugins into the wp.plugins variables, this varibales is used by the Phing target wp-plugins-activate.
269 |
270 | ```
271 | wp.plugins=business-profile,contact-form-7,updraftplus,w3-total-cache
272 | ```
273 |
274 | Do the same to your **build.local.properties**.
275 |
276 | Run a composer update to install the plugin.
277 |
278 | ```
279 | composer.phar update
280 | ```
281 |
282 | Then activate the plugins:
283 |
284 | ```
285 | ./vendor/bin/phing wp-plugins-activate
286 | ```
287 |
288 | Open in your browser http://192.168.99.100/wp-admin/plugins.php the updraftplus plugin is installed and activated. Note that the password for the **admin** user is **password**, we have updated it so we can run automated test.
289 |
290 | Notice all the plugin are installed and activated, but wait a minute, we W3 Total Cache that require an update, let's edit our composer.json and bump the version.
291 |
292 | Get the latest version at [WordPress Packagist](https://wpackagist.org/search?q=w3-total-cache&type=any&search=)
293 |
294 | ```
295 | "wpackagist-plugin/w3-total-cache": "0.9.5.2",
296 | ```
297 |
298 | Run composer update and refresh the plugin page, our plugin is up to date!
299 |
300 | ```
301 | composer.phar update
302 | ```
303 |
304 | If you need to install a Plugin which isn't available on WordPress Packagist or that you have to build a custom plugin, add it into the project root in wp-content folder, it is symlinked into the WordPress install, so you can develop or make it available to WordPress.
305 |
306 | #### Running the behat tests
307 |
308 | To run the behat test locally first, copy the **behat.local.yml.sample** to **behat.local.yml**
309 |
310 | ```
311 | cp tests/behat.local.yml.sample tests/behat.local.yml
312 | ```
313 |
314 | Then run behat with:
315 |
316 | ```
317 | ./vendor/bin/behat -c tests/behat.local.yml
318 | ```
319 |
320 | #### Themes Installation
321 |
322 | Now let's install a theme, we do the same, adding it to our **composer.json** and run ```composer update```.
323 |
324 | ```
325 | "wpackagist-theme/vanilla": "1.3.5"
326 | ```
327 |
328 | Update the theme in the **build.properties** and **build.local.properties**
329 |
330 | ```
331 | wp.theme=vanilla
332 | ```
333 |
334 | And let's activate it:
335 |
336 | ```
337 | ./vendor/bin/phing wp-theme-activate
338 | ```
339 |
340 | Let's change our behat test by editing the **tests/features/homepage.feature** file with:
341 |
342 | ```
343 | @home
344 | Feature: As a visitor I should be able to load the home page
345 |
346 | Scenario: Home page loads
347 | Given I am on the homepage
348 | Then I should see **"Just another WordPress site"**
349 | ```
350 |
351 | and run behat again:
352 |
353 | ```
354 | ./vendor/bin/behat -c tests/behat.local.yml
355 | ```
356 |
357 | We have now "Just another WordPress site"!
358 |
359 | Now, let's develop a dummy-plugin.
360 |
361 | #### Developing a dumy plugin
362 |
363 | Let's develop a dumy plugin to show how it works, for this we create a dumy-plugin plugin into the root wp-content/plugins.
364 |
365 | ```
366 | mkdir ./wp-content/plugins/dumy-plugin
367 | cd ./wp-content/plugins/dumy-plugin
368 | ```
369 |
370 | And add a **dumy-plugin.php** file with the following:
371 |
372 | ```
373 |
383 | ```
384 |
385 | Open your browser to http://192.168.99.100/wp-admin/plugins.php and your plugin is displayed.
386 |
387 | Add it to your **build.properties** and **build.local.properties**:
388 |
389 | ```
390 | wp.plugins=business-profile,contact-form-7,updraftplus,w3-total-cache,wordpress-https,dumy-plugin
391 | ```
392 |
393 | And let's activate it:
394 |
395 | ```
396 | ./vendor/bin/phing wp-plugins-activate
397 | ```
398 |
399 | Same apply to the theme development. **Be sure to only commit your themes and plugins of the root wp-content folder, not the ones installed by composer**.
400 |
401 | So we have our base WordPress development ready, now we are going to create our staging environment on AWS Elastic BeanStalk.
402 |
403 | ## Set-up AWS Elastic BeanStalk Staging environment
404 |
405 | ### Set-up the AWS environment accounts
406 |
407 | AWS recommends the separation of responsibilities, and therefore you should create a separate AWS account for every environment you might require.
408 |
409 | This tutorial explains Wordpress deployment in a **staging** environment.
410 |
411 | So let's start and create an AWS account for your staging environment.
412 |
413 | **Set up a new account:**
414 |
415 | 1. Open [https://aws.amazon.com/](https://aws.amazon.com/), and then choose *Create an AWS Account*.
416 | 2. Follow the online instructions.
417 |
418 | ### Set-up the WordPress backup S3 bucket
419 |
420 | Let's first create an S3 bucket for your WP backup.
421 |
422 | **Create the backup bucket**
423 |
424 | 1. Sign-in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3.
425 | 2. Click *Create Bucket*.
426 | 3. In the *Create a Bucket* dialog box, fill in the *Bucket Name*. In this example we will use **"my-wordpress-site-backup"**.
427 | 4. In the *Region* box, select a region from the drop-down list.
428 | 5. Click Create.
429 |
430 | When Amazon S3 has successfully created your bucket, the console displays your empty bucket **"my-wordpress-site-backup"** in the Bucket panel.
431 |
432 | Let's configure the Bucket Polocy.
433 |
434 | **Configuring the bucket policy**
435 |
436 | 1. Open the **my-wordpress-site-backup** bucket properties.
437 | 2. Goto **Permissions**
438 | 3. Select the **Bucket Policy** and add:
439 |
440 | ```
441 | {
442 | "Version": "2012-10-17",
443 | "Statement": [
444 | {
445 | "Sid": "PublicReadGetObject",
446 | "Effect": "Allow",
447 | "Principal": {
448 | "AWS": "*"
449 | },
450 | "Action": "s3:GetObject",
451 | "Resource": "arn:aws:s3:::my-wordpress-site-backup/*"
452 | }
453 | ]
454 | }
455 | ```
456 |
457 | Note: To get your account ID goto on the AWS My Account.
458 |
459 | ### Set-up the WordPress backup S3 bucket IAM policy
460 |
461 | Let's create an IAM policy to grant UpdraftPlus plugin the permission to upload the backups to your backup S3 bucket.
462 |
463 | **Create the policy**
464 |
465 | 1. Sign-in to the IAM console at https://console.aws.amazon.com/iam/ with your user that has administrator permissions.
466 | 2. In the navigation pane, choose *Policies*.
467 | 3. In the content pane, choose *Create Policy*.
468 | 4. Next to *Create Your Own Policy*, choose *Select*.
469 | 5. As *Policy Name*, type **my-wordpress-site-backup**.
470 | 6. As *Policy Document*, paste the following policy.
471 |
472 | ```
473 | {
474 | "Version": "2012-10-17",
475 | "Statement": [
476 | {
477 | "Effect": "Allow",
478 | "Action": [
479 | "s3:ListBucket",
480 | "s3:GetBucketLocation",
481 | "s3:ListBucketMultipartUploads"
482 | ],
483 | "Resource": "arn:aws:s3:::my-wordpress-site-backup",
484 | "Condition": {}
485 | },
486 | {
487 | "Effect": "Allow",
488 | "Action": [
489 | "s3:AbortMultipartUpload",
490 | "s3:DeleteObject",
491 | "s3:DeleteObjectVersion",
492 | "s3:GetObject",
493 | "s3:GetObjectAcl",
494 | "s3:GetObjectVersion",
495 | "s3:GetObjectVersionAcl",
496 | "s3:PutObject",
497 | "s3:PutObjectAcl",
498 | "s3:PutObjectAclVersion"
499 | ],
500 | "Resource": "arn:aws:s3:::my-wordpress-site-backup/*",
501 | "Condition": {}
502 | },
503 | {
504 | "Effect": "Allow",
505 | "Action": "s3:ListAllMyBuckets",
506 | "Resource": "*",
507 | "Condition": {}
508 | }
509 | ]
510 | }
511 | ```
512 | 7\. Choose *Validate Policy* and ensure that no errors display in a red box at the top of the screen. Correct any that are reported.
513 |
514 | 8\. Choose *Create Policy*.
515 |
516 | Now let's create an IAM user with an Access Key and attach the policy we've just created.
517 |
518 | **Create a new User and attach the User policy**
519 |
520 | 1. Sign-in to the Identity and Access Management (IAM) console at https://console.aws.amazon.com/iam/.
521 | 2. In the navigation pane, choose *Users* and then choose *Create New Users*.
522 | 3. Enter the following user: **my-wordpress-site-backup**
523 | 4. Select **Programmatic access** then click Next
524 | 5. Select **Attach existing policies directly**
525 | 6. Search for the policy we just made: **my-wordpress-site-backup**
526 | 7. Click Next the Create User
527 | 8. **Save the generated access key in a safe place**.
528 | 9. Choose *Close*.
529 |
530 | ### Configuring the UpdraftPlus WordPress plugin
531 |
532 | We are now going to configure the UpdraftPlus WordPress plugin. We use this plugin to keep a backup of our database and media files, so we can restore any of our environment from any backup.
533 |
534 | Open your browser to http://192.168.99.100/wp-admin/plugins.php
535 |
536 | 1. Open the settings page of the UpdraftPlus plugin
537 | 2. Goto the Settings Tab and configure the Backup settings:
538 | * File Backup schedule: Daily and retain this many scheduled backups: 15 Days
539 | * Database backup schedule: Daily and retain this many scheduled backups: 15 Days
540 | * Remote storage: Amazon S3
541 | * S3 access key: \
542 | * S3 secret key: \
543 | * S3 location: my-wordpress-site-backup/
544 | 3. Click on **Test S3 Settings**
545 | 4. Click on **Save Changes**
546 | 5. Goto the Current Status Tab
547 | 6. Click on **Backup Now**, ensure all checks are checked.
548 |
549 | Note: If you have an error with updraft folder is not writtable, create the folder and give it permission: ```mkdir wp/wp-content/updraft ; chmod 777 wp/wp-content/updraft```
550 |
551 | UpdraftPlus Backup ensure we keep your WordPress state up to date on all environments and be able to restore a version if needed.
552 |
553 | Let's open our S3 Backup Bucket my-wordpress-site-backup and get the latest DB backup filename to set our **build.local.properties** file with the s3_backup_url value.
554 |
555 | ```
556 | s3_backup_url=s3://my-wordpress-site-backup/backup_2017-02-16-1006_My_WP_site_1437f9fb506f-db.gz
557 | ```
558 |
559 | Let's configure our AWS cli profile using the S3 Bucket user:
560 |
561 | ```
562 | aws configure --profile=my-wordpress-site
563 | AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXX
564 | AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
565 | Default region name [None]: eu-central-1
566 | Default output format [None]:
567 | ```
568 |
569 | And let's rebuild our development environment:
570 |
571 | ```
572 | AWS_DEFAULT_PROFILE=my-wordpress-site ./vendor/bin/phing setup-dev
573 | ```
574 |
575 | As you can see now the wp-get-s3-backup get our backup and reinstall our WordPress database with the db-migration target, this enable us to make changes to our WordPress, make a backup and restore its state for all our environments.
576 |
577 | Let's do a test, add a page to our WordPress, make a backup, update the build.local.properties with the new WordPress database backup url and run the **setup-dev** phing target.
578 |
579 | Now let's continue to set our AWS Elastic BeanStalk environment.
580 |
581 | ### Creating the EC2 Key Pair
582 |
583 | To create your key pair using the Amazon EC2 console
584 |
585 | 1. Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/.
586 | 2. In the navigation pane, under *NETWORK & SECURITY*, choose *Key Pairs*.
587 | 3. Enter a name for the new key pair in the Key pair name field of the *Create Key Pair* dialog box, and then choose *Create*.
588 | The private key file is automatically downloaded by your browser. The base file name is the name you specified as the name of your key pair, and the file name extension is *.pem*. Save the private key file in a safe place.
589 | 4. If you will use an SSH client on a Mac or Linux computer to connect to your Linux instance, use the following command to set the permissions of your private key file so that only you can read it :
590 |
591 | ```bash
592 | chmod 400 my-key-pair.pem
593 | ```
594 |
595 | ### Creating the MySQL DB Instance
596 |
597 | 1. Sign in to the AWS Management Console and open the Amazon RDS console at https://console.aws.amazon.com/rds/.
598 | 2. In the top right corner of the Amazon RDS console, choose the region in which you want to create the DB instance.
599 | 3. In the navigation pane, choose Instances.
600 | 4. Choose Launch DB Instance. The Launch DB Instance Wizard opens on the Select Engine page.
601 | 5. On the Select Engine page, choose the MySQL icon and then choose Select for the MySQL DB engine for Dev/Test.
602 | 6. On the Specify DB Details page, specify your DB instance information.
603 | * DB Instance Class: db.t2.micro
604 | * Multi-AZ Deployment: No (We are in staging)
605 | * Allocated Storage: 5 GB
606 | * Storage Type: Magnetic
607 | * DB Instance Identifier: staging-my-wordpress-site-db
608 | * Master Username: wordpress_userdb
609 | * Master Password: \
610 | * VPC: Select the default VPC
611 | * Publicly Accessible: No
612 | * VPC Security Group(s): Create New Security Group
613 | * Database Name: staging_my_wordpress_site_db
614 | * Backup Retention Period: 1
615 | * Auto Minor Version Upgrade: Yes
616 | 7. Click on **Launch DB Instance**
617 |
618 | ### Set-up your Elastic BeanStalk Application
619 |
620 | **To create a new application**
621 |
622 | 1. Open the Elastic Beanstalk console.
623 | 2. Choose Create New Application.
624 | 3. Enter the name of the application: **my-wordpress-site**
625 | 4. Then click Create.
626 |
627 | ### Create your Staging Application Environment
628 |
629 | **To launch an environment**
630 |
631 | 1. Open the Elastic Beanstalk console.
632 | 2. Choose our application: **my-wordpress-site**
633 | 3. In the upper right corner, choose Create New Environment from the Actions menu.
634 | 4. Choose **Web server** environment types.
635 | 5. For Platform: PHP
636 | 6. For App code, choose Sample application.
637 | 7. Choose Configure more options.
638 | 8. Configuration presets: Custom configuration
639 | 9. Select **Environment settings** and fill in the following:
640 | *. Name: Staging
641 | *. Domain: staging-my-wordpress-site
642 | 10. Select **Software settings** and fill in the following **Environment properties**:
643 | * environment: staging
644 | * MYSQL_ADDON_DB: staging_my_wordpress_site_db
645 | * MYSQL_ADDON_HOST: staging-my-wordpress-site-db.ce7wdtyntw8p.\.rds.amazonaws.com
646 | * MYSQL_ADDON_USER: wordpress_userdb
647 | * MYSQL_ADDON_PASSWORD: \
648 | * S3_BACKUP_URL: \
649 | * S3_MEDIA_URL:
650 | 11. Optionally if you have configured the WP Security Keys, set the following variables as well:
651 | * AUTH_KEY:
652 | * AUTH_SALT:
653 | * LOGGED_IN_KEY:
654 | * LOGGED_IN_SALT:
655 | * NONCE_KEY:
656 | * NONCE_SALT:
657 | * SECURE_AUTH_KEY:
658 | * SECURE_AUTH_SALT:
659 | 12. Select **Instances** and fill in the following:
660 | 1. Root volume type: General Purpose (SSD)
661 | 2. Size: 10 GB
662 | 13. Select **Security**
663 | 1. EC2 key pair: \
664 | 14. Select **Notifications**
665 | 1. Email: \
666 | 15. Select **Network**
667 | 1. Select your default VPC in the Virtual private cloud (VPC)
668 | 2. Select all the Instance subnets
669 | 3. Instance security groups select:
670 | * rds-launch-wizard
671 | 16. Do not configure the Database settings.
672 | 17. Choose Create environment.
673 |
674 | ### Configuring the DocumentRoot
675 |
676 | When the environment has been created, let's configure your DocumentRoot.
677 |
678 | 1. Goto your Elastic Beanstalk application **my-wordpress-site**
679 | 2. Select your environment **Staging**
680 | 3. Goto Configuration
681 | 4. Select **Software Configuration**, and fill in the following:
682 | * Document root: /wp
683 |
684 | Now let's configure the WordPress Site URL.
685 |
686 | ### Configuring the WordPress Site URL
687 |
688 | Still in the **Software Configuration** you will add the SERVER_HOSTNAME variable, but before let's get the URL of our Elastic BeanStalk URL available at the top of the page near the environment name, copy it and add the variable:
689 |
690 | * SERVER_HOSTNAME: http://staging-my-wordpress-site.eu-central-1.elasticbeanstalk.com/
691 |
692 | Note: if you configure a Route53 alias to your Elastic Load Balancer, use that domain name instead.
693 |
694 | ### Adding the EC2 Security Group to your RDS Database
695 |
696 | In order to let the EC2 communicate with your WordPress RDS Database you need to add the EC2 Security Group to your RDS Database Security Group, for this:
697 |
698 | 1. Sign-in to the IAM console at https://console.aws.amazon.com/ec2/ with your user that has administrator permissions.
699 | 2. Goto Security Groups
700 | 3. Select the rds-launch-wizard Security Group
701 | 4. Goto Inbound and Edit
702 | 5. Add in Inboud Rule with:
703 | * Type: MySQL/Aurora
704 | * Protocol: TCP/IP
705 | * Port Range: 3306
706 | * Source: \
707 |
708 | To find the EC2 Security Group Id, find the Security Group Name called **my-wordpress-site**
709 |
710 | ## Set up the IAM permissions
711 |
712 | Let's create an IAM policy to grant continuousphp the permission to upload the package to your Elastic BeanStalk bucket and communicate with Elastic BeanStalk to deploy it.
713 |
714 | **Create the policy**
715 |
716 | 1. Sign-in to the IAM console at https://console.aws.amazon.com/iam/ with your user that has administrator permissions.
717 | 2. In the navigation pane, choose *Policies*.
718 | 3. In the content pane, choose *Create Policy*.
719 | 4. Next to *Create Your Own Policy*, choose *Select*.
720 | 5. As *Policy Name*, type **eb-deploy-staging**.
721 | 6. As *Policy Document*, paste the following policy.
722 |
723 | ```json
724 | {
725 | "Version": "2012-10-17",
726 | "Statement": [
727 | {
728 | "Action": [
729 | "autoscaling:*",
730 | "cloudformation:*",
731 | "ec2:*"
732 | ],
733 | "Effect": "Allow",
734 | "Resource": [
735 | "*"
736 | ]
737 | },
738 | {
739 | "Action": [
740 | "elasticbeanstalk:*"
741 | ],
742 | "Effect": "Allow",
743 | "Resource": [
744 | "arn:aws:elasticbeanstalk:*::solutionstack/*",
745 | "arn:aws:elasticbeanstalk:::application/my-wordpress-site",
746 | "arn:aws:elasticbeanstalk:::applicationversion/my-wordpress-site/*",
747 | "arn:aws:elasticbeanstalk:::environment/my-wordpress-site/*",
748 | "arn:aws:elasticbeanstalk:::template/my-wordpress-site/*"
749 | ]
750 | },
751 | {
752 | "Action": [
753 | "s3:Get*"
754 | ],
755 | "Effect": "Allow",
756 | "Resource": [
757 | "arn:aws:s3:::elasticbeanstalk-*/*"
758 | ]
759 | },
760 | {
761 | "Action": [
762 | "s3:CreateBucket",
763 | "s3:DeleteObject",
764 | "s3:GetBucketPolicy",
765 | "s3:GetObjectAcl",
766 | "s3:ListBucket",
767 | "s3:PutBucketPolicy",
768 | "s3:PutObject",
769 | "s3:PutObjectAcl"
770 | ],
771 | "Effect": "Allow",
772 | "Resource": [
773 | "arn:aws:s3:::elasticbeanstalk--",
774 | "arn:aws:s3:::elasticbeanstalk--/*"
775 | ]
776 | },
777 | {
778 | "Action": [
779 | "iam:PassRole"
780 | ],
781 | "Effect": "Allow",
782 | "Resource": [
783 | "arn:aws:iam:::role/aws-elasticbeanstalk-ec2-role"
784 | ]
785 | },
786 | {
787 | "Action": [
788 | "elasticloadbalancing:DescribeLoadBalancers"
789 | ],
790 | "Effect": "Allow",
791 | "Resource": [
792 | "*"
793 | ]
794 | },
795 | {
796 | "Action": [
797 | "elasticloadbalancing:RegisterInstancesWithLoadBalancer"
798 | ],
799 | "Effect": "Allow",
800 | "Resource": [
801 | "arn:aws:elasticloadbalancing:::loadbalancer",
802 | "arn:aws:elasticloadbalancing:::loadbalancer/*"
803 | ]
804 | },
805 | {
806 | "Effect": "Allow",
807 | "Action": "sns:*",
808 | "Resource": "arn:aws:sns:::*"
809 | }
810 | ]
811 | }
812 | ```
813 |
814 | 7\. Choose *Validate Policy* and ensure that no errors display in a red box at the top of the screen. Correct any that are reported.
815 |
816 | 8\. Choose *Create Policy*.
817 |
818 | Now let's create an IAM user with an Access Key and attach the policy we've just created.
819 |
820 | **Create a new User and attach the User policy**
821 |
822 | 1. Sign-in to the Identity and Access Management (IAM) console at https://console.aws.amazon.com/iam/.
823 | 2. In the navigation pane, choose *Users* and then choose *Create New Users*.
824 | 3. Enter the following user: **staging-wordpress-deploy**
825 | 4. Select **Programmatic access** then click Next
826 | 5. Select **Attach existing policies directly**
827 | 6. Search for the policy we just made: **eb-deploy-staging**
828 | 7. Click Next the Create User
829 | 8. Save the generated access key in a safe place.
830 | 9. Choose *Close*.
831 |
832 | ## Set-up continuousphp
833 |
834 | ### WordPress Project Set-up in continuousphp
835 |
836 | **Set-up our WordPress project in continuousphp**
837 |
838 | 1. Type in the omnibar the name of the application: **wordpress-eb**
839 | 2. The fork should appear in the Project List (if not please wait a little that projects list update or simply logout/login)
840 | 3. Click on **Setup**
841 | 4. Click on **Setup Repository**
842 | 5. Click on **+** to add a deployment pipeline
843 | 6. Select the **develop** branch
844 |
845 | ### Deployment pipeline Configuration
846 |
847 | **To configure your deployment pipeline**
848 |
849 | 1. In the Build Settings (Step 1):
850 | 1. In the **PHP VERSIONS**, select the PHP versions: **7.1**
851 | 2. Set the Document Root to: wp
852 | 3. In the **CREDENTIALS**, click on the **+**, add the AWS IAM Credential **deployment.staging** User Access Key and Secret Key we created in step [Set-up the IAM permissions](#set-up-the-iam-permissions)
853 | * Name: deployment.staging
854 | * Region: \
855 | * Access Key: \
856 | * Secret Key: \
857 | 4. Still in the **CREDENTIALS**, click on the **+**, add the AWS IAM Credential **my-wordpress-site-backup** User Access Key and Secret Key we created in step [Set-up the WordPress backup S3 bucket IAM policy](#set-up-the-wordpress-backup-s3-bucket-iam-policy)
858 | * Name: my-wordpress-site-backup
859 | * Region: \
860 | * Access Key: \
861 | * Secret Key: \
862 | 5. In the **PHING** section, add the following Phing Target: **wp-composer-plugins-update**
863 | 6. Uncheck the **Enable caching of Composer packages**
864 | 6. Click on **Next** to move to the Test Settings
865 | 2. In the Test Settings (Step 2):
866 | 1. continuousphp automatically discovers that you have a `behat.yml` and `phpunit.xml` in your repository and creates the testing configuration for you.
867 | 2. Click on the **Behat** configuration panel. In the **PHING** section, select the following Phing Targets: **reset-db** and **setup-test**
868 | 3. Still in the **PHING** section, add the following variables:
869 | * environment: develop
870 | 4. Set the environment variables, Click on the + Next to **ENVIRONMENT VARIABLES**
871 | * MYSQL_ADDON_HOST: 127.0.0.1
872 | * MYSQL_ADDON_DB: wordpress
873 | * MYSQL_ADDON_USER: root
874 | * MYSQL_ADDON_PASSWORD:
875 | * S3_BACKUP_URL: \
876 | * S3_MEDIA_URL:
877 | * SERVER_HOSTNAME: http://localhost/
878 | * AUTH_KEY:
879 | * AUTH_SALT:
880 | * SECURE_AUTH_KEY:
881 | * LOGGED_IN_KEY:
882 | * NONCE_KEY:
883 | * SECURE_AUTH_SALT:
884 | * LOGGED_IN_SALT:
885 | * NONCE_SALT:
886 | 5. Click on **Next** to move to the Package Settings
887 | 3. In the Package Settings (Step 3):
888 | 1. Select **AWS ElasticBeanstalk**
889 | 2. In the **PHING** section, add the following Phing Target: **wp-composer-plugins-update**
890 | 3. Click on **Next** to move to the Deployment Settings
891 | 4. In the Deployment Settings (Step 4):
892 | 1. Click on **+** on the **DESTINATIONS** panel
893 | 2. Complete the destination:
894 | * Name: staging
895 | * Apply to: push
896 | * IAM Profile: The profile we created in Step 1.2
897 | * Application: my-wordpress-site
898 | * Environment: Staging
899 | * S3 Bucket: Sign-in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3, look for a bucket called elasticbeanstalk-\-\ and add **/package**
900 | 3. Check the **enable deployment for successful builds** checkbox
901 |
902 | ## Deploying WordPress
903 |
904 | Before Deploying, let's push our changes:
905 |
906 | ```
907 | git status
908 | git add build.properties
909 | git add composer.json
910 | git add tests/features/homepage.feature
911 | git commit -m "Adding plugins and behat tests"
912 | git push origin develop
913 | ```
914 |
915 | A build has started automatically on continuousphp.
916 |
917 | **Deploying WordPress manually with continuousphp**
918 |
919 | 1. Click on the **Play** button on the top right of the project
920 | 2. Select the **develop** branch
921 | 3. The build is started. It will create the testing and dist package, then run the tests (Behat) for the choosen PHP versions, and finally it deploys the WordPress on Elastic BeanStalk Staging environment.
922 | 4. In the deploy console, you should see **Deployment successfully started**
923 | 5. Login to the AWS console/AWS Elastic BeanStalk to see the details.
924 |
925 | Let's modify our Dumy plugin at ./wp-content/plugins/dumy-plugin/dumy-plugin.php and bump its version to 1.1:
926 |
927 | ```
928 |
938 | ```
939 |
940 | ```bash
941 | git checkout develop
942 | git add ./wp-content/plugins/dumy-plugin/dumy-plugin.php
943 | git commit -m "Bumping our Dumy plugin version"
944 | git pusih origin develop
945 | ```
946 |
947 | Now, everytime you push to the develop branch, your develop pipeline is triggered and continuousphp builds, tests and deploys your WordPress upon a successful build.
948 |
949 | ## Notes
950 |
951 | * The Configuration used in this tutorial is an example and should not be used for production use as is.
952 | * The Configuration used in this tutorial is a base and should be completed to suit your needs.
953 | * This Tutorials used AWS Resources which has cost, please delete your Elastic BeanStalk and RDS database when you have finished to avoid cost.
954 |
955 | If you like to know more about production configuration or have questions about this tutorial, do not hesitate to contact us using the chat button!
956 |
--------------------------------------------------------------------------------