├── LICENSE.md ├── README.md ├── addon ├── WPMU.jps ├── edgeportCDN.jps ├── multisites.jps └── myisam2innodb.jps ├── configs ├── autotest.yaml ├── cp │ ├── litespeed │ │ ├── .htaccess_basic │ │ ├── .htaccess_subdir │ │ └── .htaccess_subdom │ └── nginx │ │ ├── subdir.conf │ │ └── subdom.conf ├── deps.yaml ├── lb │ └── litespeed │ │ └── jelastic.xml ├── settings.yaml ├── sqldb │ └── wordpress.cnf ├── vers.yaml └── wordpress │ └── wp-jelastic.php ├── images ├── cluster-litespeed.svg ├── cluster.svg ├── deploy-to-jelastic.png ├── favicon.ico ├── install-new.png ├── patch-install.png ├── patch-logo.png ├── patch-success.png ├── single-cluster-topology-storage-scaling.png ├── single-cluster-topology.png ├── standalone.svg ├── success-wordpress.png ├── woo_logo.png ├── wordpress-multisite.png ├── wp-cluster-business.png ├── wp-cluster-enterprise.png ├── wp-cluster-installation.png ├── wp-cluster-installed.png ├── wp-cluster-kit.png ├── wp-cluster.png ├── wp-standalone-pro.png ├── wp-standalone-starter.png ├── wp_logo.svg └── wp_logo_70.png ├── manifest.jps ├── patch ├── loadOptimization │ ├── README.md │ ├── configs │ │ └── LSADC_vhost.xml │ ├── optimization.jps │ └── scripts │ │ ├── DB.sh │ │ ├── LSADC.sh │ │ └── LSWEB.sh ├── lscache_v3.jps └── setupWP.sh ├── scripts ├── WP-CLI.jps ├── addTriggers.js ├── beforeinstall.js ├── checkCdnContent.txt ├── dummyLS.js ├── idna.js ├── installWP.jps ├── nginx-fastcgi-cache-purge.zip ├── settings.js ├── setupBL.jps ├── setupCDN.jps ├── setupCP.jps ├── setupSITES.jps ├── setupWP.sh └── updateTriggers.js └── success ├── email └── cluster │ ├── oneregion-cdn.md │ └── oneregion-default.md └── text └── oneregion ├── success-cdn.md └── success.md /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Highly Available and Auto-Scalable WordPress Cluster v2 2 | 3 | Out-of-the-box automated Enterprise WordPress Cluster solution v2 for large businesses and mission-critical sites 4 | 5 | 6 | ## WordPress Cluster Topology 7 | 8 | Upon the package installation, a new environment with the following topology will be created: 9 | 10 | * Either highly available **[LiteSpeed ADC](https://docs.jelastic.com/litespeed-web-adc)** or **[NGINX](https://docs.jelastic.com/tcp-load-balancing)** load balancer is used for distributing the incoming traffic within a cluster 11 | * **WordPress Brute Force Attack Protection** option will protect WordPress admin panel in case **[LiteSpeed Web Server](https://docs.jelastic.com/litespeed-web-server)** is chosen 12 | * **Web Application Firewall** will be enabled by the default if **LiteSpeed Web Server** will be installed 13 | * The *WordPress* application itself is handled by either **LiteSpeed Web Server** or **[NGINX PHP](https://docs.jelastic.com/nginx-php)** servers with preconfigured [automatic horizontal scaling](https://docs.jelastic.com/automatic-horizontal-scaling) to handle load spikes 14 | * **Redis** is high-performance RAM-allocated data structure store used as a highspeed caching solution 15 | * Highly-available **[MariaDB Galera Cluster](https://github.com/jelastic-jps/mysql-cluster#mariadb-galera-cluster)** is used to store and operate user data 16 | * **[Shared Storage](https://docs.jelastic.com/shared-storage-container)** cluster, ensuring high avaiablity with GlusterFS, is mounted to all application server nodes for sharing common data 17 | * Traffic encryption is provided by [Let's Encrypt Add-On](https://jelastic.com/blog/free-ssl-certificates-with-lets-encrypt/) with automatic issuing of trusted SSL certificate and Auto-Renewal. 18 | * **[Premium CDN](https://jelastic.com/blog/enterprise-cdn-verizon-integration/)** integration in order to provide Lightning-fast static assets loading 19 | 20 | 21 | 22 | 23 |

24 | 25 |

26 | 27 | ## Deployment to the Cloud 28 | 29 | Click the **Deploy** button below, specify your email address within the widget, choose one of the [Jelastic Public Cloud providers](https://jelastic.com/install-application/?manifest=https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/v2.0.0/manifest.yml&keys=app.mycloud.by;app.jelastic.eapps.com;app.hidora.com;app.rag-control.hosteur.com;app.jpc.infomaniak.com;;app.jpe.infomaniak.com;app.trendhosting.cloud;app.cloudjiffy.com;app.paas.mamazala.com;app.mircloud.host;app.paas-infra.previder.com;app.my.reclaim.cloud;app.j.scaleforce.net;app.unicloud.pl;app.unispace.io;app.trendhosting.cloud;app.cloudlets.com.au&filter=auto_cluster) and press **Install**. 30 | 31 | [![Deploy to Jelastic](https://github.com/jelastic-jps/git-push-deploy/raw/master/images/deploy-to-jelastic.png)](https://jelastic.com/install-application/?manifest=https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/v2.0.0/manifest.yml&keys=app.mycloud.by;app.jelastic.eapps.com;app.hidora.com;app.rag-control.hosteur.com;app.jpc.infomaniak.com;;app.jpe.infomaniak.com;app.trendhosting.cloud;app.cloudjiffy.com;app.paas.mamazala.com;app.mircloud.host;app.paas-infra.previder.com;app.my.reclaim.cloud;app.j.scaleforce.net;app.unicloud.pl;app.unispace.io;app.trendhosting.cloud;app.cloudlets.com.au&filter=auto_cluster) 32 | 33 | > **Note:** 34 | > - The installation of this clustered solution is available only for billing customers 35 | > - If you are already registered at Jelastic, you can deploy this cluster by importing the [the package manifest raw link](https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/v2.0.0/manifest.yml) within the dashboard. 36 | 37 | ## Installation Process 38 | 39 | In the opened confirmation window at Jelastic dashboard, if required change: 40 | 41 | * preconfigured horizontal __Scaling Strategy__ 42 | 43 | * what __Advanced Features__ should be installed or not 44 | * __Environment__ name 45 | 46 | * __Display Name__ 47 | 48 | * destination __[Region](https://docs.jelastic.com/environment-regions)__ if several are available 49 | 50 | and click on __Install__. 51 | 52 |

53 | 54 |

55 | 56 | Once the deployment is finished, you’ll see an appropriate success pop-up with access credentials to your administration WordPress panel, whilst the same information will be duplicated to your email box. 57 | 58 |

59 | 60 |

61 | 62 | So now you can just click on the **Open in browser** button within the shown frame and start filling your highly available and reliable WP installation with the required content, being ready to handle as much users as your service requires. 63 | 64 | > **Note:** Keep in mind that you can't do redeploy from previous WordPress Cluster edition to the new version. So in case you have decided to move your site to the WordPress Cluster v2 you should migrate it following the Tutorial ["How to Migrate a WordPress Site to Jelastic PaaS](https://jelastic.com/blog/migrate-wordpress-site/) or any other one you prefer. 65 | 66 | ## WordPress Managed Hosting Business 67 | 68 | To start offering this solution to your customers please follow to [Auto-Scalable Clusters for Managed Cloud Business](https://jelastic.com/apaas/) 69 | -------------------------------------------------------------------------------- /addon/WPMU.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | jpsVersion: '1.1' 3 | name: Multisites addon for WordPress cluster 4 | description: Multisites addon for WordPress cluster 5 | logo: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/images/wp-cluster.png 6 | baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master 7 | settings: 8 | main: 9 | fields: 10 | - name: mode 11 | caption: Multisites mode 12 | type: radio-fieldset 13 | values: 14 | subdir: SubDirectories 15 | subdom: SubDomain 16 | default: subdir 17 | 18 | globals: 19 | MODE: ${settings.mode} 20 | 21 | onInstall: 22 | - if (/lemp/.test("${nodes.cp.nodeType}") || /nginxphp/.test("${nodes.cp.nodeType}")): 23 | - if ('${globals.MODE}' == 'subdir'): 24 | cmd[${nodes.cp.master.id}]: |- 25 | wget ${baseUrl}/configs/cp/nginx/subdir.conf -O /etc/nginx/conf.d/SITES_ENABLED/subdir.conf 26 | sudo /etc/init.d/nginx reload 27 | - if ('${globals.MODE}' == 'subdom'): 28 | cmd[${nodes.cp.master.id}]: |- 29 | wget ${baseUrl}/configs/cp/nginx/subdom.conf -O /etc/nginx/conf.d/SITES_ENABLED/subdom.conf 30 | sudo /etc/init.d/nginx reload 31 | 32 | - if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")): 33 | - if ('${globals.MODE}' == 'subdir'): 34 | cmd[${nodes.cp.master.id}]: |- 35 | wget ${baseUrl}/configs/cp/litespeed/.htaccess_subdir -O /tmp/.htaccess_wpmu 36 | 37 | - if ('${globals.MODE}' == 'subdom'): 38 | cmd[${nodes.cp.master.id}]: |- 39 | wget ${baseUrl}/configs/cp/litespeed/.htaccess_subdom -O /tmp/.htaccess_wpmu 40 | 41 | - cmd[${nodes.cp.master.id}]: |- 42 | cat /tmp/.htaccess_wpmu >> /var/www/webroot/ROOT/.htaccess 43 | wget ${baseUrl}/scripts/setupWP.sh?_r=${fn.random} -O ~/setupWP.sh &>> /var/log/run.log 44 | bash ~/setupWP.sh --wpmu true --MODE ${settings.mode} 45 | 46 | -------------------------------------------------------------------------------- /addon/edgeportCDN.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | jpsVersion: '1.1' 3 | name: Addon for EdgePort CDN 4 | description: Addon for EdgePort CDN 5 | baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-master/master 6 | 7 | onInstall: 8 | - install-edgeport-CDN 9 | - configure-edgeport-CDN 10 | 11 | actions: 12 | install-edgeport-CDN: 13 | - install: https://raw.githubusercontent.com/edgeport/cdn/master/manifest.yml?_r=${fn.random} 14 | 15 | configure-edgeport-CDN: 16 | - script: return jelastic.dev.scripting.Eval("c05ffa5b45628a2a0c95467ebca8a0b4", session, "cdn.info", {partnerCode:1}) 17 | - cmd[${nodes.cp.master.id}]: |- 18 | wget ${baseUrl}/scripts/setupWP.sh?_r=${fn.random} -O ~/setupWP.sh &>> /var/log/run.log 19 | bash ~/setupWP.sh --edgeportCDN true --CDN_URL ${env.envName}-${response.response.partnerCode}.cdn.edgeport.net 20 | -------------------------------------------------------------------------------- /addon/multisites.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | jpsVersion: '1.1' 3 | name: Multisites addon for WordPress cluster 4 | description: Multisites addon for WordPress cluster 5 | logo: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/images/wp-cluster.png 6 | baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master 7 | settings: 8 | main: 9 | fields: 10 | - name: mode 11 | caption: Multisites mode 12 | type: radio-fieldset 13 | values: 14 | subdir: SubDirectories 15 | subdom: SubDomain 16 | default: subdir 17 | 18 | globals: 19 | MODE: ${settings.mode} 20 | 21 | onInstall: 22 | - if (/lemp/.test("${nodes.cp.nodeType}") || /nginxphp/.test("${nodes.cp.nodeType}")): 23 | - if ('${globals.MODE}' == 'subdir'): 24 | cmd[${nodes.cp.master.id}]: |- 25 | wget ${baseUrl}/configs/cp/nginx/subdir.conf -O /etc/nginx/conf.d/SITES_ENABLED/subdir.conf 26 | sudo /etc/init.d/nginx reload 27 | - if ('${globals.MODE}' == 'subdom'): 28 | cmd[${nodes.cp.master.id}]: |- 29 | wget ${baseUrl}/configs/cp/nginx/subdom.conf -O /etc/nginx/conf.d/SITES_ENABLED/subdom.conf 30 | sudo /etc/init.d/nginx reload 31 | 32 | - if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")): 33 | - if ('${globals.MODE}' == 'subdir'): 34 | cmd[${nodes.cp.master.id}]: |- 35 | wget ${baseUrl}/configs/cp/litespeed/.htaccess_subdir -O /tmp/.htaccess_wpmu 36 | 37 | - if ('${globals.MODE}' == 'subdom'): 38 | cmd[${nodes.cp.master.id}]: |- 39 | wget ${baseUrl}/configs/cp/litespeed/.htaccess_subdom -O /tmp/.htaccess_wpmu 40 | 41 | - cmd[${nodes.cp.master.id}]: |- 42 | cat /tmp/.htaccess_wpmu >> /var/www/webroot/ROOT/.htaccess 43 | wget ${baseUrl}/scripts/setupWP.sh?_r=${fn.random} -O ~/setupWP.sh &>> /var/log/run.log 44 | bash ~/setupWP.sh --wpmu true --MODE ${settings.mode} 45 | 46 | -------------------------------------------------------------------------------- /addon/myisam2innodb.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | jpsVersion: '1.1' 3 | id: myisam2innodb 4 | name: WordPress MyISAM to InnoDB converter 5 | 6 | onInstall: 7 | - forEach(nodes.sqldb): 8 | - cmd[${nodes.cp.master.id}]: |- 9 | rm -f /tmp/dump-node${@i.id}.sql 10 | ~/bin/wp config set DB_HOST node${@i.id} --path=${SERVER_WEBROOT} 11 | ~/bin/wp db export /tmp/dump-node${@i.id}.sql --path=${SERVER_WEBROOT} 12 | 13 | - cmd[${nodes.cp.master.id}]: |- 14 | mv $(ls -S /tmp/dump* | head -n 1) /tmp/dump.sql 15 | sed 's/ENGINE=MyISAM/ENGINE=InnoDB/g' /tmp/dump.sql > /tmp/dump-innodb.sql 16 | ~/bin/wp db import /tmp/dump-innodb.sql --path=${SERVER_WEBROOT} 17 | ~/bin/wp config set DB_HOST sqldb --path=${SERVER_WEBROOT} 18 | -------------------------------------------------------------------------------- /configs/autotest.yaml: -------------------------------------------------------------------------------- 1 | jps: https://github.com/jelastic-jps/wordpress-cluster/blob/v2.0.0/manifest.jps 2 | component: wordpress 3 | stack: 4 | - nodeType: litespeedadc 5 | tagSetting: bl_tag 6 | optimization: true 7 | options: 8 | - ls_addon: true 9 | wp_protect: true 10 | waf: true 11 | - nodeType: litespeedphp 12 | tagSetting: cp_tag 13 | optimization: true 14 | options: 15 | - ls_addon: true 16 | wp_protect: true 17 | waf: true 18 | - nodeType: nginx 19 | tagSetting: bl_tag 20 | options: 21 | - ls_addon: false 22 | - nodeType: nginxphp 23 | tagSetting: cp_tag 24 | optimization: true 25 | options: 26 | - ls_addon: false 27 | - nodeType: mariadb 28 | tagSetting: sqldb_tag 29 | options: 30 | - galera: true 31 | - galera: false 32 | - nodeType: storage 33 | tagSetting: storage_tag 34 | options: 35 | - glusterfs: false 36 | - glusterfs: true 37 | -------------------------------------------------------------------------------- /configs/cp/litespeed/.htaccess_basic: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /configs/cp/litespeed/.htaccess_subdir: -------------------------------------------------------------------------------- 1 | # BEGIN WordPress in the network (subdirectory) 2 | 3 | RewriteEngine On 4 | RewriteBase / 5 | RewriteRule ^index\.php$ - [L] 6 | 7 | # add a trailing slash to /wp-admin 8 | RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] 9 | 10 | RewriteCond %{REQUEST_FILENAME} -f [OR] 11 | RewriteCond %{REQUEST_FILENAME} -d 12 | RewriteRule ^ - [L] 13 | RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L] 14 | RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L] 15 | RewriteRule . index.php [L] 16 | 17 | # END WordPress 18 | -------------------------------------------------------------------------------- /configs/cp/litespeed/.htaccess_subdom: -------------------------------------------------------------------------------- 1 | # BEGIN WordPress in the network (subdomains) 2 | 3 | RewriteEngine On 4 | RewriteBase / 5 | RewriteRule ^index\.php$ - [L] 6 | 7 | # add a trailing slash to /wp-admin 8 | RewriteRule ^wp-admin$ wp-admin/ [R=301,L] 9 | 10 | RewriteCond %{REQUEST_FILENAME} -f [OR] 11 | RewriteCond %{REQUEST_FILENAME} -d 12 | RewriteRule ^ - [L] 13 | RewriteRule ^(wp-(content|admin|includes).*) $1 [L] 14 | RewriteRule ^(.*\.php)$ $1 [L] 15 | RewriteRule . index.php [L] 16 | 17 | # END WordPress 18 | -------------------------------------------------------------------------------- /configs/cp/nginx/subdir.conf: -------------------------------------------------------------------------------- 1 | # WordPress multisite subdirectory rules. 2 | # Designed to be included in any server {} block. 3 | location ~ ^(/[^/]+/)?files/(.+) { 4 | try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ; 5 | access_log off; log_not_found off; expires max; 6 | } 7 | 8 | #avoid php readfile() 9 | location ^~ /blogs.dir { 10 | internal; 11 | alias /var/www/webroot/ROOT/wp-content/blogs.dir ; 12 | access_log off; log_not_found off; expires max; 13 | } 14 | 15 | if (!-e $request_filename) { 16 | # Don't use `$uri` here, see https://github.com/yandex/gixy/issues/77 17 | rewrite /wp-admin$ $scheme://$host$request_uri/ permanent; 18 | rewrite ^(/[^/]+)?(/wp-.*) $2 last; 19 | rewrite ^(/[^/]+)?(/.*\.php) $2 last; 20 | } 21 | 22 | #add some rules for static content expiry-headers here 23 | -------------------------------------------------------------------------------- /configs/cp/nginx/subdom.conf: -------------------------------------------------------------------------------- 1 | #WPMU Files 2 | location ~ ^/files/(.*)$ { 3 | try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1 ; 4 | access_log off; log_not_found off; expires max; 5 | } 6 | 7 | #WPMU x-sendfile to avoid php readfile() 8 | location ^~ /blogs.dir { 9 | internal; 10 | alias /var/www/webroot/ROOT/wp-content/blogs.dir; 11 | access_log off; log_not_found off; expires max; 12 | } 13 | 14 | #add some rules for static content expiry-headers here 15 | -------------------------------------------------------------------------------- /configs/deps.yaml: -------------------------------------------------------------------------------- 1 | templates: 2 | litespeed: 3 | - ^litespeed 4 | litespeedadc: 5 | - ^litespeedadc 6 | mariadb: 7 | - ^mariadb10 8 | nginxbalancer: 9 | - ^nginxbalancer 10 | nginxphp: 11 | - ^nginxphp 12 | storage: 13 | - ^storage 14 | -------------------------------------------------------------------------------- /configs/lb/litespeed/jelastic.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1 6 | 7 | 8 | 9 | 0 10 | 10 11 | 12 | 13 | 14 | /tmp/lscache/vhosts/$VH_NAME 15 | 0 16 | 17 | 18 | 1 19 | 1 20 | 15 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /configs/settings.yaml: -------------------------------------------------------------------------------- 1 | fields: 2 | - caption: Scaling Strategy 3 | type: list 4 | name: loadGrowth 5 | default: slow 6 | required: true 7 | width: 225 8 | tooltip: | 9 | Configure auto-scaling triggers, i.e. how fast the system responds to load spikes by adding or removing nodes. 10 |

