├── 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 | [](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 | [](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 |
--------------------------------------------------------------------------------