Cloudflare
- Signup Cloudflare
- Add website to Cloudflare
- Change name servers to Cloudflare’s
- Enable “Always On HTTPS”
- Tweak SSL settings if necessary – default is Full, can be Flexible or Strict
AWS
- Signup AWS account
- Decide which AWS Region as primary region, considering cost, latency, and feature parity
- Draw a Deployment Diagram using draw.io. Diagram should contain: Buyer, Vendor, Customer Support, Internet, Cloudflare CDN, ECS for production, ECS for staging, EBS for production, EBS for staging, MariaDB, Redis, SES.
- Login to AWS Management Console.
- Switch to your chosen Region.
- (If not yet exists) Create a security group: “
web-server
“, allow Inbound on HTTP and HTTPS from anywhere. Optionally, allow SSH port.
AWS SES
- We start with SES as this step requires validation (SPF and DKIM) and also request to get out of sandbox.
- Check if SES is available in your primary region. If not, go to US East (N. Virginia).
- Verify your domain:
- Save Record Set as CSV and save it in safe place.
- In Cloudflare, add given TXT records.
- In Cloudflare, add given CNAME/DKIM records (make sure to set as not proxied).
- Only if you want to receive mail using SES: add given MX records.
- Add TXT record (example is if you use Yandex Mail too):
v=spf1 include:amazonses.com include:_spf.yandex.net ~all
- Request Sending Limit Increase:
- Select your region (likely US East Northern Virginia)
- Desired Daily Sending Quota: 20000
- Desired Maximum Send Rate: 20
- Describe how you will comply: “My email-sending complies with the AWS Service Terms and AUP”
- Then: “I only send to recipients who have specifically requested my mail”
- Then: “I have a process to handle bounces and complaints”
- Dear AWS team, In my app/website, I am collecting emails through opt-in subscriptions. My emails are clean and verified. I will be using online emailing application: WordPress/Mautic. This application can handle bounce, complaint and unsubscription effectively. I have also verified the domain I am using. Kindly approve my request for Amazon SES production access in above mentioned region. Let me know if you have any question. Thanks and Regards!
- Go to IAM. Create user “
mailer
” with Programmatic Access only, using policiesAmazonSESFullAccess
andAmazonSNSFullAccess
(for more security, limit the permissions with manual policy).- Save the AWS access key ID and secret access key in a safe place.
RDS MariaDB
- Go to your primary region.
- Go to RDS.
- Create a MariaDB cluster at latest version.
- Dev/Test is sufficient for starter
- Instance size: db.t3.micro is sufficient for starter
- Additional connectivity: If you need public access (but less security), set as Publicly accessible
- Security group: Create “mariadb” security group.
- Availability zone: Choose the “a” AZ, and later ensure that other services use the same AZ for highest performance and lower bandwidth costs.
- Enhanced monitoring: You may want to disable this to save costs
- Log exports: Audit log, Error log, General log, Slow query log
- Deletion protection: Enable
- Save the master username, master password, and endpoint, in a safe place.
- Create users in MariaDB, e.g. brand_wp_prd and brand_wp_stg.
- Create databases in MariaDB, e.g. brand_wp_prd and brand_wp_stg. Make sure to use charset=utf8mb4.
- Grant privileges to databases.
- Flush privileges.
- Save the users and databases credentials in a safe place.
- Go to EC2 > Security Groups > mariadb. Allow Inbound MySQL from “webserver”.
- Later, you’ll need to create ECS instances that includes the “mariadb” security group.
ElastiCache Redis
- Go to your primary region.
- Create Security group “redis”.
- Allow Inbound Redis (port 6379) from “webserver”.
- Go to ElastiCache.
- Create a new ElastiCache Redis cluster:
- Cluster mode is usually disabled (i.e. replicas only, no shards), if enabled you can configure shards.
- Node type: cache.t3.micro is sufficient for a start.
- Replicas: if you only need primary, you can set 0 replicas.
- Preferred availability zone(s): select the “a” zone.
- Backup: If you use Redis only for caching, automatic backups can be disabled.
- Security group: “redis”.
- Later, you’ll need to create ECS instances that includes “webserver” security group which is allowed to access Redis.
S3
- Create bucket “media.brand.com” in your primary region.
- Disable “Block all public access” to the bucket.
- Create “media-stg.brand.com” in your primary region.
- Disable “Block all public access” to the bucket.
- Create IAM Policy “brand_S3_media.brand.com” with access to bucket “media.brand.com” and “media-stg.brand.com”.
- Assign the IAM Policy to Role “brand_ecsInstanceRole”.
- In Cloudflare, add CNAME (proxied) “media.brand.com” to your S3 standard endpoint, e.g. “s3.ap-southeast-1.amazonaws.com”.
- In Cloudflare, add CNAME (proxied) “media-stg.brand.com” to your S3 standard endpoint, e.g. “s3.ap-southeast-1.amazonaws.com”.
ECS
- Go to your primary region.
- Go to EC2. Create a keypair.
- Save the keypair in a safe place.
- Create Elastic IP and name it “subdomain.brand.com”.
- In Cloudflare, add A record (proxied) to that Elastic IP.
- Go to IAM. Create RexrayPolicy.
- Add RexrayPolicy to “brand_ecsInstanceRole”.
- Go to ECS. Create cluster “brand-wp-prd”.
- Instance type: t3a.nano is sufficient for WordPress, t3a.micro is sufficient for WooCommerce.
- Key pair: Choose the keypair you already prepared.
- VPC: Choose existing.
- Subnet: Choose “a”.
- Security group: “webserver”.
- Assign Elastic IP to ECS instance.
- SSH to instance.
- Install rexray/ebs docker plugin.
- Restart docker service.
- Create cluster capacity provider, managed scaling & termination: disabled.
- Update cluster to use the new capacity provider.
- Optionally, go back to step 5 to prepare stg cluster.
- Create Task Definition “brand-wp-prd”.
- Volume:
brand-wp-prd
.
Driver: rexray/ebs.
Scope: Shared.
Auto-provision: true.
Driver options: volumetype=gp2, size=5. - Container: wordpress,
Port mapping: 80:80
Environment variables:WORDPRESS_DB_HOST
,WORDPRESS_DB_USER
,WORDPRESS_DB_PASSWORD
,WORDPRESS_DB_NAME
- Mount
brand-wp-prd
to/var/www/html
- Auto-configure CloudWatch Logs
- Volume:
- Run task.
WordPress Setup Phase 1
- In
.htaccess
, increasememory_limit
,post_max_size
, andupload_max_size
via.htaccess
. php.ini’s upload_max_filesize is too small for typical web sites, and also for uploading plugins. Set both to 64M. How to:- SSH to the ECS instance
docker ps
(to get wordpress container name)docker exec -it CONTAINER /bin/bash
apt-get update
apt-get install nano
nano /var/www/html/.htaccess
- Append at bottom:
php_value memory_limit 256M
php_value post_max_size 64M
php_value upload_max_filesize 64M - After editing, save with Ctrl+X, enter, enter.
- In
wp-config.php
, increaseWP_MEMORY_LIMIT
andWP_MAX_MEMORY_LIMIT
(reason). How to:- SSH to the ECS instance
docker ps
(to get wordpress container name)docker exec -it CONTAINER /bin/bash
apt-get update
apt-get install nano
nano /var/www/html/wp-config.php
- Append before
/* That's all, stop editing! Happy publishing. */
: define( 'WP_MEMORY_LIMIT', '128M' );
define( 'WP_MAX_MEMORY_LIMIT', '256M' );
- After editing, save with Ctrl+X, enter, enter.
- Install WP Offload SES Lite for AWS SES Mail Support.
- Note: need to edit wp-config.php using ssh/SFTP, and check the mount of docker’s rexray plugin, then edit using vi since nano & vim is not available in ECS container image.
- Enable: Send via SES, Open Tracking, Click Tracking.
- (Optional) Alternative to WP Offload SES Lite: weMail.
- Connect AWS SES using IAM user “mailer” API key.
- Go to weMail Settings.
- Registration Opt-in: Enabled.
- WooCommerce Opt-in: Enabled.
- Select List: WordPress Users.
- Enable Notification: Enabled.
- Enable (transactional) Emails: Enabled.
- (Optional) Alternative mailing lists: Sendy + Sendybay, MailPoet (1,000 subscribers free, visual builder), SendFox (basic WYSIWYG, no visual builder).
- Install WP Offload Media Lite.
- Choose “My server is on Amazon Web Services and I’d like to use IAM Roles”
- Bucket: “media.brand.com”
- Custom Domain (CNAME): “media.brand.com”
- Force HTTPS: Yes
- Remove Files from Server: Yes (Warning: This is may cause problems with some plugins)
- (Only if you use Redis) Define in wp-config.php:
- WP_REDIS_HOST (without port)
- WP_CACHE_KEY_SALT = (stg.)brand.com
- (Only if you use Redis) Install Redis Object Cache.
- Enable Object Cache.
- Make sure status is “Connected”.
- TODO: phpredis (PECL)
- Install Breeze.
- Setup Cron.
WooCommerce
Optional plugins depending on requirements:
- Abandoned cart reports plugin:
- Abandoned Cart Reports Lite (Free)
- Abandoned Cart Reports Premium ($15/yr/store)
- Cart Reports ($79/yr)
- WooCommerce Product addons plugin ($49/yr)
- WooCommerce Orders Spreadsheet ($29.99/yr or $69.99 lifetime)
Multi-Vendor
- Install Dokan plugin (Free/Starter/Pro/Business/Enterprise)
- Register a vendor
- Enable vendor for selling
- Free modules:
- WooCommerce PDF Invoices & Packing Slips
- Dokan Invoice
- Setup Logo & Invoice Information: Admin > WooCommerce > PDF Invoices > Template
Elementor & WooCommerce Theme
- Theme (Freemium or Pro) compatible with WooCommerce. Should be compatible with Elementor and Elementor WooCommerce Builder:
- Astra (Pro has its own WooCommerce Designer, $59/year for unlimited sites)
- Elementor Hello
- GeneratePress (Premium: $49.95/year for unlimited sites)
- OceanWP
- Neve
- Phlox
- Flatsome (has its own page builder, so you don’t need Elementor, check this thread before you decide to choose Flatsome)
- Divi (review)
- Elementor (Pro).
- Starter Templates for Elementor.
- Elementor WooCommerce Builder.
- Essential Addons for Elementor.
- Dynamic Visibility for Elementor.
- Design header and footer.
SEO & Analytics
- Google Tag Manager.
- Track outbound link clicks.
- Yoast SEO (Free or Pro).
CloudWatch
- In your AWS Region, create CloudWatch Dashboard
- ECS EC2 – CPU per instance:
CPUUtilization
&CPUCreditBalance
- ECS EC2 – Disk I/O per instance:
EBSReadOps
&EBSWriteOps
- ECS EC2 – Network I/O per instance:
NetworkIn
&NetworkOut
- RDS – per instance:
DatabaseConnections
&FreeableMemory
- RDS – per instance:
FreeStorageSpace
&BurstBalance
- RDS – per instance:
ReadIOPS
&WriteIOPS
- S3: Storage
- S3: Network I/O
- Billing: Current & Forecasted
- ECS EC2 – CPU per instance:
- Create CloudWatch Alarms with email (SNS) notification
Performance Optimization
- Install Query Monitor plugin.
- Install XHProf extension.
- Install aws-xray plugin.
Known Issues
Design Customization
- Elementor WooCommerce Builder: Single Product Template.
- Elementor WooCommerce Builder: Product Archive Template.
AMP
- TODO