Read more about Automatic Horizontal Scaling

11 | values: 12 | - value: slow 13 | caption: Low Load 14 | tooltip:

Low load scaling strategy

add 1 new node when CPU > 70%

remove when CPU < 20%

15 | - value: medium 16 | caption: Medium Load 17 | tooltip:

Medium load scaling strategy

add 1 new node when CPU > 50%

remove when CPU < 20%

18 | - value: fast 19 | caption: High Load 20 | tooltip:

High load scaling strategy

add 2 new nodes when CPU > 30%

remove when CPU < 10%

21 | 22 | - caption: Advanced Features 23 | type: displayfield 24 | name: displayfield 25 | markup: 26 | -------------------------------------------------------------------------------- /configs/sqldb/wordpress.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | 3 | # Duplicate entry '_transient_doing_cron' for key 'option_name', Error_code: 1062; 4 | slave-skip-errors = 1062 5 | 6 | max_connections=500 7 | join_buffer_size = 3M 8 | tmp_table_size = 128M 9 | max_heap_table_size = 128M 10 | thread_cache_size = 16K 11 | table_definition_cache = 4K 12 | open_files_limit = 524290 13 | local-infile=0 14 | sync_binlog = 0 15 | query_cache_size = 0 16 | innodb_log_file_size = 128M 17 | wsrep_slave_threads = 16 18 | innodb_flush_log_at_trx_commit = 2 19 | -------------------------------------------------------------------------------- /configs/vers.yaml: -------------------------------------------------------------------------------- 1 | globals: 2 | version_w3total: 2.8.8 3 | version_lscache: 7.0.1 4 | version_woocommerce: 9.8.2 5 | version_wordpress: 6.8 6 | -------------------------------------------------------------------------------- /configs/wordpress/wp-jelastic.php: -------------------------------------------------------------------------------- 1 | geo clusters 2 | -------------------------------------------------------------------------------- /images/deploy-to-jelastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/deploy-to-jelastic.png -------------------------------------------------------------------------------- /images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/favicon.ico -------------------------------------------------------------------------------- /images/install-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/install-new.png -------------------------------------------------------------------------------- /images/patch-install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/patch-install.png -------------------------------------------------------------------------------- /images/patch-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/patch-logo.png -------------------------------------------------------------------------------- /images/patch-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/patch-success.png -------------------------------------------------------------------------------- /images/single-cluster-topology-storage-scaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/single-cluster-topology-storage-scaling.png -------------------------------------------------------------------------------- /images/single-cluster-topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/single-cluster-topology.png -------------------------------------------------------------------------------- /images/standalone.svg: -------------------------------------------------------------------------------- 1 | geo clusters_1 2 | -------------------------------------------------------------------------------- /images/success-wordpress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/success-wordpress.png -------------------------------------------------------------------------------- /images/woo_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/woo_logo.png -------------------------------------------------------------------------------- /images/wordpress-multisite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wordpress-multisite.png -------------------------------------------------------------------------------- /images/wp-cluster-business.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-cluster-business.png -------------------------------------------------------------------------------- /images/wp-cluster-enterprise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-cluster-enterprise.png -------------------------------------------------------------------------------- /images/wp-cluster-installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-cluster-installation.png -------------------------------------------------------------------------------- /images/wp-cluster-installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-cluster-installed.png -------------------------------------------------------------------------------- /images/wp-cluster-kit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-cluster-kit.png -------------------------------------------------------------------------------- /images/wp-cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-cluster.png -------------------------------------------------------------------------------- /images/wp-standalone-pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-standalone-pro.png -------------------------------------------------------------------------------- /images/wp-standalone-starter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp-standalone-starter.png -------------------------------------------------------------------------------- /images/wp_logo.svg: -------------------------------------------------------------------------------- 1 | WP_logo -------------------------------------------------------------------------------- /images/wp_logo_70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/images/wp_logo_70.png -------------------------------------------------------------------------------- /manifest.jps: -------------------------------------------------------------------------------- 1 | type: install 2 | jpsVersion: '1.7.2' 3 | name: WordPress Cluster Kit v2 4 | id: wordpress-cluster 5 | categories: 6 | - apps/clusters 7 | - apps/content-management 8 | description: 9 | text: WordPress Cluster Kit with highly available Load Balancer and Shared Storage with GlusterFS, database clustering, and scaling mode to create an optimal environment for highly-loaded projects. The package provides integrated autoscaling and high availability for development and production environments. Clustered topology ensures effective handling of heavy workload. 10 | short: WordPress Cluster with built-in kit v2 for choosing optimal servers, database clustering type, scaling mode and a set of advanced features for highly-loaded projects 11 | logo: /images/wp-cluster-kit.svg 12 | 13 | baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/v2.2.0 14 | 15 | onBeforeInit: /scripts/beforeInit.js?_r=${fn.random} 16 | onBeforeInstall: /scripts/beforeInstall.js?_r=${fn.random} 17 | 18 | skipNodeEmails: true 19 | nodes: definedInOnBeforeInstall 20 | 21 | settings: 22 | fields: 23 | - caption: Scaling Strategy 24 | type: list 25 | name: loadGrowth 26 | default: slow 27 | required: true 28 | width: 225 29 | tooltip: | 30 | Configure auto-scaling triggers, i.e. how fast the system responds to load spikes by adding or removing nodes. 31 |

Read more about Automatic Horizontal Scaling

32 | values: 33 | - value: slow 34 | caption: Low Load 35 | tooltip:

Low load scaling strategy

add 1 new node when CPU > 70%

remove when CPU < 20%

36 | - value: medium 37 | caption: Medium Load 38 | tooltip:

Medium load scaling strategy

add 1 new node when CPU > 50%

remove when CPU < 20%

39 | - value: fast 40 | caption: High Load 41 | tooltip:

High load scaling strategy

add 2 new nodes when CPU > 30%

remove when CPU < 10%

42 | 43 | - caption: Advanced Features 44 | type: displayfield 45 | name: displayfield 46 | markup: 47 | 48 | - caption: Install LiteSpeed High-Performance Web Server 49 | type: checkbox 50 | name: ls-addon 51 | value: true 52 | disabled: false 53 | tooltip: "If this option is disabled, the cluster will be installed using NGINX load balancer and application servers" 54 | showIf: 55 | true: 56 | - caption: WordPress Brute Force Attack Protection 57 | type: checkbox 58 | name: wp_protect 59 | value: true 60 | disabled: false 61 | tooltip: "Secure WordPress Admin Panel with LiteSpeed Brute Force Protection that limits failed login attempts. Default action is Throttle and number of allowed attempts is 100" 62 | 63 | - caption: Web Application Firewall 64 | type: checkbox 65 | name: waf 66 | value: true 67 | disabled: false 68 | tooltip: "Protect web sites with LiteSpeed built-in WAF based on Free ModSecurity Rules from Comodo" 69 | 70 | false: 71 | - caption: WordPress Brute Force Attack Protection 72 | type: checkbox 73 | name: wp_protect 74 | value: false 75 | disabled: true 76 | tooltip: "Secure WordPress Admin Panel with LiteSpeed Brute Force Protection that limits failed login attempts. Default action is Throttle and number of allowed attempts is 100" 77 | 78 | - caption: Web Application Firewall 79 | type: checkbox 80 | name: waf 81 | value: false 82 | disabled: true 83 | tooltip: "Protect web sites with LiteSpeed built-in WAF based on Free ModSecurity Rules from Comodo" 84 | 85 | - caption: Install MariaDB Galera Cluster 86 | type: checkbox 87 | name: galera 88 | value: true 89 | disabled: false 90 | tooltip: "

Requirements for All Tables:

* run on InnoDB storage engine

* have a primary key

Read more about limitations" 91 | 92 | - caption: Install Let's Encrypt SSL with Auto-Renewal 93 | type: checkbox 94 | name: le-addon 95 | value: true 96 | disabled: false 97 | tooltip: "Advanced integration with Let's Encrypt certificate authority that simplifies and automates the process of issuing, configuring and updating trusted custom SSL certificates." 98 | 99 | - caption: Install Lightning-Fast Premium CDN 100 | type: checkbox 101 | name: cdn-addon 102 | value: true 103 | disabled: false 104 | tooltip: "Jelastic CDN is an HTTP/3 premium content delivery network of 160+ Super PoPs (points of presence) with bandwidth capacity up to 115 Tbps, advanced caching and acceleration strategies based on best-in-class IP Anycast technology." 105 | 106 | - caption: 'Install GlusterFS Cluster' 107 | type: checkbox 108 | name: glusterfs 109 | value: false 110 | disabled: false 111 | tooltip: "Shared Storage auto-clustering is based on GlusterFS software that provides a fault-tolerant distributed file system with automatic data synchronization across the cluster nodes." 112 | 113 | - caption: Install WordPress Multisite Network 114 | type: checkbox 115 | name: mu-addon 116 | value: false 117 | disabled: false 118 | tooltip: "Multisite is a type of WordPress installation that allows you to create and manage a network of multiple websites from a single WordPress dashboard. This lets you easily make changes and keep all of your websites updated from one place." 119 | 120 | - caption: Install WooCommerce 121 | type: checkbox 122 | name: woocommerce 123 | value: false 124 | disabled: false 125 | tooltip: "WooCommerce is a free open-source e-commerce plugin designed specifically for WordPress. This is a great platform for a store of any size." 126 | 127 | - type: displayfield 128 | hideLabel: true 129 | hidden: true 130 | name: bl_count 131 | value: 2 132 | markup: 133 | 134 | mixins: 135 | - https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/configs/vers.yaml 136 | 137 | globals: 138 | PATH: ${baseUrl} 139 | DB_USER: ${settings.DB_USER:user-[fn.random]} 140 | DB_PASS: ${settings.DB_PASS:[fn.password(10)]} 141 | DB_HOST: sqldb 142 | PROTOCOL: http 143 | WP_ADMIN_PASS: ${settings.WP_ADMIN_PASS:[fn.password(10)]} 144 | LS_ADMIN_PASS: ${settings.LS_ADMIN_PASS:[fn.password(10)]} 145 | SUCCESS: default 146 | 147 | onInstall: 148 | 149 | - limits 150 | - setProtocol 151 | - setDomain 152 | - initLEsettings 153 | - if (${settings.is_trigger:true}): setTriggers 154 | - optimization 155 | - setupCacheSync 156 | - storageHealthCheck 157 | - storageMount: NFS4 158 | - if (/litespeed/.test("${nodes.cp.nodeType}")): setPassword 159 | - getRedisPswd 160 | - installWordpress 161 | - if ('${settings.mu-addon:false}' == 'true'): configureMultisite 162 | - if (${settings.woocommerce:false}): installWoocommerce 163 | - if (('${settings.le-addon:false}' == 'true') || ('${settings.cdn-addon:false}' == 'true')): 164 | - script: | 165 | var actions = []; 166 | if ('${settings.le-addon:false}' == 'true') 167 | actions.push({ 168 | jps: "https://github.com/jelastic-jps/lets-encrypt/blob/master/manifest.jps?_r=${fn.random}?_r=${fn.random}", 169 | nodeGroup: "bl", 170 | skipEmail: "true", 171 | settings: { 172 | customDomains: "${globals.DOMAIN}", 173 | fallbackToX1: "true", 174 | withExtIp: "${globals.isExtIP}" 175 | } 176 | }); 177 | if ('${settings.cdn-addon:false}' == 'true') 178 | actions.push({ 179 | jps: "https://raw.githubusercontent.com/edgeport/cdn/master/manifest.yml?_r=${fn.random}", 180 | nodeGroup: "bl", 181 | skipEmail: "true", 182 | settings: { 183 | note: "${settings.noteCDN:}" 184 | } 185 | }); 186 | return { result: 0, onAfterReturn: { install: actions } }; 187 | 188 | - if ('${settings.le-addon:false}' == 'true'): setupLEdomain 189 | - if ('${settings.cdn-addon:false}' == 'true'): setupCDN 190 | - install: 191 | - jps: /scripts/cacheClean.jps?_r=${fn.random} 192 | - jps: /scripts/addons.jps?_r=${fn.random} 193 | - jps: /scripts/events.jps?_r=${fn.random} 194 | - if ('${settings.success_email}' != 'false'): 195 | - return: 196 | type: success 197 | message: /success/text/success-${globals.SUCCESS}.md?_r=${fn.random} 198 | email: /success/email/success-${nodes.cp.master.nodeType}-${globals.SUCCESS}.md?_r=${fn.random} 199 | 200 | actions: 201 | 202 | limits: 203 | - env.control.ApplyNodeGroupData[bl,cp,sqldb,storage,nosqldb]: 204 | data: 205 | project: ${settings.project:default} 206 | projectScope: ${settings.projectScope:production} 207 | isRequired: true 208 | 209 | setProtocol: 210 | - script: | 211 | return { 212 | result:0, 213 | ssl: jelastic.billing.account.GetQuotas('environment.jelasticssl.enabled').array[0].value 214 | } 215 | - if (${response.ssl} || ${settings.le-addon:false}): 216 | setGlobals: 217 | PROTOCOL: https 218 | 219 | setDomain: 220 | - script: /scripts/idna.js 221 | domains: ${env.domain} 222 | - setGlobals: 223 | DOMAIN: ${response.domains} 224 | 225 | setTriggers: 226 | - log: Auto Scaling Triggers 227 | - script: /scripts/addTriggers.js 228 | nodeGroup: cp 229 | resourceType: CPU 230 | loadGrowth: ${settings.loadGrowth} 231 | cleanOldTriggers: true 232 | scaleDownLimit: ${nodes.cp.length} 233 | 234 | initLEsettings: 235 | - script: | 236 | return { 237 | result:0, 238 | extIP: Boolean(jelastic.billing.account.GetQuotas('environment.externalip.enabled').array[0].value) 239 | } 240 | - setGlobals: 241 | isExtIP: ${response.extIP} 242 | 243 | - cmd[cp, bl]: |- 244 | [ ! -d /var/lib/jelastic/keys/letsencrypt ] && mkdir -p /var/lib/jelastic/keys/letsencrypt; 245 | echo "webroot=false" > /var/lib/jelastic/keys/letsencrypt/settings-custom; 246 | echo "webrootPath=/var/www/webroot/ROOT" >> /var/lib/jelastic/keys/letsencrypt/settings-custom; 247 | echo "test=false" >> /var/lib/jelastic/keys/letsencrypt/settings-custom; 248 | echo "withExtIp=${globals.isExtIP}" >> /var/lib/jelastic/keys/letsencrypt/settings-custom; 249 | user: root 250 | 251 | setupLEdomain: 252 | - cmd[${nodes.bl.master.id}]: source /opt/letsencrypt/settings && echo $domain 253 | - cmd[${nodes.cp.master.id}]: bash ~/bin/setupWP.sh --url https://${response.out}; 254 | 255 | optimization: 256 | - log: Load Balancers and App servers optimization 257 | - install: 258 | - jps: https://raw.githubusercontent.com/jelastic/templates/master/config_v2.jps?_r=${fn.random} 259 | settings: 260 | targetGroup: bl 261 | targetNodes: bl 262 | optimization: wordpress 263 | - jps: https://raw.githubusercontent.com/jelastic/templates/master/config_v2.jps?_r=${fn.random} 264 | settings: 265 | targetGroup: cp 266 | targetNodes: cp 267 | optimization: wordpress 268 | - cmd[cp, bl]: if test -f /usr/local/sbin/optimization.sh; then bash /usr/local/sbin/optimization.sh &>> /var/log/run.log; fi 269 | 270 | setPassword: 271 | - cmd[cp, bl]: jem passwd set -p ${globals.LS_ADMIN_PASS} 272 | user: root 273 | 274 | storageMount: 275 | - log: Mount Storage 276 | - api: 277 | - method: jelastic.environment.file.AddMountPointByGroup 278 | params: 279 | nodeGroup: cp 280 | sourceNodeId: ${nodes.storage.master.id} 281 | sourcePath: /data 282 | path: /var/www/webroot/ROOT 283 | sourceAddressType: NODE_GROUP 284 | protocol: ${this} 285 | 286 | storageHealthCheck: 287 | - cmd[cp]: |- 288 | echo "" > /var/www/webroot/ROOT/index.php 289 | 290 | setupCDN: 291 | - script: return jelastic.dev.scripting.Eval("c05ffa5b45628a2a0c95467ebca8a0b4", session, "cdn.info", {partnerCode:1}) 292 | - setGlobals: 293 | CDN_URL: ${globals.PROTOCOL}://${env.envName}-${response.response.partnerCode}.cdn.jelastic.net/ 294 | CDN: ${env.envName}-${response.response.partnerCode}.cdn.jelastic.net 295 | SUCCESS: cdn 296 | - install: /scripts/setupCDN.jps 297 | 298 | configureMultisite: 299 | - install: /addons/multisite.jps 300 | 301 | getRedisPswd: 302 | - cmd[nosqldb]: cat /etc/redis.conf | tail -1 | awk '{print $2}'; 303 | - setGlobals: 304 | REDIS_PSWD: ${response.out} 305 | 306 | installWordpress: 307 | - install: /scripts/installWP.jps 308 | settings: 309 | db_host: ${globals.DB_HOST} 310 | db_user: ${globals.DB_USER} 311 | db_pass: ${globals.DB_PASS} 312 | redis_host: nosqldb 313 | redis_port: 6379 314 | redis_user: admin 315 | redis_pswd: ${globals.REDIS_PSWD} 316 | wp_admin_pass: ${globals.WP_ADMIN_PASS} 317 | wp_title: "Hello World" 318 | wp_url: ${globals.PROTOCOL}://${globals.DOMAIN}/ 319 | version_wordpress: ${globals.version_wordpress} 320 | 321 | setupCacheSync: 322 | - if (/litespeed/.test("${nodes.bl.nodeType}")): 323 | - install: /scripts/setupHA4LB.jps?_r=${fn.random} 324 | 325 | updateTriggers: 326 | if (!${event.params.auto:true}): 327 | - log: update scaling trigger 328 | - script: /scripts/updateTriggers.js 329 | count: ${nodes.cp.length} 330 | 331 | installWoocommerce: 332 | cmd[${nodes.cp.master.id}]: |- 333 | wp plugin install woocommerce --version=${globals.version_woocommerce} --activate --path=${SERVER_WEBROOT} &>> /var/log/run.log; 334 | 335 | -------------------------------------------------------------------------------- /patch/loadOptimization/README.md: -------------------------------------------------------------------------------- 1 | ## WordPress Cluster Load Performance Optimization 2 | 3 | This add-on is designed to increase the performance of existing WordPress Clusters based on LiteSpeed Web Server and Load Balancer stack templates. 4 | It is achieved via optimization those settings that make the most influence on cluster load: 5 | - moving Brute Force Attack Protection from backend server to Load Balancer thus web sever doesn't bear extra load by handling brute force requests 6 | - caching static assets at Load Balancer layer 7 | - changing balancing strategy 8 | - keeping the LSCache plugin up-to-date 9 | - disabling GZIP compression 10 | - reducing the number of database disk write operations 11 | 12 | Settings to be optimized on: 13 | 14 | **LiteSpeed ADC (Load Balancer)** 15 | 16 | - enables [WordPress Brute Force Attack Protection](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:config:wordpress-protection 17 | ) with parameteres: 18 | * WP_PROTECT_ACTION: 3 19 | * WP_PROTECT_LIMIT: 100 20 | 21 | - enables static content [caching](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:webadc) at the load balancer thus tremendously increasing static assets output speed 22 | 23 | - permits up 150 connections to be handled simultaneously through the *Max Connection* parameter for each of backend server(Worker Group node). Here the maximum number of concurrent connections is that can be established between the server and an external application 24 | 25 | - sets up *Balancing strategy* as [Fastest Response](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:lslb:basic_config). The Fastest Response algorithm chooses the Worker Group node that responds the fastest to a backend worker ping. 26 | 27 | **LiteSpeed Web Server(backend server)** 28 | 29 | - disables WordPress *Brute Force Attack Protection* since it was shouldered on the load balancer 30 | - disables GZIP compression decreasing CPU load on backend 31 | - updates LSCache plugin to the latest plugin version. 32 | 33 | **DataBase** 34 | - it turns *innodb_flush_log_at_trx_commit* = 2. When the value is 2, the log buffer is written out to the file at each commit, but the flush to disk operation is not performed on it and it is done once per second. So it gets a very fast write speed. 35 | 36 | ## Deployment to the Cloud 37 | 38 | Click the **Deploy** button below, specify your email address within the widget, choose one of the [Jelastic Public Cloud providers](https://jelastic.com/install-application/?manifest=https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/patch/loadOptimization/optimization.jps&keys=app.jelastic.elastx.net;app.milesweb.cloud;app.jelastic.eapps.com;app.jelastic.saveincloud.net&filter=auto_cluster) and press **Install**. 39 | 40 | [![Deploy to Jelastic](https://github.com/jelastic-jps/git-push-deploy/raw/master/images/deploy-to-jelastic.png)](https://jelastic.com/install-application/?manifest=https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/patch/loadOptimization/optimization.jps&keys=app.jelastic.elastx.net;app.milesweb.cloud;app.jelastic.eapps.com;app.jelastic.saveincloud.net&filter=auto_cluster) 41 | 42 | > **Note:** If you are already registered at Jelastic, you can deploy this cluster by importing the [the package manifest raw link](https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/patch/loadOptimization/optimization.jps) within the dashboard. 43 | 44 | ## Installation Process 45 | 46 | In the opened confirmation window at Jelastic dashboard choose the WordPress cluster to be optimized: 47 | 48 |

49 | 50 |

51 | 52 | An appropriate pop-up will appear upon successfull patch installation. 53 | 54 |

55 | 56 |

57 | 58 | Congratulations! Now your WordPress cluster is ready for heavy load. 59 | -------------------------------------------------------------------------------- /patch/loadOptimization/configs/LSADC_vhost.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1 6 | 7 | 8 | 9 | 0 10 | 10 11 | 12 | 13 | 14 | /tmp/lscache/vhosts/$VH_NAME 15 | 0 16 | 17 | 18 | 1 19 | 1 20 | 15 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /patch/loadOptimization/optimization.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | jpsVersion: '1.1' 3 | id: wp-cluster-optimization 4 | name: WordPress Cluster Load Performance Optimization 5 | description: Increase WordPress performance for the Clusters based on LiteSpeed Software with optimization of load distribution and caching, and database fine tuning. 6 | logo: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master/images/patch-logo.png 7 | baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master 8 | 9 | globals: 10 | WP_PROTECT_ACTION: 3 11 | WP_PROTECT_LIMIT: 100 12 | 13 | onInstall: 14 | - log: LiteSpeed ADC optimization 15 | - cmd[bl]: |- 16 | sed -i 's/^WP_PROTECT=.*/WP_PROTECT=DENY/g' /.jelenv; 17 | sed -i 's/^WP_PROTECT_LIMIT=.*/WP_PROTECT_LIMIT=${globals.WP_PROTECT_LIMIT}/g' /.jelenv; 18 | user: root 19 | 20 | - cmd[bl]: |- 21 | wget ${baseUrl}/patch/loadOptimization/configs/LSADC_vhost.xml -O /var/www/conf/jelastic.xml; 22 | wget ${baseUrl}/patch/loadOptimization/scripts/LSADC.sh -O ~/LSADC.sh; 23 | bash ~/LSADC.sh; 24 | 25 | - log: LiteSpeed WEB optimization 26 | - cmd[${nodes.cp.master.id}]: |- 27 | wp plugin update litespeed-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log; 28 | 29 | - forEach(nodes.cp): 30 | - cmd[${@i.id}]: sed -i 's/^WP_PROTECT=.*/WP_PROTECT=OFF/g' /.jelenv; 31 | user: root 32 | 33 | - cmd[${@i.id}]: |- 34 | wget ${baseUrl}/patch/loadOptimization/scripts/LSWEB.sh -O ~/LSWEB.sh; 35 | bash ~/LSWEB.sh; 36 | cd /var/www/webroot/ROOT; wp cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log; 37 | cd /var/www/webroot/ROOT; wp lscache-purge all --path=${SERVER_WEBROOT} &>> /var/log/run.log; 38 | 39 | - log: DataBase optimization 40 | - forEach(nodes.sqldb): 41 | - cmd[${@i.id}]: wget ${baseUrl}/configs/sqldb/wordpress.cnf -O /etc/mysql/conf.d/wordpress.cnf 42 | - cmd[${@i.id}]: |- 43 | wget ${baseUrl}/patch/loadOptimization/scripts/DB.sh -O ~/DB.sh; 44 | bash ~/DB.sh; 45 | user: root 46 | -------------------------------------------------------------------------------- /patch/loadOptimization/scripts/DB.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp -f /etc/my.cnf /etc/my.cnf.backup.$(date +%d-%m-%Y.%H:%M:%S.%N) || exit 1 4 | 5 | sed -i '/innodb_flush_log_at_trx_commit/d' /etc/my.cnf 6 | sed -i '/\[mysqld\]/a innodb_flush_log_at_trx_commit = 2' /etc/my.cnf 7 | 8 | cp -f /etc/jelastic/redeploy.conf /etc/jelastic/redeploy.conf.$(date +%d-%m-%Y.%H:%M:%S.%N) || exit 1 9 | 10 | sed -i '/\/etc\/mysql\/conf.d/d' /etc/jelastic/redeploy.conf 11 | echo "/etc/mysql/conf.d" >> /etc/jelastic/redeploy.conf 12 | 13 | sudo service mysql restart; 14 | -------------------------------------------------------------------------------- /patch/loadOptimization/scripts/LSADC.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | LSLB_CONF="/var/www/conf/lslbd_config.xml" 4 | VH_CONF="/var/www/conf/jelastic.xml" 5 | ED_CMD="ed --inplace" 6 | 7 | WP_PROTECT_ACTION=3 8 | WP_PROTECT_LIMIT=100 9 | 10 | cp -f ${LSLB_CONF} ${LSLB_CONF}.backup.$(date +%d-%m-%Y.%H:%M:%S.%N) || exit 1 11 | 12 | #Wordpress Brute Force Attacks Protect 13 | /usr/bin/xmlstarlet ${ED_CMD} -d "loadBalancerConfig/security/wpProtectAction" "${LSLB_CONF}" 2>/dev/null; 14 | /usr/bin/xmlstarlet ${ED_CMD} -d "loadBalancerConfig/security/wpProtectLimit" "${LSLB_CONF}" 2>/dev/null; 15 | /usr/bin/xmlstarlet ${ED_CMD} -d "virtualHostConfig/security/wpProtectAction" "${VH_CONF}" 2>/dev/null; 16 | /usr/bin/xmlstarlet ${ED_CMD} -d "virtualHostConfig/security/wpProtectLimit" "${VH_CONF}" 2>/dev/null; 17 | /usr/bin/xmlstarlet ${ED_CMD} -s "loadBalancerConfig/security" -t elem -n "wpProtectLimit" -v "${WP_PROTECT_LIMIT}" "${LSLB_CONF}" 2>/dev/null; 18 | /usr/bin/xmlstarlet ${ED_CMD} -s "loadBalancerConfig/security" -t elem -n "wpProtectAction" -v "${WP_PROTECT_ACTION}" "${LSLB_CONF}" 2>/dev/null; 19 | /usr/bin/xmlstarlet ${ED_CMD} -s "virtualHostConfig/security" -t elem -n "wpProtectLimit" -v "${WP_PROTECT_LIMIT}" "${VH_CONF}" 2>/dev/null; 20 | /usr/bin/xmlstarlet ${ED_CMD} -s "virtualHostConfig/security" -t elem -n "wpProtectAction" -v "${WP_PROTECT_ACTION}" "${VH_CONF}" 2>/dev/null; 21 | 22 | #Load Balancer Optimization 23 | /usr/bin/xmlstarlet ${ED_CMD} -u "loadBalancerConfig/loadBalancerList/loadBalancer[name = "*"]/workerGroupList/workerGroup[name = "*"]/maxConns" -v "150" "${LSLB_CONF}" 2>/dev/null; 24 | /usr/bin/xmlstarlet ${ED_CMD} -u "loadBalancerConfig/loadBalancerList/loadBalancer[name = "*"]/workerGroupList/workerGroup[name = "*"]/retryTimeout" -v "5" "${LSLB_CONF}" 2>/dev/null; 25 | /usr/bin/xmlstarlet ${ED_CMD} -u "loadBalancerConfig/loadBalancerList/loadBalancer[name = "*"]/workerGroupList/workerGroup/pingInterval" -v "1" "${LSLB_CONF}" 2>/dev/null; 26 | /usr/bin/xmlstarlet ${ED_CMD} -u "loadBalancerConfig/loadBalancerList/loadBalancer[name = "*"]/strategy" -v "3" "${LSLB_CONF}" 2>/dev/null; 27 | 28 | sudo service lslb reload 29 | -------------------------------------------------------------------------------- /patch/loadOptimization/scripts/LSWEB.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEFAULT_LSWS_CONFIG="/var/www/conf/httpd_config.xml" 4 | DEFAULT_VIRTUALHOST_CONFIG="/var/www/webroot/vhconf.xml" 5 | PHPMYADMIN_VIRTUALHOST_CONFIG="/usr/share/phpMyAdmin/vhost.conf" 6 | ED_CMD="ed --inplace" 7 | 8 | cp -f "${DEFAULT_LSWS_CONFIG}" ${DEFAULT_LSWS_CONFIG}.backup.$(date +%d-%m-%Y.%H:%M:%S.%N) || exit 1 9 | cp -f "${DEFAULT_VIRTUALHOST_CONFIG}" ${DEFAULT_VIRTUALHOST_CONFIG}.backup.$(date +%d-%m-%Y.%H:%M:%S.%N) || exit 1 10 | [ -f "${PHPMYADMIN_VIRTUALHOST_CONFIG}" ] && { cp -f "${PHPMYADMIN_VIRTUALHOST_CONFIG}" ${PHPMYADMIN_VIRTUALHOST_CONFIG}.backup.$(date +%d-%m-%Y.%H:%M:%S.%N) || exit 1; } 11 | 12 | if [ -e ${DEFAULT_LSWS_CONFIG} ]; then 13 | /usr/bin/xmlstarlet $ED_CMD -d "httpServerConfig/security/wpProtectAction" ${DEFAULT_LSWS_CONFIG} 2>&1; 14 | /usr/bin/xmlstarlet $ED_CMD -s "httpServerConfig/security" -t elem -n "wpProtectAction" -v "0" ${DEFAULT_LSWS_CONFIG} 2>&1; 15 | /usr/bin/xmlstarlet $ED_CMD -u "httpServerConfig/tuning/enableGzipCompress" -v "0" ${DEFAULT_LSWS_CONFIG} 2>&1; 16 | fi 17 | for i in ${DEFAULT_VIRTUALHOST_CONFIG} ${PHPMYADMIN_VIRTUALHOST_CONFIG} 18 | do 19 | if [ -e ${i} ]; then 20 | /usr/bin/xmlstarlet $ED_CMD -d "virtualHostConfig/security/wpProtectAction" ${i} 2>&1; 21 | /usr/bin/xmlstarlet $ED_CMD -s "virtualHostConfig/security" -t elem -n "wpProtectAction" -v "0" ${i} 2>&1; 22 | fi 23 | done 24 | 25 | sudo service lsws reload 26 | -------------------------------------------------------------------------------- /patch/lscache_v3.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | jpsVersion: '1.1' 3 | id: wp-lscacher-v3 4 | name: Patch for LSCACHE V3 5 | description: Patch for LSCACHE V3 6 | baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master 7 | 8 | onInstall: 9 | - script: return jelastic.dev.scripting.Eval("c05ffa5b45628a2a0c95467ebca8a0b4", session, "cdn.info", {partnerCode:1}) 10 | - setGlobals: 11 | CDN: ${env.envName}-${response.response.partnerCode}.cdn.edgeport.net 12 | - cmd[${nodes.cp.master.id}]: |- 13 | wget ${baseUrl}/scripts/setupWP.sh?_r=${fn.random} -O ~/bin/setupWP.sh &>> /var/log/run.log 14 | bash ~/bin/setupWP.sh --pgcache true --objectcache true --REDIS_HOST 127.0.0.1 --edgeportCDN true --CDN_URL ${globals.CDN} 15 | 16 | -------------------------------------------------------------------------------- /patch/setupWP.sh: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | name: WP script deploy 3 | baseUrl: https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/v2.0.0/scripts 4 | onInstall: 5 | - cmd[${nodes.cp.master.id}]: |- 6 | [ ! -d $HOME/bin ] && mkdir $HOME/bin 7 | curl -o $HOME/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x $HOME/bin/wp 8 | echo "export PATH=$PATH:$HOME/bin/" >> $HOME/.bash_profile 9 | wget ${baseUrl}/setupWP.sh?_r=${fn.random} -O ~/bin/setupWP.sh &>> /var/log/run.log 10 | echo $HOME/bin; 11 | - cmd[${nodes.cp.master.id}]: 12 | echo ${response.out} >> /etc/jelastic/redeploy.conf; 13 | user: root 14 | -------------------------------------------------------------------------------- /scripts/WP-CLI.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | jpsVersion: '1.1' 3 | name: WP-CLI installation 4 | description: WP-CLI installation 5 | globals: 6 | TARGET_NODES: "${settings.TARGET_NODES}" 7 | onInstall: 8 | - cmd[${globals.TARGET_NODES}]: |- 9 | [ ! -d $HOME/bin ] && mkdir $HOME/bin 10 | curl -o $HOME/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x $HOME/bin/wp 11 | echo "export PATH=$PATH:$HOME/bin/" >> $HOME/.bash_profile 12 | wget ${baseUrl}/setupWP.sh?_r=${fn.random} -O ~/bin/setupWP.sh &>> /var/log/run.log 13 | -------------------------------------------------------------------------------- /scripts/addTriggers.js: -------------------------------------------------------------------------------- 1 | //@auth 2 | //@req(nodeGroup, resourceType, cleanOldTriggers, loadGrowth) 3 | 4 | var scaleUpLoadPeriod = 1, 5 | scaleDownLimit = getParam("scaleDownLimit") || 2, 6 | scaleDownLoadPeriod = 5; 7 | 8 | var resp = jelastic.billing.account.GetQuotas('environment.maxsamenodescount'); 9 | if (resp.result != 0) return resp; 10 | var scaleUpLimit = resp.array[0] && resp.array[0].value ? resp.array[0].value : 1000; 11 | 12 | if (scaleUpLimit <= scaleDownLimit) return {result:0, warning: 'autoscaling triggers have not been added due to upLimit ['+scaleUpLimit+'] <= downLimit ['+scaleDownLimit+']'} 13 | 14 | if (loadGrowth.toLowerCase() == "slow") { 15 | var scaleUpValue = 70, 16 | scaleDownValue = 20, 17 | scaleNodeCount = 1; 18 | } 19 | 20 | if (loadGrowth.toLowerCase() == "medium") { 21 | var scaleUpValue = 50, 22 | scaleDownValue = 20, 23 | scaleNodeCount = 1; 24 | } 25 | 26 | if (loadGrowth.toLowerCase() == "fast") { 27 | var scaleUpValue = 30, 28 | scaleDownValue = 10, 29 | scaleNodeCount = 2; 30 | } 31 | 32 | if (cleanOldTriggers) { 33 | var actions = ['ADD_NODE', 'REMOVE_NODE']; 34 | for (var i = 0; i < actions.length; i++){ 35 | var array = jelastic.env.trigger.GetTriggers(appid, session, actions[i]).array; 36 | for (var j = 0; j < array.length; j++) jelastic.env.trigger.DeleteTrigger(appid, session, array[j].id); 37 | } 38 | } 39 | 40 | resp = jelastic.env.trigger.AddTrigger('${env.envName}', session, 41 | { 42 | "isEnabled": true, 43 | "name": "scale-up", 44 | "nodeGroup": nodeGroup, 45 | "period": scaleUpLoadPeriod, 46 | "condition": { 47 | "type": "GREATER", 48 | "value": scaleUpValue, 49 | "resourceType": resourceType, 50 | "valueType": "PERCENTAGES" 51 | }, 52 | "actions": [ 53 | { 54 | "type": "ADD_NODE", 55 | "customData": { 56 | "limit": scaleUpLimit, 57 | "count": scaleNodeCount, 58 | "notify": true 59 | } 60 | } 61 | ] 62 | } 63 | ); 64 | 65 | if (resp.result != 0) return resp; 66 | 67 | resp = jelastic.env.trigger.AddTrigger('${env.envName}', session, 68 | { 69 | "isEnabled": true, 70 | "name": "scale-down", 71 | "nodeGroup": nodeGroup, 72 | "period": scaleDownLoadPeriod, 73 | "condition": { 74 | "type": "LESS", 75 | "value": scaleDownValue, 76 | "resourceType": resourceType, 77 | "valueType": "PERCENTAGES" 78 | }, 79 | "actions": [ 80 | { 81 | "type": "REMOVE_NODE", 82 | "customData": { 83 | "limit": scaleDownLimit, 84 | "count": 1, 85 | "notify": true 86 | } 87 | } 88 | ] 89 | } 90 | ); 91 | 92 | return resp; 93 | -------------------------------------------------------------------------------- /scripts/beforeinstall.js: -------------------------------------------------------------------------------- 1 | var wpbfp = '${settings.wp_protect}' == 'true' ? "THROTTLE" : "OFF"; 2 | 3 | var resp = { 4 | result: 0, 5 | ssl: !!jelastic.billing.account.GetQuotas('environment.jelasticssl.enabled').array[0].value, 6 | nodes: [{ 7 | nodeType: "storage", 8 | flexibleCloudlets: ${settings.st_flexibleCloudlets:8}, 9 | fixedCloudlets: ${settings.st_fixedCloudlets:1}, 10 | diskLimit: ${settings.st_diskLimit:100}, 11 | nodeGroup: "storage", 12 | displayName: "Storage" 13 | }] 14 | } 15 | 16 | if (${settings.galera:false}) { 17 | resp.nodes.push({ 18 | nodeType: "mariadb-dockerized", 19 | tag: "10.3.24", 20 | count: 3, 21 | flexibleCloudlets: ${settings.db_flexibleCloudlets:8}, 22 | fixedCloudlets: ${settings.db_fixedCloudlets:1}, 23 | diskLimit: ${settings.db_diskLimit:10}, 24 | nodeGroup: "sqldb", 25 | displayName: "Galera cluster", 26 | restartDelay: 5, 27 | skipNodeEmails: true, 28 | cluster: false, 29 | env: { 30 | ON_ENV_INSTALL: "", 31 | JELASTIC_PORTS: "4567,4568,4444" 32 | } 33 | }) 34 | } 35 | 36 | if (!${settings.galera:false}) { 37 | resp.nodes.push({ 38 | nodeType: "mariadb-dockerized", 39 | tag: "10.3.24", 40 | count: 2, 41 | cluster: false, 42 | flexibleCloudlets: ${settings.db_flexibleCloudlets:8}, 43 | fixedCloudlets: ${settings.db_fixedCloudlets:1}, 44 | diskLimit: ${settings.db_diskLimit:10}, 45 | nodeGroup: "sqldb", 46 | skipNodeEmails: true, 47 | displayName: "DB Server", 48 | env: { 49 | ON_ENV_INSTALL: "" 50 | } 51 | }) 52 | } 53 | 54 | if (${settings.ls-addon:false}) { 55 | resp.nodes.push({ 56 | nodeType: "litespeedadc", 57 | tag: "2.5.1", 58 | count: 1, 59 | flexibleCloudlets: ${settings.bl_flexibleCloudlets:8}, 60 | fixedCloudlets: ${settings.bl_fixedCloudlets:1}, 61 | diskLimit: ${settings.bl_diskLimit:10}, 62 | nodeGroup: "bl", 63 | scalingMode: "STATEFUL", 64 | displayName: "Load balancer", 65 | env: { 66 | WP_PROTECT: wpbfp, 67 | WP_PROTECT_LIMIT: 100 68 | } 69 | }, { 70 | nodeType: "litespeedphp", 71 | tag: "5.4.1-php-7.3.7", 72 | count: ${settings.cp_count:2}, 73 | flexibleCloudlets: ${settings.cp_flexibleCloudlets:16}, 74 | fixedCloudlets: ${settings.cp_fixedCloudlets:1}, 75 | diskLimit: ${settings.cp_diskLimit:10}, 76 | nodeGroup: "cp", 77 | scalingMode: "STATELESS", 78 | displayName: "AppServer", 79 | env: { 80 | SERVER_WEBROOT: "/var/www/webroot/ROOT", 81 | REDIS_ENABLED: "true", 82 | WAF: "${settings.waf:false}", 83 | WP_PROTECT: "OFF" 84 | }, 85 | volumes: [ 86 | "/var/www/webroot/ROOT" 87 | ], 88 | volumeMounts: { 89 | "/var/www/webroot/ROOT": { 90 | readOnly: "false", 91 | sourcePath: "/data/ROOT", 92 | sourceNodeGroup: "storage" 93 | } 94 | } 95 | }) 96 | } 97 | 98 | if (!${settings.ls-addon:false}) { 99 | resp.nodes.push({ 100 | nodeType: "nginx-dockerized", 101 | tag: "1.16.0", 102 | count: 1, 103 | flexibleCloudlets: ${settings.bl_flexibleCloudlets:8}, 104 | fixedCloudlets: ${settings.bl_fixedCloudlets:1}, 105 | diskLimit: ${settings.bl_diskLimit:10}, 106 | nodeGroup: "bl", 107 | scalingMode: "STATEFUL", 108 | displayName: "Load balancer" 109 | }, { 110 | nodeType: "nginxphp-dockerized", 111 | tag: "1.16.0-php-7.3.8", 112 | count: ${settings.cp_count:2}, 113 | flexibleCloudlets: ${settings.cp_flexibleCloudlets:8}, 114 | fixedCloudlets: ${settings.cp_fixedCloudlets:1}, 115 | diskLimit: ${settings.cp_diskLimit:10}, 116 | nodeGroup: "cp", 117 | scalingMode: "STATELESS", 118 | displayName: "AppServer", 119 | env: { 120 | SERVER_WEBROOT: "/var/www/webroot/ROOT", 121 | REDIS_ENABLED: "true" 122 | }, 123 | volumes: [ 124 | "/var/www/webroot/ROOT", 125 | "/var/www/webroot/.cache", 126 | "/etc/nginx/conf.d/SITES_ENABLED" 127 | ], 128 | volumeMounts: { 129 | "/var/www/webroot/ROOT": { 130 | readOnly: "false", 131 | sourcePath: "/data/ROOT", 132 | sourceNodeGroup: "storage" 133 | }, 134 | "/var/www/webroot/.cache": { 135 | readOnly: "false", 136 | sourcePath: "/data/.cache", 137 | sourceNodeGroup: "storage" 138 | }, 139 | "/etc/nginx/conf.d/SITES_ENABLED": { 140 | readOnly: "false", 141 | sourcePath: "/data/APP_CONFIGS", 142 | sourceNodeGroup: "storage" 143 | } 144 | } 145 | }) 146 | } 147 | 148 | return resp; 149 | -------------------------------------------------------------------------------- /scripts/checkCdnContent.txt: -------------------------------------------------------------------------------- 1 | wp-content/themes/twentynineteen/style.css 2 | wp-includes/css/dist/block-library/style.min.css 3 | wp-includes/css/dist/block-library/theme.min.css 4 | wp-includes/js/wp-embed.min.js 5 | wp-content/themes/twentynineteen/print.css 6 | -------------------------------------------------------------------------------- /scripts/dummyLS.js: -------------------------------------------------------------------------------- 1 | import com.hivext.api.Response; 2 | import org.yaml.snakeyaml.Yaml; 3 | import com.hivext.api.core.utils.Transport; 4 | 5 | var cdnAppid = "c05ffa5b45628a2a0c95467ebca8a0b4"; 6 | var lsAppid = "9e6afcf310004ac84060f90ff41atest"; 7 | var baseUrl = "https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master"; 8 | var cdnText = "Install Lightning-Fast Premium CDN", 9 | sslText = "Install Let's Encrypt SSL with Auto-Renewal"; 10 | lsText = "Install LiteSpeed High-Performance Web Server"; 11 | muText = "Install WordPress Multisite Network"; 12 | dbText = "Install MariaDB Galera Cluster"; 13 | wafText = "Web Application Firewall"; 14 | var group = jelastic.billing.account.GetAccount(appid, session); 15 | var isCDN = jelastic.dev.apps.GetApp(cdnAppid); 16 | var isLS = jelastic.dev.apps.GetApp(lsAppid); 17 | 18 | var sameNodes = "environment.maxsamenodescount"; 19 | var maxNodes = "environment.maxnodescount"; 20 | var minEnvNodes = 7, minEnvLayerNodes = 3, quotaName, quotaValue, quotaText = "", 21 | quota = jelastic.billing.account.GetQuotas(maxNodes + ";" + sameNodes).array || []; 22 | 23 | for (var i = 0, n = quota.length; i < n; i++) { 24 | quotaName = quota[i].quota.name; 25 | quotaValue = quota[i].value; 26 | 27 | if (quotaName == maxNodes && quotaValue < minEnvNodes) { 28 | quotaText = "Quota limits: " + quotaName + " = " + quotaValue + ". Min value is " + minEnvNodes + ". Please upgrade your account."; 29 | continue; 30 | } 31 | 32 | if (quotaName == sameNodes && quotaValue < minEnvLayerNodes) { 33 | quotaText = "Quota limits: " + quotaName + " = " + quotaValue + ". Min value is " + minEnvLayerNodes + ". Please upgrade your account."; 34 | continue; 35 | } 36 | } 37 | 38 | var url = baseUrl + "/configs/settings.yaml"; 39 | var settings = toNative(new Yaml().load(new Transport().get(url))); 40 | var fields = settings.fields; 41 | if (group.groupType == 'trial') { 42 | 43 | fields.push({ 44 | "type": "displayfield", 45 | "cls": "warning", 46 | "height": 30, 47 | "hideLabel": true, 48 | "markup": "Not available for " + group.groupType + " account. Please upgrade your account." 49 | }) 50 | 51 | if (isLS.result == 0 || isLS.result == Response.PERMISSION_DENIED) { 52 | settings.fields.push({ 53 | "type": "compositefield", 54 | "hideLabel": true, 55 | "pack": "left", 56 | "itemCls": "deploy-manager-grid", 57 | "cls": "x-grid3-row-unselected", 58 | "items": [{ 59 | "type": "spacer", 60 | "width": 4 61 | }, { 62 | "type": "displayfield", 63 | "cls": "x-grid3-row-checker x-item-disabled", 64 | "width": 30, 65 | "height": 20 66 | }, { 67 | "type": "displayfield", 68 | "cls": "x-item-disabled", 69 | "value": lsText 70 | }] 71 | }); 72 | } 73 | 74 | settings.fields.push({ 75 | "type": "compositefield", 76 | "hideLabel": true, 77 | "pack": "left", 78 | "itemCls": "deploy-manager-grid", 79 | "cls": "x-grid3-row-unselected", 80 | "items": [{ 81 | "type": "spacer", 82 | "width": 4 83 | }, { 84 | "type": "displayfield", 85 | "cls": "x-grid3-row-checker x-item-disabled", 86 | "width": 30, 87 | "height": 20 88 | }, { 89 | "type": "displayfield", 90 | "cls": "x-item-disabled", 91 | "value": dbText 92 | }] 93 | }); 94 | 95 | if (isCDN.result == 0 || isCDN.result == Response.PERMISSION_DENIED) { 96 | settings.fields.push({ 97 | "type": "compositefield", 98 | "hideLabel": true, 99 | "pack": "left", 100 | "itemCls": "deploy-manager-grid", 101 | "cls": "x-grid3-row-unselected", 102 | "items": [{ 103 | "type": "spacer", 104 | "width": 4 105 | }, { 106 | "type": "displayfield", 107 | "cls": "x-grid3-row-checker x-item-disabled", 108 | "width": 30, 109 | "height": 20 110 | }, { 111 | "type": "displayfield", 112 | "cls": "x-item-disabled", 113 | "value": cdnText 114 | }] 115 | }); 116 | } 117 | 118 | settings.fields.push({ 119 | "type": "compositefield", 120 | "hideLabel": true, 121 | "pack": "left", 122 | "itemCls": "deploy-manager-grid", 123 | "cls": "x-grid3-row-unselected", 124 | "items": [{ 125 | "type": "spacer", 126 | "width": 4 127 | }, { 128 | "type": "displayfield", 129 | "cls": "x-grid3-row-checker x-item-disabled", 130 | "width": 30, 131 | "height": 20 132 | }, { 133 | "type": "displayfield", 134 | "cls": "x-item-disabled", 135 | "value": sslText 136 | }] 137 | }); 138 | 139 | settings.fields.push({ 140 | type: "checkbox", 141 | name: "mu-addon", 142 | caption: muText, 143 | value: false 144 | 145 | }); 146 | 147 | } else { 148 | 149 | if (isLS.result == 0 || isLS.result == Response.PERMISSION_DENIED) { 150 | settings.fields.push({ 151 | type: "checkbox", 152 | name: "ls-addon", 153 | caption: lsText, 154 | value: true, 155 | tooltip: "If this option is disabled, the cluster will be installed using NGINX load balancer and application servers", 156 | "showIf": { 157 | "true": { 158 | "type": "checkbox", 159 | "name": "waf", 160 | "caption": wafText, 161 | "value": true, 162 | "tooltip": "Protect web sites with LiteSpeed built-in WAF based on Free ModSecurity Rules from Comodo" 163 | }, 164 | "false": { 165 | "type": "compositefield", 166 | "hideLabel": true, 167 | "pack": "left", 168 | "name": "waf", 169 | "value": false, 170 | "itemCls": "deploy-manager-grid", 171 | "cls": "x-grid3-row-unselected", 172 | "items": [{ 173 | "type": "displayfield", 174 | "cls": "x-grid3-row-checker x-item-disabled", 175 | "margins": "0 0 0 -3", 176 | "width": 16, 177 | "height": 20 178 | 179 | }, { 180 | "type": "displayfield", 181 | "cls": "x-item-disabled", 182 | "value": wafText, 183 | "margins": "0 0 0 12" 184 | }] 185 | } 186 | } 187 | }); 188 | } 189 | 190 | settings.fields.push({ 191 | type: "checkbox", 192 | name: "galera", 193 | caption: dbText, 194 | value: true, 195 | tooltip: "

Requirements for All Tables:

* run on InnoDB storage engine

* have a primary key

Read more about limitations" 196 | }); 197 | 198 | if (isCDN.result == 0 || isCDN.result == Response.PERMISSION_DENIED) { 199 | settings.fields.push({ 200 | type: "checkbox", 201 | name: "cdn-addon", 202 | caption: cdnText, 203 | value: true 204 | }); 205 | } 206 | 207 | var resp = jelastic.billing.account.GetQuotas('environment.externalip.enabled'); 208 | if (resp.result == 0 && resp.array[0].value) { 209 | fields.push({ 210 | type: "checkbox", 211 | name: "le-addon", 212 | caption: sslText, 213 | value: true 214 | }); 215 | } 216 | settings.fields.push({ 217 | type: "checkbox", 218 | name: "mu-addon", 219 | caption: muText, 220 | value: false 221 | }); 222 | } 223 | 224 | if (quotaText) { 225 | settings.fields.push( 226 | {"type": "displayfield", "cls": "warning", "height": 30, "hideLabel": true, "markup": quotaText}, 227 | {"type": "compositefield","height": 0,"hideLabel": true,"width": 0,"items": [{"height": 0,"type": "string","required": true}]} 228 | ); 229 | } 230 | 231 | return { 232 | result: 0, 233 | settings: settings 234 | }; 235 | -------------------------------------------------------------------------------- /scripts/idna.js: -------------------------------------------------------------------------------- 1 | // http://stackoverflow.com/questions/183485/can-anyone-recommend-a-good-free-javascript-for-punycode-to-unicode-conversion 2 | //Javascript Punycode converter derived from example in RFC3492. 3 | //This implementation is created by some@domain.name and released into public domain 4 | var punycode = new function Punycode() { 5 | // This object converts to and from puny-code used in IDN 6 | // 7 | // punycode.ToASCII ( domain ) 8 | // 9 | // Returns a puny coded representation of "domain". 10 | // It only converts the part of the domain name that 11 | // has non ASCII characters. I.e. it dosent matter if 12 | // you call it with a domain that already is in ASCII. 13 | // 14 | // punycode.ToUnicode (domain) 15 | // 16 | // Converts a puny-coded domain name to unicode. 17 | // It only converts the puny-coded parts of the domain name. 18 | // I.e. it dosent matter if you call it on a string 19 | // that already has been converted to unicode. 20 | // 21 | // 22 | this.utf16 = { 23 | // The utf16-class is necessary to convert from javascripts internal character representation to unicode and back. 24 | decode:function(input){ 25 | var output = [], i=0, len=input.length,value,extra; 26 | while (i < len) { 27 | value = input.charCodeAt(i++); 28 | if ((value & 0xF800) === 0xD800) { 29 | extra = input.charCodeAt(i++); 30 | if ( ((value & 0xFC00) !== 0xD800) || ((extra & 0xFC00) !== 0xDC00) ) { 31 | throw new RangeError("UTF-16(decode): Illegal UTF-16 sequence"); 32 | } 33 | value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000; 34 | } 35 | output.push(value); 36 | } 37 | return output; 38 | }, 39 | encode:function(input){ 40 | var output = [], i=0, len=input.length,value; 41 | while (i < len) { 42 | value = input[i++]; 43 | if ( (value & 0xF800) === 0xD800 ) { 44 | throw new RangeError("UTF-16(encode): Illegal UTF-16 value"); 45 | } 46 | if (value > 0xFFFF) { 47 | value -= 0x10000; 48 | output.push(String.fromCharCode(((value >>>10) & 0x3FF) | 0xD800)); 49 | value = 0xDC00 | (value & 0x3FF); 50 | } 51 | output.push(String.fromCharCode(value)); 52 | } 53 | return output.join(""); 54 | } 55 | } 56 | 57 | //Default parameters 58 | var initial_n = 0x80; 59 | var initial_bias = 72; 60 | var delimiter = "\x2D"; 61 | var base = 36; 62 | var damp = 700; 63 | var tmin=1; 64 | var tmax=26; 65 | var skew=38; 66 | var maxint = 0x7FFFFFFF; 67 | 68 | // decode_digit(cp) returns the numeric value of a basic code 69 | // point (for use in representing integers) in the range 0 to 70 | // base-1, or base if cp is does not represent a value. 71 | 72 | function decode_digit(cp) { 73 | return cp - 48 < 10 ? cp - 22 : cp - 65 < 26 ? cp - 65 : cp - 97 < 26 ? cp - 97 : base; 74 | } 75 | 76 | // encode_digit(d,flag) returns the basic code point whose value 77 | // (when used for representing integers) is d, which needs to be in 78 | // the range 0 to base-1. The lowercase form is used unless flag is 79 | // nonzero, in which case the uppercase form is used. The behavior 80 | // is undefined if flag is nonzero and digit d has no uppercase form. 81 | 82 | function encode_digit(d, flag) { 83 | return d + 22 + 75 * (d < 26) - ((flag != 0) << 5); 84 | // 0..25 map to ASCII a..z or A..Z 85 | // 26..35 map to ASCII 0..9 86 | } 87 | //** Bias adaptation function ** 88 | function adapt(delta, numpoints, firsttime ) { 89 | var k; 90 | delta = firsttime ? Math.floor(delta / damp) : (delta >> 1); 91 | delta += Math.floor(delta / numpoints); 92 | 93 | for (k = 0; delta > (((base - tmin) * tmax) >> 1); k += base) { 94 | delta = Math.floor(delta / ( base - tmin )); 95 | } 96 | return Math.floor(k + (base - tmin + 1) * delta / (delta + skew)); 97 | } 98 | 99 | // encode_basic(bcp,flag) forces a basic code point to lowercase if flag is zero, 100 | // uppercase if flag is nonzero, and returns the resulting code point. 101 | // The code point is unchanged if it is caseless. 102 | // The behavior is undefined if bcp is not a basic code point. 103 | 104 | function encode_basic(bcp, flag) { 105 | bcp -= (bcp - 97 < 26) << 5; 106 | return bcp + ((!flag && (bcp - 65 < 26)) << 5); 107 | } 108 | 109 | // Main decode 110 | this.decode=function(input,preserveCase) { 111 | // Dont use utf16 112 | var output=[]; 113 | var case_flags=[]; 114 | var input_length = input.length; 115 | 116 | var n, out, i, bias, basic, j, ic, oldi, w, k, digit, t, len; 117 | 118 | // Initialize the state: 119 | 120 | n = initial_n; 121 | i = 0; 122 | bias = initial_bias; 123 | 124 | // Handle the basic code points: Let basic be the number of input code 125 | // points before the last delimiter, or 0 if there is none, then 126 | // copy the first basic code points to the output. 127 | 128 | basic = input.lastIndexOf(delimiter); 129 | if (basic < 0) basic = 0; 130 | 131 | for (j = 0; j < basic; ++j) { 132 | if(preserveCase) case_flags[output.length] = ( input.charCodeAt(j) -65 < 26); 133 | if ( input.charCodeAt(j) >= 0x80) { 134 | throw new RangeError("Illegal input >= 0x80"); 135 | } 136 | output.push( input.charCodeAt(j) ); 137 | } 138 | 139 | // Main decoding loop: Start just after the last delimiter if any 140 | // basic code points were copied; start at the beginning otherwise. 141 | 142 | for (ic = basic > 0 ? basic + 1 : 0; ic < input_length; ) { 143 | 144 | // ic is the index of the next character to be consumed, 145 | 146 | // Decode a generalized variable-length integer into delta, 147 | // which gets added to i. The overflow checking is easier 148 | // if we increase i as we go, then subtract off its starting 149 | // value at the end to obtain delta. 150 | for (oldi = i, w = 1, k = base; ; k += base) { 151 | if (ic >= input_length) { 152 | throw RangeError ("punycode_bad_input(1)"); 153 | } 154 | digit = decode_digit(input.charCodeAt(ic++)); 155 | 156 | if (digit >= base) { 157 | throw RangeError("punycode_bad_input(2)"); 158 | } 159 | if (digit > Math.floor((maxint - i) / w)) { 160 | throw RangeError ("punycode_overflow(1)"); 161 | } 162 | i += digit * w; 163 | t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; 164 | if (digit < t) { break; } 165 | if (w > Math.floor(maxint / (base - t))) { 166 | throw RangeError("punycode_overflow(2)"); 167 | } 168 | w *= (base - t); 169 | } 170 | 171 | out = output.length + 1; 172 | bias = adapt(i - oldi, out, oldi === 0); 173 | 174 | // i was supposed to wrap around from out to 0, 175 | // incrementing n each time, so we'll fix that now: 176 | if ( Math.floor(i / out) > maxint - n) { 177 | throw RangeError("punycode_overflow(3)"); 178 | } 179 | n += Math.floor( i / out ) ; 180 | i %= out; 181 | 182 | // Insert n at position i of the output: 183 | // Case of last character determines uppercase flag: 184 | if (preserveCase) { case_flags.splice(i, 0, input.charCodeAt(ic -1) -65 < 26);} 185 | 186 | output.splice(i, 0, n); 187 | i++; 188 | } 189 | if (preserveCase) { 190 | for (i = 0, len = output.length; i < len; i++) { 191 | if (case_flags[i]) { 192 | output[i] = (String.fromCharCode(output[i]).toUpperCase()).charCodeAt(0); 193 | } 194 | } 195 | } 196 | return this.utf16.encode(output); 197 | }; 198 | 199 | //** Main encode function ** 200 | 201 | this.encode = function (input,preserveCase) { 202 | //** Bias adaptation function ** 203 | 204 | var n, delta, h, b, bias, j, m, q, k, t, ijv, case_flags; 205 | 206 | if (preserveCase) { 207 | // Preserve case, step1 of 2: Get a list of the unaltered string 208 | case_flags = this.utf16.decode(input); 209 | } 210 | // Converts the input in UTF-16 to Unicode 211 | input = this.utf16.decode(input.toLowerCase()); 212 | 213 | var input_length = input.length; // Cache the length 214 | 215 | if (preserveCase) { 216 | // Preserve case, step2 of 2: Modify the list to true/false 217 | for (j=0; j < input_length; j++) { 218 | case_flags[j] = input[j] != case_flags[j]; 219 | } 220 | } 221 | 222 | var output=[]; 223 | 224 | 225 | // Initialize the state: 226 | n = initial_n; 227 | delta = 0; 228 | bias = initial_bias; 229 | 230 | // Handle the basic code points: 231 | for (j = 0; j < input_length; ++j) { 232 | if ( input[j] < 0x80) { 233 | output.push( 234 | String.fromCharCode( 235 | case_flags ? encode_basic(input[j], case_flags[j]) : input[j] 236 | ) 237 | ); 238 | } 239 | } 240 | 241 | h = b = output.length; 242 | 243 | // h is the number of code points that have been handled, b is the 244 | // number of basic code points 245 | 246 | if (b > 0) output.push(delimiter); 247 | 248 | // Main encoding loop: 249 | // 250 | while (h < input_length) { 251 | // All non-basic code points < n have been 252 | // handled already. Find the next larger one: 253 | 254 | for (m = maxint, j = 0; j < input_length; ++j) { 255 | ijv = input[j]; 256 | if (ijv >= n && ijv < m) m = ijv; 257 | } 258 | 259 | // Increase delta enough to advance the decoder's 260 | // state to , but guard against overflow: 261 | 262 | if (m - n > Math.floor((maxint - delta) / (h + 1))) { 263 | throw RangeError("punycode_overflow (1)"); 264 | } 265 | delta += (m - n) * (h + 1); 266 | n = m; 267 | 268 | for (j = 0; j < input_length; ++j) { 269 | ijv = input[j]; 270 | 271 | if (ijv < n ) { 272 | if (++delta > maxint) return Error("punycode_overflow(2)"); 273 | } 274 | 275 | if (ijv == n) { 276 | // Represent delta as a generalized variable-length integer: 277 | for (q = delta, k = base; ; k += base) { 278 | t = k <= bias ? tmin : k >= bias + tmax ? tmax : k - bias; 279 | if (q < t) break; 280 | output.push( String.fromCharCode(encode_digit(t + (q - t) % (base - t), 0)) ); 281 | q = Math.floor( (q - t) / (base - t) ); 282 | } 283 | output.push( String.fromCharCode(encode_digit(q, preserveCase && case_flags[j] ? 1:0 ))); 284 | bias = adapt(delta, h + 1, h == b); 285 | delta = 0; 286 | ++h; 287 | } 288 | } 289 | 290 | ++delta, ++n; 291 | } 292 | return output.join(""); 293 | } 294 | 295 | this.ToASCII = function ( domain ) { 296 | var domain_array = domain.split("."); 297 | var out = []; 298 | for (var i=0; i < domain_array.length; ++i) { 299 | var s = domain_array[i]; 300 | out.push( 301 | s.match(/[^A-Za-z0-9-]/) ? 302 | "xn--" + punycode.encode(s) : 303 | s 304 | ); 305 | } 306 | return out.join("."); 307 | } 308 | this.ToUnicode = function ( domain ) { 309 | var domain_array = domain.split("."); 310 | var out = []; 311 | for (var i=0; i < domain_array.length; ++i) { 312 | var s = domain_array[i]; 313 | out.push( 314 | s.match(/^xn--/) ? 315 | punycode.decode(s.slice(4)) : 316 | s 317 | ); 318 | } 319 | return out.join("."); 320 | } 321 | }(); 322 | 323 | var sEnvUrl = "${env.url}", 324 | sConverted = sEnvUrl.split('.')[0], 325 | sDomain, 326 | sResp; 327 | 328 | 329 | if (sConverted) { 330 | if (/[а-яА-ЯЁё]/.test(sConverted)) { 331 | sDomain = sConverted.split('//')[1]; 332 | sConverted = punycode.ToASCII(sDomain); 333 | } 334 | } 335 | 336 | sResp = sEnvUrl.replace(sDomain, sConverted).split('/')[2]; 337 | 338 | return {result: 0, domain: sResp} 339 | -------------------------------------------------------------------------------- /scripts/installWP.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | name: WordPress Installation addon 3 | description: This package for WowrdPress configurations 4 | 5 | globals: 6 | WP_ADMIN_PASS: "${settings.wp_admin_pass}" 7 | WP_TITLE: "${settings.wp_title}" 8 | DB_HOST: "${settings.db_host}" 9 | DB_NAME: wp_${fn.random} 10 | DB_USER: "${settings.db_user}" 11 | DB_PASS: "${settings.db_pass}" 12 | WP_URL: "${settings.wp_url}" 13 | TARGET_NODE_ID: "${settings.targetNodeID}" 14 | 15 | onInstall: 16 | - installWP 17 | - setupWP 18 | - if (/lemp/.test("${nodes.cp.nodeType}") || /nginxphp/.test("${nodes.cp.nodeType}")): 19 | - nginxPurgeCache 20 | 21 | actions: 22 | installWP: 23 | - cmd[${globals.TARGET_NODE_ID}]: |- 24 | wget -qO- 'https://wordpress.org/latest.tar.gz' | tar xz -C /tmp && mv /tmp/wordpress/* ${SERVER_WEBROOT} 25 | mysql -u${globals.DB_USER} -p${globals.DB_PASS} -h ${globals.DB_HOST} -e "CREATE DATABASE IF NOT EXISTS ${globals.DB_NAME};" 26 | cd /var/www/webroot/ROOT && wp core config --dbhost=${globals.DB_HOST} --dbname=${globals.DB_NAME} --dbuser=${globals.DB_USER} --dbpass=${globals.DB_PASS} --path=${SERVER_WEBROOT} 27 | cd /var/www/webroot/ROOT && wp core install --title="${globals.WP_TITLE}" --admin_user=${user.email} --admin_password=${globals.WP_ADMIN_PASS} --url=${globals.WP_URL} --admin_email=${user.email} --skip-email --path=${SERVER_WEBROOT} 28 | wget ${baseUrl}../configs/wordpress/wp-jelastic.php -O ${SERVER_WEBROOT}/wp-jelastic.php 29 | sed -i "s/.*'wp-settings.php';.*/require_once ABSPATH . 'wp-jelastic.php';\n&/" ${SERVER_WEBROOT}/wp-config.php 30 | wget ${baseUrl}../images/favicon.ico -O ${SERVER_WEBROOT}/favicon.ico 31 | 32 | setupWP: 33 | - cmd[${globals.TARGET_NODE_ID}]: |- 34 | wget ${baseUrl}../scripts/setupWP.sh?_r=${fn.random} -O ~/bin/setupWP.sh &>> /var/log/run.log 35 | bash ~/bin/setupWP.sh --pgcache true --objectcache true --REDIS_HOST 127.0.0.1 36 | 37 | nginxPurgeCache: 38 | - cmd[${globals.TARGET_NODE_ID}]: |- 39 | cd ${SERVER_WEBROOT}; 40 | wp plugin install ${baseUrl}../scripts/nginx-fastcgi-cache-purge.zip --path=${SERVER_WEBROOT} 41 | wp plugin activate nginx-fastcgi-cache-purge --path=${SERVER_WEBROOT} 42 | wp option update permalink_structure '/%postname%' --path=${SERVER_WEBROOT} 43 | -------------------------------------------------------------------------------- /scripts/nginx-fastcgi-cache-purge.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/48411ed5452a74dd42a12234471c9c894972cfe1/scripts/nginx-fastcgi-cache-purge.zip -------------------------------------------------------------------------------- /scripts/settings.js: -------------------------------------------------------------------------------- 1 | import com.hivext.api.Response; 2 | import org.yaml.snakeyaml.Yaml; 3 | import com.hivext.api.core.utils.Transport; 4 | 5 | var cdnAppid = "c05ffa5b45628a2a0c95467ebca8a0b4"; 6 | var lsAppid = "9e6afcf310004ac84060f90ff41a5aba"; 7 | var baseUrl = "https://raw.githubusercontent.com/jelastic-jps/wordpress-cluster/master"; 8 | var cdnText = "Install Lightning-Fast Premium CDN", 9 | sslText = "Install Let's Encrypt SSL with Auto-Renewal"; 10 | lsText = "Install LiteSpeed High-Performance Web Server"; 11 | muText = "Install WordPress Multisite Network"; 12 | dbText = "Install MariaDB Galera Cluster"; 13 | wafText = "Web Application Firewall"; 14 | wpbfText = "WordPress Brute Force Attack Protection"; 15 | var group = jelastic.billing.account.GetAccount(appid, session); 16 | var isCDN = jelastic.dev.apps.GetApp(cdnAppid); 17 | var isLS = jelastic.dev.apps.GetApp(lsAppid); 18 | 19 | var sameNodes = "environment.maxsamenodescount"; 20 | var maxNodes = "environment.maxnodescount"; 21 | var minEnvNodes = 7, minEnvLayerNodes = 3, quotaName, quotaValue, quotaText = "", 22 | quota = jelastic.billing.account.GetQuotas(maxNodes + ";" + sameNodes).array || []; 23 | 24 | for (var i = 0, n = quota.length; i < n; i++) { 25 | quotaName = quota[i].quota.name; 26 | quotaValue = quota[i].value; 27 | 28 | if (quotaName == maxNodes && quotaValue < minEnvNodes) { 29 | quotaText = "Quota limits: " + quotaName + " = " + quotaValue + ". Min value is " + minEnvNodes + ". Please upgrade your account."; 30 | continue; 31 | } 32 | 33 | if (quotaName == sameNodes && quotaValue < minEnvLayerNodes) { 34 | quotaText = "Quota limits: " + quotaName + " = " + quotaValue + ". Min value is " + minEnvLayerNodes + ". Please upgrade your account."; 35 | continue; 36 | } 37 | } 38 | 39 | var url = baseUrl + "/configs/settings.yaml"; 40 | var settings = toNative(new Yaml().load(new Transport().get(url))); 41 | var fields = settings.fields; 42 | if (group.groupType == 'trial') { 43 | 44 | fields.push({ 45 | "type": "displayfield", 46 | "cls": "warning", 47 | "height": 30, 48 | "hideLabel": true, 49 | "markup": "Not available for " + group.groupType + " account. Please upgrade your account." 50 | }) 51 | 52 | if (isLS.result == 0 || isLS.result == Response.PERMISSION_DENIED) { 53 | settings.fields.push({ 54 | "type": "compositefield", 55 | "hideLabel": true, 56 | "pack": "left", 57 | "itemCls": "deploy-manager-grid", 58 | "cls": "x-grid3-row-unselected", 59 | "items": [{ 60 | "type": "spacer", 61 | "width": 4 62 | }, { 63 | "type": "displayfield", 64 | "cls": "x-grid3-row-checker x-item-disabled", 65 | "width": 30, 66 | "height": 20 67 | }, { 68 | "type": "displayfield", 69 | "cls": "x-item-disabled", 70 | "value": lsText 71 | }] 72 | }); 73 | } 74 | 75 | settings.fields.push({ 76 | "type": "compositefield", 77 | "hideLabel": true, 78 | "pack": "left", 79 | "itemCls": "deploy-manager-grid", 80 | "cls": "x-grid3-row-unselected", 81 | "items": [{ 82 | "type": "spacer", 83 | "width": 4 84 | }, { 85 | "type": "displayfield", 86 | "cls": "x-grid3-row-checker x-item-disabled", 87 | "width": 30, 88 | "height": 20 89 | }, { 90 | "type": "displayfield", 91 | "cls": "x-item-disabled", 92 | "value": dbText 93 | }] 94 | }); 95 | 96 | if (isCDN.result == 0 || isCDN.result == Response.PERMISSION_DENIED) { 97 | settings.fields.push({ 98 | "type": "compositefield", 99 | "hideLabel": true, 100 | "pack": "left", 101 | "itemCls": "deploy-manager-grid", 102 | "cls": "x-grid3-row-unselected", 103 | "items": [{ 104 | "type": "spacer", 105 | "width": 4 106 | }, { 107 | "type": "displayfield", 108 | "cls": "x-grid3-row-checker x-item-disabled", 109 | "width": 30, 110 | "height": 20 111 | }, { 112 | "type": "displayfield", 113 | "cls": "x-item-disabled", 114 | "value": cdnText 115 | }] 116 | }); 117 | } 118 | 119 | settings.fields.push({ 120 | "type": "compositefield", 121 | "hideLabel": true, 122 | "pack": "left", 123 | "itemCls": "deploy-manager-grid", 124 | "cls": "x-grid3-row-unselected", 125 | "items": [{ 126 | "type": "spacer", 127 | "width": 4 128 | }, { 129 | "type": "displayfield", 130 | "cls": "x-grid3-row-checker x-item-disabled", 131 | "width": 30, 132 | "height": 20 133 | }, { 134 | "type": "displayfield", 135 | "cls": "x-item-disabled", 136 | "value": sslText 137 | }] 138 | }); 139 | 140 | settings.fields.push({ 141 | type: "checkbox", 142 | name: "mu-addon", 143 | caption: muText, 144 | value: false 145 | 146 | }); 147 | 148 | } else { 149 | 150 | if (isLS.result == 0 || isLS.result == Response.PERMISSION_DENIED) { 151 | settings.fields.push({ 152 | type: "checkbox", 153 | name: "ls-addon", 154 | caption: lsText, 155 | value: true, 156 | tooltip: "If this option is disabled, the cluster will be installed using NGINX load balancer and application servers", 157 | "showIf": { 158 | "true": [{ 159 | "type": "checkbox", 160 | "name": "waf", 161 | "caption": wafText, 162 | "value": true, 163 | "tooltip": "Protect web sites with LiteSpeed built-in WAF based on Free ModSecurity Rules from Comodo" 164 | }, { 165 | "type": "checkbox", 166 | "name": "wp_protect", 167 | "caption": wpbfText, 168 | "value": true, 169 | "tooltip": "Secure WordPress Admin Panel with LiteSpeed Brute Force Protection that limits failed login attempts. Default action is Throttle and number of allowed attempts is 100" 170 | }], 171 | "false": [{ 172 | "type": "compositefield", 173 | "hideLabel": true, 174 | "pack": "left", 175 | "name": "waf", 176 | "value": false, 177 | "itemCls": "deploy-manager-grid", 178 | "cls": "x-grid3-row-unselected", 179 | "items": [{ 180 | "type": "displayfield", 181 | "cls": "x-grid3-row-checker x-item-disabled", 182 | "margins": "0 0 0 -3", 183 | "width": 16, 184 | "height": 20 185 | 186 | }, { 187 | "type": "displayfield", 188 | "cls": "x-item-disabled", 189 | "value": wafText, 190 | "margins": "0 0 0 12" 191 | }] 192 | }, { 193 | "type": "compositefield", 194 | "hideLabel": true, 195 | "pack": "left", 196 | "name": "wp_protect", 197 | "value": false, 198 | "itemCls": "deploy-manager-grid", 199 | "cls": "x-grid3-row-unselected", 200 | "items": [{ 201 | "type": "displayfield", 202 | "cls": "x-grid3-row-checker x-item-disabled", 203 | "margins": "0 0 0 -3", 204 | "width": 16, 205 | "height": 20 206 | 207 | }, { 208 | "type": "displayfield", 209 | "cls": "x-item-disabled", 210 | "value": wpbfText, 211 | "margins": "0 0 0 12" 212 | }] 213 | }] 214 | } 215 | }); 216 | } 217 | 218 | settings.fields.push({ 219 | type: "checkbox", 220 | name: "galera", 221 | caption: dbText, 222 | value: true, 223 | tooltip: "

Requirements for All Tables:

* run on InnoDB storage engine

* have a primary key

Read more about limitations" 224 | }); 225 | 226 | if (isCDN.result == 0 || isCDN.result == Response.PERMISSION_DENIED) { 227 | settings.fields.push({ 228 | type: "checkbox", 229 | name: "cdn-addon", 230 | caption: cdnText, 231 | value: true 232 | }); 233 | } 234 | 235 | var resp = jelastic.billing.account.GetQuotas('environment.externalip.enabled'); 236 | if (resp.result == 0 && resp.array[0].value) { 237 | fields.push({ 238 | type: "checkbox", 239 | name: "le-addon", 240 | caption: sslText, 241 | value: true 242 | }); 243 | } 244 | settings.fields.push({ 245 | type: "checkbox", 246 | name: "mu-addon", 247 | caption: muText, 248 | value: false 249 | }); 250 | } 251 | 252 | if (quotaText) { 253 | settings.fields.push( 254 | {"type": "displayfield", "cls": "warning", "height": 30, "hideLabel": true, "markup": quotaText}, 255 | {"type": "compositefield","height": 0,"hideLabel": true,"width": 0,"items": [{"height": 0,"type": "string","required": true}]} 256 | ); 257 | } 258 | 259 | return { 260 | result: 0, 261 | settings: settings 262 | }; 263 | -------------------------------------------------------------------------------- /scripts/setupBL.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | name: Load Balancer setup script 3 | description: This script for Load Balancer configurations 4 | 5 | globals: 6 | PATH: ${settings.PATH} 7 | MASTER_BACKEND: ${settings.MASTER_BACKEND:false} 8 | 9 | onInstall: 10 | - if (/litespeed/.test("${nodes.bl.nodeType}") && '${globals.MASTER_BACKEND}' == 'false'): 11 | - cmd [bl]: |- 12 | wget ${globals.PATH}/configs/lb/litespeed/jelastic.xml -O /var/www/conf/jelastic.xml 13 | wget ${globals.PATH}/configs/lb/litespeed/letsencrypt.xml -O /tmp/letsencrypt.xml 14 | sed -i '//r /tmp/letsencrypt.xml' /var/www/conf/lslbd_config.xml 15 | sudo jem service restart 16 | - if (/litespeed/.test("${nodes.bl.nodeType}") && '${globals.MASTER_BACKEND}' != 'false'): 17 | - cmd [bl]: |- 18 | xmlstarlet ed --inplace -u "loadBalancerConfig/loadBalancerList/loadBalancer[name = 'Letsencrypt']/workerGroupList/workerGroup[name = 'http-le']/nodeAddresses" -v "${globals.MASTER_BACKEND}" /var/www/conf/lslbd_config.xml 19 | -------------------------------------------------------------------------------- /scripts/setupCDN.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | name: Edgeport CDN setup script 3 | description: This script for Edgeport CDN configurations 4 | 5 | globals: 6 | PATH: ${settings.PATH} 7 | 8 | onInstall: 9 | - script: return jelastic.dev.scripting.Eval("c05ffa5b45628a2a0c95467ebca8a0b4", session, "cdn.info", {partnerCode:1}) 10 | - set: 11 | CDN_URL: ${env.envName}-${response.response.partnerCode}.cdn.edgeport.net 12 | - cmd[${nodes.cp.master.id}]: |- 13 | wget ${globals.PATH}/scripts/setupWP.sh?_r=${fn.random} -O ~/bin/setupWP.sh &>> /var/log/run.log 14 | wget ${globals.PATH}/scripts/checkCdnContent.txt?_r=${fn.random} -O ~/bin/checkCdnContent.txt &>> /var/log/run.log 15 | bash ~/bin/setupWP.sh --edgeportCDN true --CDN_URL ${this.CDN_URL} 16 | -------------------------------------------------------------------------------- /scripts/setupCP.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | name: CP setup script 3 | description: This script for AppServer configurations 4 | 5 | globals: 6 | PATH: ${settings.PATH} 7 | TARGET_NODES: ${settings.TARGET_NODES} 8 | 9 | onInstall: 10 | - if (/lemp/.test("${nodes.cp.nodeType}") || /nginxphp/.test("${nodes.cp.nodeType}")): 11 | - nginx 12 | - redis: 13 | PHP_CONFIG_PATH: /etc/php.d 14 | 15 | - if (/llsmp/.test("${nodes.cp.nodeType}") || /litespeed/.test("${nodes.cp.nodeType}")): 16 | - litespeed 17 | - redis: 18 | PHP_CONFIG_PATH: /usr/local/lsws/lsphp73/etc/php.d 19 | 20 | actions: 21 | redis: 22 | - cmd[${globals.TARGET_NODES}]: |- 23 | wget ${globals.PATH}/configs/cp/php/wp-upload.ini -O ${this.PHP_CONFIG_PATH}/wp-upload.ini 24 | wget ${globals.PATH}/configs/cp/php/opcache.ini -O ${this.PHP_CONFIG_PATH}/opcache.ini 25 | wget ${globals.PATH}/configs/cp/php/extensions.ini -O ${this.PHP_CONFIG_PATH}/extensions.ini 26 | wget ${globals.PATH}/configs/cp/php/redis.ini -O ${this.PHP_CONFIG_PATH}/redis.ini 27 | sudo jem service restart 28 | 29 | nginx: 30 | - cmd[${globals.TARGET_NODES}]: |- 31 | mkdir -p /var/www/webroot/SITES_ENABLED; 32 | ln -s /var/www/webroot/SITES_ENABLED /etc/nginx/conf.d/SITES_ENABLED; 33 | wget ${globals.PATH}/configs/cp/nginx/nginx.conf -O /etc/nginx/nginx.conf 34 | wget ${globals.PATH}/configs/cp/nginx/nossl.conf -O /etc/nginx/conf.d/nossl.conf 35 | wget ${globals.PATH}/configs/cp/nginx/ssl.conf.disabled -O /etc/nginx/conf.d/ssl.conf.disabled 36 | wget ${globals.PATH}/configs/cp/nginx/fastcgi_cache.conf -O /etc/nginx/conf.d/fastcgi_cache.conf 37 | 38 | litespeed: 39 | - cmd[${globals.TARGET_NODES}]: |- 40 | wget ${globals.PATH}/configs/cp/litespeed/vhconf.xml -O /var/www/webroot/vhconf.xml 41 | -------------------------------------------------------------------------------- /scripts/setupSITES.jps: -------------------------------------------------------------------------------- 1 | jpsType: update 2 | name: Custom Sites setup script 3 | description: This script for Sites configurations 4 | 5 | onInstall: 6 | - if (/lemp/.test("${nodes.cp.nodeType}") || /nginxphp/.test("${nodes.cp.nodeType}")): 7 | - nginx 8 | 9 | actions: 10 | nginx: 11 | - cmd[cp]: |- 12 | wget ${baseUrl}../configs/cp/nginx/default.conf -O /etc/nginx/conf.d/SITES_ENABLED/default.conf 13 | wget ${baseUrl}../configs/cp/nginx/skip_cache.conf -O /etc/nginx/conf.d/SITES_ENABLED/skip_cache.conf 14 | sudo /etc/init.d/nginx restart 15 | -------------------------------------------------------------------------------- /scripts/setupWP.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | purge=false; 4 | pgcache=false; 5 | objectcache=false; 6 | edgeportCDN=false; 7 | wpmu=false; 8 | DOMAIN=false; 9 | 10 | SERVER_WEBROOT=/var/www/webroot/ROOT 11 | 12 | ARGUMENT_LIST=( 13 | "purge" 14 | "pgcache" 15 | "objectcache" 16 | "edgeportCDN" 17 | "wpmu" 18 | "REDIS_HOST" 19 | "REDIS_PASS" 20 | "CDN_URL" 21 | "CDN_ORI" 22 | "MODE" 23 | "DOMAIN" 24 | 25 | ) 26 | 27 | WP=`which wp` 28 | 29 | # read arguments 30 | opts=$(getopt \ 31 | --longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")" \ 32 | --name "$(basename "$0")" \ 33 | --options "" \ 34 | -- "$@" 35 | ) 36 | eval set --$opts 37 | 38 | while [[ $# -gt 0 ]]; do 39 | case "$1" in 40 | --purge) 41 | purge=$2 42 | shift 2 43 | ;; 44 | 45 | --pgcache) 46 | pgcache=$2 47 | shift 2 48 | ;; 49 | 50 | --objectcache) 51 | objectcache=$2 52 | shift 2 53 | ;; 54 | 55 | --edgeportCDN) 56 | edgeportCDN=$2 57 | shift 2 58 | ;; 59 | 60 | --REDIS_HOST) 61 | REDIS_HOST=$2 62 | shift 2 63 | ;; 64 | 65 | --REDIS_PASS) 66 | REDIS_PASS=$2 67 | shift 2 68 | ;; 69 | 70 | --CDN_URL) 71 | CDN_URL=$2 72 | shift 2 73 | ;; 74 | 75 | --CDN_ORI) 76 | CDN_ORI=$2 77 | shift 2 78 | ;; 79 | 80 | --wpmu) 81 | wpmu=$2 82 | shift 2 83 | ;; 84 | 85 | --MODE) 86 | MODE=$2 87 | shift 2 88 | ;; 89 | 90 | --DOMAIN) 91 | DOMAIN=$2 92 | shift 2 93 | ;; 94 | 95 | *) 96 | break 97 | ;; 98 | esac 99 | done 100 | 101 | W3TC_OPTION_SET="${WP} w3-total-cache option set" 102 | LSCWP_OPTION_SET="${WP} litespeed-option set" 103 | lOG="/var/log/run.log" 104 | 105 | COMPUTE_TYPE=$(grep "COMPUTE_TYPE=" /etc/jelastic/metainf.conf | cut -d"=" -f2) 106 | 107 | cd ${SERVER_WEBROOT}; 108 | 109 | if [[ ${COMPUTE_TYPE} == *"llsmp"* || ${COMPUTE_TYPE} == *"litespeed"* ]] ; then 110 | ${WP} plugin install litespeed-cache --activate --path=${SERVER_WEBROOT} 111 | CACHE_FLUSH="${WP} litespeed-purge all --path=${SERVER_WEBROOT}; rm -rf /var/www/webroot/.cache/vhosts/Jelastic/* " 112 | WPCACHE='lscwp'; 113 | elif [[ ${COMPUTE_TYPE} == *"lemp"* || ${COMPUTE_TYPE} == *"nginx"* ]] ; then 114 | ${WP} plugin install w3-total-cache --activate --path=${SERVER_WEBROOT} 115 | CACHE_FLUSH="${WP} w3-total-cache flush all --path=${SERVER_WEBROOT}; /var/www/webroot/.cache/* " 116 | WPCACHE="w3tc"; 117 | else 118 | echo 'Compute type is not defined'; 119 | exit; 120 | fi 121 | 122 | function checkCdnStatus () { 123 | if [ $WPCACHE == 'w3tc' ] ; then 124 | CDN_ENABLE_CMD="${WP} w3-total-cache option set cdn.enabled true --type=boolean" 125 | elif [ $WPCACHE == 'lscwp' ] ; then 126 | CDN_ENABLE_CMD="${WP} litespeed-option set cdn true" 127 | fi 128 | cat > ~/bin/checkCdnStatus.sh <> /var/log/run.log 141 | ${CACHE_FLUSH} &>> /var/log/run.log 142 | ${WP} cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log 143 | crontab -l | sed "/checkCdnStatus/d" | crontab - 144 | EOF 145 | chmod +x ~/bin/checkCdnStatus.sh 146 | PROTOCOL=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d':' -f1) 147 | crontab -l | { cat; echo "* * * * * /bin/bash ~/bin/checkCdnStatus.sh ${PROTOCOL}://${CDN_URL}/"; } | crontab 148 | } 149 | 150 | if [ $purge == 'true' ] ; then 151 | ${CACHE_FLUSH} &>> /var/log/run.log 152 | ${WP} cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log 153 | [ -d /tmp/lscache/vhosts/ ] && /usr/bin/rm -rf /tmp/lscache/vhosts/Jelastic/* &>> /var/log/run.log 154 | fi 155 | 156 | if [ $pgcache == 'true' ] ; then 157 | case $WPCACHE in 158 | w3tc) 159 | $W3TC_OPTION_SET pgcache.enabled true --type=boolean --path=${SERVER_WEBROOT} &>> $lOG 160 | $W3TC_OPTION_SET pgcache.file.nfs true --type=boolean --path=${SERVER_WEBROOT} &>> $lOG 161 | ;; 162 | lscwp) 163 | $LSCWP_OPTION_SET cache_browser true --path=${SERVER_WEBROOT} &>> $lOG 164 | $LSCWP_OPTION_SET css_http2 true --path=${SERVER_WEBROOT} &>> $lOG 165 | $LSCWP_OPTION_SET js_http2 true --path=${SERVER_WEBROOT} &>> $lOG 166 | $LSCWP_OPTION_SET optm_qs_rm true --path=${SERVER_WEBROOT} &>> $lOG 167 | $LSCWP_OPTION_SET optm_emoji_rm true --path=${SERVER_WEBROOT} &>> $lOG 168 | $LSCWP_OPTION_SET esi_enabled true --path=${SERVER_WEBROOT} &>> $lOG 169 | $LSCWP_OPTION_SET cache_priv false --path=${SERVER_WEBROOT} &>> $lOG 170 | ;; 171 | esac 172 | fi 173 | 174 | if [ $objectcache == 'true' ] ; then 175 | case $WPCACHE in 176 | w3tc) 177 | $W3TC_OPTION_SET objectcache.enabled true --type=boolean --path=${SERVER_WEBROOT} &>> /var/log/run.log 178 | $W3TC_OPTION_SET objectcache.engine redis --path=${SERVER_WEBROOT} &>> /var/log/run.log 179 | $W3TC_OPTION_SET objectcache.redis.servers ${REDIS_HOST}:6379 --path=${SERVER_WEBROOT} &>> /var/log/run.log 180 | $W3TC_OPTION_SET objectcache.redis.password ${REDIS_PASS} --path=${SERVER_WEBROOT} &>> /var/log/run.log 181 | ;; 182 | lscwp) 183 | $LSCWP_OPTION_SET object true --path=${SERVER_WEBROOT} &>> /var/log/run.log 184 | $LSCWP_OPTION_SET object-kind 1 --path=${SERVER_WEBROOT} &>> /var/log/run.log 185 | $LSCWP_OPTION_SET object-host ${REDIS_HOST} --path=${SERVER_WEBROOT} &>> /var/log/run.log 186 | $LSCWP_OPTION_SET object-port 6379 --path=${SERVER_WEBROOT} &>> /var/log/run.log 187 | ;; 188 | esac 189 | fi 190 | 191 | if [ $edgeportCDN == 'true' ] ; then 192 | if ! $(${WP} core is-installed --network --path=${SERVER_WEBROOT}); then 193 | case $WPCACHE in 194 | w3tc) 195 | checkCdnStatus; 196 | $W3TC_OPTION_SET cdn.enabled false --type=boolean --path=${SERVER_WEBROOT} &>> /var/log/run.log 197 | $W3TC_OPTION_SET cdn.engine mirror --path=${SERVER_WEBROOT} &>> /var/log/run.log 198 | $W3TC_OPTION_SET cdn.mirror.domain ${CDN_URL} --path=${SERVER_WEBROOT} &>> /var/log/run.log 199 | ;; 200 | lscwp) 201 | checkCdnStatus; 202 | CDN_ORI=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d'/' -f3) 203 | PROTOCOL=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d':' -f1) 204 | $LSCWP_OPTION_SET cdn false --path=${SERVER_WEBROOT} &>> /var/log/run.log 205 | $LSCWP_OPTION_SET cdn-mapping[url][0] ${PROTOCOL}://${CDN_URL}/ --path=${SERVER_WEBROOT} &>> /var/log/run.log 206 | $LSCWP_OPTION_SET cdn-ori "//${CDN_ORI}/" --path=${SERVER_WEBROOT} &>> /var/log/run.log 207 | ;; 208 | esac 209 | fi 210 | fi 211 | 212 | if [ $wpmu == 'true' ] ; then 213 | case $WPCACHE in 214 | w3tc) 215 | ${WP} plugin deactivate w3-total-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log 216 | [[ ${MODE} == 'subdir' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} &>> /var/log/run.log 217 | [[ ${MODE} == 'subdom' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} --subdomains &>> /var/log/run.log 218 | ${WP} plugin activate w3-total-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log 219 | ;; 220 | lscwp) 221 | ${WP} plugin deactivate litespeed-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log 222 | [[ ${MODE} == 'subdir' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} &>> /var/log/run.log 223 | [[ ${MODE} == 'subdom' ]] && ${WP} core multisite-convert --path=${SERVER_WEBROOT} --subdomains &>> /var/log/run.log 224 | ${WP} plugin activate litespeed-cache --path=${SERVER_WEBROOT} &>> /var/log/run.log 225 | ;; 226 | esac 227 | fi 228 | 229 | if [ $DOMAIN != 'false' ] ; then 230 | if ! $(${WP} core is-installed --network --path=${SERVER_WEBROOT}); then 231 | OLD_DOMAIN=$(${WP} option get siteurl --path=${SERVER_WEBROOT}) 232 | OLD_SHORT_DOMAIN=$(${WP} option get siteurl --path=${SERVER_WEBROOT} | cut -d'/' -f3) 233 | NEW_SHORT_DOMAIN=$(echo $DOMAIN | cut -d'/' -f3) 234 | 235 | ${WP} search-replace "${OLD_DOMAIN}" "${DOMAIN}" --skip-columns=guid --all-tables --path=${SERVER_WEBROOT} &>> /var/log/run.log 236 | ${WP} search-replace "${OLD_SHORT_DOMAIN}" "${NEW_SHORT_DOMAIN}" --skip-columns=guid --all-tables --path=${SERVER_WEBROOT} &>> /var/log/run.log 237 | ${CACHE_FLUSH} &>> /var/log/run.log 238 | ${WP} cache flush --path=${SERVER_WEBROOT} &>> /var/log/run.log 239 | fi 240 | fi 241 | -------------------------------------------------------------------------------- /scripts/updateTriggers.js: -------------------------------------------------------------------------------- 1 | var SCALE = "scale-", 2 | DOWN = "down", 3 | UP = "up", 4 | scaleUp = SCALE + UP, 5 | scaleDown = SCALE + DOWN, 6 | addNode = "ADD_NODE", 7 | removeNode = "REMOVE_NODE", 8 | count = getParam('count'), 9 | ENV_NAME = "${env.name}", 10 | triggersToEdit = [], 11 | triggerActions, 12 | customData, 13 | triggers, 14 | upLimit, 15 | resp; 16 | 17 | resp = jelastic.environment.trigger.GetTriggers(ENV_NAME, session, addNode + ";" + removeNode); 18 | if (resp.result != 0) return resp; 19 | 20 | triggers = resp.array; 21 | 22 | for (var i = 0, n = triggers.length; i < n; i++) { 23 | if ([scaleUp, scaleDown].indexOf(String(triggers[i].name)) != -1) { 24 | triggerActions = triggers[i].actions; 25 | 26 | for (var l = 0, m = triggerActions.length; l < m; l++) { 27 | customData = triggerActions[l].customData; 28 | 29 | if (triggers[i].name == scaleUp) upLimit = customData.limit; 30 | 31 | if ((triggerActions[l].type == addNode && customData.limit < count) || triggerActions[l].type == removeNode) { 32 | triggers[i].actions[l].customData.limit = count; 33 | 34 | triggersToEdit.push({ 35 | scale: triggers[i].name.indexOf(UP) != -1 ? UP : DOWN, 36 | trigger: triggers[i] 37 | }); 38 | } 39 | } 40 | } 41 | } 42 | 43 | for (var i = 0, n = triggersToEdit.length; i < n; i++) { 44 | trigger = triggersToEdit[i].trigger; 45 | 46 | if (triggersToEdit[i].scale == DOWN && trigger.actions[0].customData.limit >= upLimit) trigger.actions[0].customData.limit = upLimit - 1; 47 | 48 | resp = jelastic.environment.trigger.EditTrigger(ENV_NAME, session, trigger.id, trigger); 49 | if (resp.result != 0) return resp; 50 | } 51 | 52 | return {result: 0}; 53 | -------------------------------------------------------------------------------- /success/email/cluster/oneregion-cdn.md: -------------------------------------------------------------------------------- 1 | **WordPress environment**: [${globals.PROTOCOL}://${env.domain}/](${globals.PROTOCOL}://${env.domain}/) 2 | 3 | **CDN Endpoint URL**: [${globals.CDN_URL}](${globals.CDN_URL}) 4 | 5 | Use the following credentials to access the admin panel: 6 | 7 | **Admin Panel**: [${globals.PROTOCOL}://${env.domain}/wp-admin/](${globals.PROTOCOL}://${env.domain}/wp-admin/) 8 | **Login**: ${user.email} 9 | **Password**: ${globals.WP_ADMIN_PASS} 10 | 11 | Manage the database nodes using the next credentials: 12 | 13 | **phpMyAdmin Panel**: [https://node${nodes.sqldb.master.id}-${env.domain}/](https://node${nodes.sqldb.master.id}-${env.domain}/) 14 | **Username**: ${globals.DB_USER} 15 | **Password**: ${globals.DB_PASS} 16 | 17 | -------------------------------------------------------------------------------- /success/email/cluster/oneregion-default.md: -------------------------------------------------------------------------------- 1 | **WordPress environment**: [${globals.PROTOCOL}://${env.domain}/](${globals.PROTOCOL}://${env.domain}/) 2 | 3 | Use the following credentials to access the admin panel: 4 | 5 | **Admin Panel**: [${globals.PROTOCOL}://${env.domain}/wp-admin/](${globals.PROTOCOL}://${env.domain}/wp-admin/) 6 | **Login**: ${user.email} 7 | **Password**: ${globals.WP_ADMIN_PASS} 8 | 9 | Manage the database nodes using the next credentials: 10 | 11 | **phpMyAdmin Panel**: [https://node${nodes.sqldb.master.id}-${env.domain}/](https://node${nodes.sqldb.master.id}-${env.domain}/) 12 | **Username**: ${globals.DB_USER} 13 | **Password**: ${globals.DB_PASS} 14 | 15 | -------------------------------------------------------------------------------- /success/text/oneregion/success-cdn.md: -------------------------------------------------------------------------------- 1 | **WordPress environment**: [${globals.PROTOCOL}://${env.domain}/](${globals.PROTOCOL}://${env.domain}/) 2 | 3 | **CDN Endpoint URL**: [${globals.CDN_URL}](${globals.CDN_URL}) 4 | 5 | Use the following credentials to access the admin panel: 6 | 7 | **Admin Panel**: [${globals.PROTOCOL}://${env.domain}/wp-admin/](${globals.PROTOCOL}://${env.domain}/wp-admin/) 8 | **Login**: ${user.email} 9 | **Password**: ${globals.WP_ADMIN_PASS} 10 | 11 | The instructions below can help you with further managing your WordPress: 12 | 13 | * [Bind custom domain](https://docs.jelastic.com/custom-domain-via-cname) 14 | * [Share access to the environment](http://docs.jelastic.com/share-environment) 15 | * [Adjust automatic vertical scaling settings](http://docs.jelastic.com/automatic-vertical-scaling) 16 | * [Configure automatic horizontal scaling](http://docs.jelastic.com/automatic-horizontal-scaling) 17 | * [Monitor the statistics](http://docs.jelastic.com/view-app-statistics) & [view log files](https://docs.jelastic.com/view-log-files) 18 | * [Attach Public IP](https://docs.jelastic.com/public-ip) 19 | * [Access environment via SSH](https://docs.jelastic.com/ssh-access) 20 | -------------------------------------------------------------------------------- /success/text/oneregion/success.md: -------------------------------------------------------------------------------- 1 | **WordPress environment**: [${globals.PROTOCOL}://${env.domain}/](${globals.PROTOCOL}://${env.domain}/) 2 | 3 | Use the following credentials to access the admin panel: 4 | 5 | **Admin Panel**: [${globals.PROTOCOL}://${env.domain}/wp-admin/](${globals.PROTOCOL}://${env.domain}/wp-admin/) 6 | **Login**: ${user.email} 7 | **Password**: ${globals.WP_ADMIN_PASS} 8 | 9 | The instructions below can help you with further managing your WordPress: 10 | 11 | * [Bind custom domain](https://docs.jelastic.com/custom-domain-via-cname) 12 | * [Share access to the environment](http://docs.jelastic.com/share-environment) 13 | * [Adjust automatic vertical scaling settings](http://docs.jelastic.com/automatic-vertical-scaling) 14 | * [Configure automatic horizontal scaling](http://docs.jelastic.com/automatic-horizontal-scaling) 15 | * [Monitor the statistics](http://docs.jelastic.com/view-app-statistics) & [view log files](https://docs.jelastic.com/view-log-files) 16 | * [Attach Public IP](https://docs.jelastic.com/public-ip) 17 | * [Access environment via SSH](https://docs.jelastic.com/ssh-access) 18 | --------------------------------------------------------------------------------