├── .gitignore ├── LICENSE ├── apache_mod_php.yml ├── group_vars └── webservers ├── hosts ├── install-all-software.yml ├── nginx_hhvm.yml ├── nginx_hhvm_fastcgi_cache.yml ├── nginx_php-fpm.yml ├── roles ├── apache │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── apache2.conf.j2 │ │ └── wp-mod_php.conf.j2 ├── common │ ├── handlers │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── hhvm │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── php.ini.j2 │ │ └── server.ini.j2 ├── mariadb │ ├── defaults │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── monit │ └── tasks │ │ └── main.yml ├── nginx │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── nginx.conf.j2 │ │ ├── wp-hhvm-fastcgi-cache.conf.j2 │ │ ├── wp-hhvm.conf.j2 │ │ └── wp-php-fpm.conf.j2 ├── php-fpm │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ │ ├── php-fpm.conf.j2 │ │ └── php.ini.j2 ├── php │ └── tasks │ │ └── main.yml ├── redis │ ├── meta │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── reset-all-configs │ ├── handlers │ │ └── main.yml │ └── tasks │ │ ├── main.yml │ │ └── stop-services.yml ├── reset-wordpress │ └── tasks │ │ └── main.yml ├── web-caching │ └── tasks │ │ └── main.yml ├── wordpress-install │ └── tasks │ │ └── main.yml └── wp-cli │ ├── meta │ └── main.yml │ └── tasks │ └── main.yml ├── wordpress_advanced.yml ├── wordpress_basic.yml └── wordpress_redis_db_cache.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | 4 | # Secret passwords and sensitive data 5 | roles/*/vars/ 6 | 7 | # Used to verify my hosts at loader.io for load testing 8 | loader.io-verification.yml 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /apache_mod_php.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: WordPress on Apache2 (no FastCGI caching), mod_php, MariaDB 3 | 4 | hosts: webservers 5 | remote_user: root 6 | vars: 7 | wp_mod_php: True 8 | 9 | roles: 10 | - reset-all-configs 11 | - apache 12 | 13 | -------------------------------------------------------------------------------- /group_vars/webservers: -------------------------------------------------------------------------------- 1 | # role: common 2 | remote_deploy_user: deploy 3 | remote_deploy_group: deploy 4 | remote_deploy_home: /home/deploy 5 | ssh_key_pub_path: /Users/lamosty/.ssh/id_rsa.pub 6 | 7 | # role: wordpress-install 8 | remote_www_dir: "{{ remote_deploy_home}}/projects" 9 | remote_wordpress_dir: "{{ remote_www_dir }}/wordpress" 10 | wordpress_db_name: wordpress 11 | wordpress_db_user: deploy 12 | wordpress_db_user_pass: deploypass 13 | wordpress_db_prefix: wp_ 14 | wordpress_home_url: http://example.com 15 | wordpress_site_title: Test Site 16 | wordpress_admin_user: admin 17 | wordpress_admin_user_pass: adminpass 18 | wordpress_admin_email: email@example.com 19 | 20 | wordpress_plugins: 21 | - wordpress-importer 22 | - woocommerce 23 | - disqus-comment-system 24 | - jetpack 25 | - wordpress-seo 26 | - custom-sidebars 27 | 28 | wordpress_theme: storefront 29 | 30 | # role: mariadb 31 | # You can put the password into roles/mariadb/vars/main.yml and add the file to .gitignore for security reasons 32 | mysql_root_password: mariadbpass -------------------------------------------------------------------------------- /hosts: -------------------------------------------------------------------------------- 1 | # Put your VPS server host here 2 | 3 | vpsfree.pgn 4 | 5 | [webservers] 6 | vpsfree.pgn -------------------------------------------------------------------------------- /install-all-software.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: > 3 | Installs PHP, WP-CLI, MariaDB, WordPress, PHP-FPM, Nginx, Apache2, HHVM, 4 | Redis. Disables the software from starting on boot and stops them. 5 | Run other playbooks to set up the server for serving, for example: 6 | wordpress_basic.yml with nginx_php-fpm.yml: WordPress with default theme 7 | served on Nginx with PHP-FPM. 8 | 9 | hosts: webservers 10 | remote_user: root 11 | 12 | roles: 13 | - common 14 | - php 15 | - wp-cli 16 | - mariadb 17 | - wordpress-install 18 | - php-fpm 19 | - nginx 20 | - apache 21 | - hhvm 22 | - redis 23 | - monit 24 | 25 | -------------------------------------------------------------------------------- /nginx_hhvm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: WordPress on Nginx (no FastCGI caching), PHP-FPM, MariaDB 3 | 4 | hosts: webservers 5 | remote_user: root 6 | vars: 7 | wp_hhvm: true 8 | hhvm_start: true 9 | 10 | roles: 11 | - reset-all-configs 12 | - hhvm 13 | - nginx 14 | 15 | -------------------------------------------------------------------------------- /nginx_hhvm_fastcgi_cache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: WordPress on Nginx (with FastCGI caching), HHVM, MariaDB 3 | 4 | hosts: webservers 5 | remote_user: root 6 | vars: 7 | wp_hhvm_cache: true 8 | hhvm_start: true 9 | 10 | roles: 11 | - reset-all-configs 12 | - hhvm 13 | - nginx 14 | 15 | -------------------------------------------------------------------------------- /nginx_php-fpm.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: WordPress on Nginx (no FastCGI caching), PHP-FPM, MariaDB 3 | 4 | hosts: webservers 5 | remote_user: root 6 | vars: 7 | wp_php_fpm: true 8 | fpm_start: true 9 | 10 | roles: 11 | - reset-all-configs 12 | - php-fpm 13 | - nginx 14 | 15 | -------------------------------------------------------------------------------- /roles/apache/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: start apache2 4 | service: name=apache2 state=started -------------------------------------------------------------------------------- /roles/apache/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add Apache PPA 3 | apt_repository: repo="ppa:ondrej/apache2" update_cache=yes 4 | 5 | - name: Install Apache 6 | apt: name=apache2 state=present 7 | 8 | - name: Install mod_php and libraries 9 | apt: name="{{ item }}" state=present 10 | with_items: 11 | - libapache2-mod-php5 12 | - libapache2-mod-auth-mysql 13 | 14 | - name: Create apache2.conf 15 | template: src=apache2.conf.j2 dest=/etc/apache2/apache2.conf 16 | 17 | - name: Disable Apache from starting on boot 18 | service: name=apache2 enabled=no state=stopped 19 | 20 | - name: Disable default site 21 | file: path=/etc/apache2/sites-enabled/000-default.conf state=absent 22 | 23 | - name: Create mod_php WordPress site configuration 24 | template: src=wp-mod_php.conf.j2 25 | dest=/etc/apache2/sites-available/wp-mod_php.conf 26 | 27 | - name: Enable mod_php WordPress site configuration 28 | file: src="/etc/apache2/sites-available/wp-mod_php.conf" 29 | dest="/etc/apache2/sites-enabled/wp-mod_php.conf" 30 | owner=root 31 | group=root 32 | state=link 33 | notify: start apache2 34 | when: wp_mod_php is defined 35 | -------------------------------------------------------------------------------- /roles/apache/templates/apache2.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | # This is the main Apache server configuration file. It contains the 4 | # configuration directives that give the server its instructions. 5 | # See http://httpd.apache.org/docs/2.4/ for detailed information about 6 | # the directives and /usr/share/doc/apache2/README.Debian about Debian specific 7 | # hints. 8 | # 9 | # 10 | # Summary of how the Apache 2 configuration works in Debian: 11 | # The Apache 2 web server configuration in Debian is quite different to 12 | # upstream's suggested way to configure the web server. This is because Debian's 13 | # default Apache2 installation attempts to make adding and removing modules, 14 | # virtual hosts, and extra configuration directives as flexible as possible, in 15 | # order to make automating the changes and administering the server as easy as 16 | # possible. 17 | 18 | # It is split into several files forming the configuration hierarchy outlined 19 | # below, all located in the /etc/apache2/ directory: 20 | # 21 | # /etc/apache2/ 22 | # |-- apache2.conf 23 | # | `-- ports.conf 24 | # |-- mods-enabled 25 | # | |-- *.load 26 | # | `-- *.conf 27 | # |-- conf-enabled 28 | # | `-- *.conf 29 | # `-- sites-enabled 30 | # `-- *.conf 31 | # 32 | # 33 | # * apache2.conf is the main configuration file (this file). It puts the pieces 34 | # together by including all remaining configuration files when starting up the 35 | # web server. 36 | # 37 | # * ports.conf is always included from the main configuration file. It is 38 | # supposed to determine listening ports for incoming connections which can be 39 | # customized anytime. 40 | # 41 | # * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ 42 | # directories contain particular configuration snippets which manage modules, 43 | # global configuration fragments, or virtual host configurations, 44 | # respectively. 45 | # 46 | # They are activated by symlinking available configuration files from their 47 | # respective *-available/ counterparts. These should be managed by using our 48 | # helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See 49 | # their respective man pages for detailed information. 50 | # 51 | # * The binary is called apache2. Due to the use of environment variables, in 52 | # the default configuration, apache2 needs to be started/stopped with 53 | # /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not 54 | # work with the default configuration. 55 | 56 | 57 | # Global configuration 58 | # 59 | 60 | # 61 | # ServerRoot: The top of the directory tree under which the server's 62 | # configuration, error, and log files are kept. 63 | # 64 | # NOTE! If you intend to place this on an NFS (or otherwise network) 65 | # mounted filesystem then please read the Mutex documentation (available 66 | # at ); 67 | # you will save yourself a lot of trouble. 68 | # 69 | # Do NOT add a slash at the end of the directory path. 70 | # 71 | #ServerRoot "/etc/apache2" 72 | 73 | # 74 | # The accept serialization lock file MUST BE STORED ON A LOCAL DISK. 75 | # 76 | Mutex file:${APACHE_LOCK_DIR} default 77 | 78 | # 79 | # PidFile: The file in which the server should record its process 80 | # identification number when it starts. 81 | # This needs to be set in /etc/apache2/envvars 82 | # 83 | PidFile ${APACHE_PID_FILE} 84 | 85 | # 86 | # Timeout: The number of seconds before receives and sends time out. 87 | # 88 | Timeout 300 89 | 90 | # 91 | # KeepAlive: Whether or not to allow persistent connections (more than 92 | # one request per connection). Set to "Off" to deactivate. 93 | # 94 | KeepAlive On 95 | 96 | # 97 | # MaxKeepAliveRequests: The maximum number of requests to allow 98 | # during a persistent connection. Set to 0 to allow an unlimited amount. 99 | # We recommend you leave this number high, for maximum performance. 100 | # 101 | MaxKeepAliveRequests 100 102 | 103 | # 104 | # KeepAliveTimeout: Number of seconds to wait for the next request from the 105 | # same client on the same connection. 106 | # 107 | KeepAliveTimeout 5 108 | 109 | 110 | # These need to be set in /etc/apache2/envvars 111 | User www-data 112 | Group www-data 113 | 114 | # 115 | # HostnameLookups: Log the names of clients or just their IP addresses 116 | # e.g., www.apache.org (on) or 204.62.129.132 (off). 117 | # The default is off because it'd be overall better for the net if people 118 | # had to knowingly turn this feature on, since enabling it means that 119 | # each client request will result in AT LEAST one lookup request to the 120 | # nameserver. 121 | # 122 | HostnameLookups Off 123 | 124 | # ErrorLog: The location of the error log file. 125 | # If you do not specify an ErrorLog directive within a 126 | # container, error messages relating to that virtual host will be 127 | # logged here. If you *do* define an error logfile for a 128 | # container, that host's errors will be logged there and not here. 129 | # 130 | ErrorLog ${APACHE_LOG_DIR}/error.log 131 | 132 | # 133 | # LogLevel: Control the severity of messages logged to the error_log. 134 | # Available values: trace8, ..., trace1, debug, info, notice, warn, 135 | # error, crit, alert, emerg. 136 | # It is also possible to configure the log level for particular modules, e.g. 137 | # "LogLevel info ssl:warn" 138 | # 139 | LogLevel warn 140 | 141 | # Include module configuration: 142 | IncludeOptional mods-enabled/*.load 143 | IncludeOptional mods-enabled/*.conf 144 | 145 | # Include list of ports to listen on 146 | Include ports.conf 147 | 148 | 149 | # Sets the default security model of the Apache2 HTTPD server. It does 150 | # not allow access to the root filesystem outside of /usr/share and /var/www. 151 | # The former is used by web applications packaged in Debian, 152 | # the latter may be used for local directories served by the web server. If 153 | # your system is serving content from a sub-directory in /srv you must allow 154 | # access here, or in any related virtual host. 155 | 156 | Options FollowSymLinks 157 | AllowOverride None 158 | Require all denied 159 | 160 | 161 | 162 | AllowOverride None 163 | Require all granted 164 | 165 | 166 | 167 | # AccessFileName: The name of the file to look for in each directory 168 | # for additional configuration directives. See also the AllowOverride 169 | # directive. 170 | # 171 | AccessFileName .htaccess 172 | 173 | # 174 | # The following lines prevent .htaccess and .htpasswd files from being 175 | # viewed by Web clients. 176 | # 177 | 178 | Require all denied 179 | 180 | 181 | 182 | # 183 | # The following directives define some format nicknames for use with 184 | # a CustomLog directive. 185 | # 186 | # These deviate from the Common Log Format definitions in that they use %O 187 | # (the actual bytes sent including headers) instead of %b (the size of the 188 | # requested file), because the latter makes it impossible to detect partial 189 | # requests. 190 | # 191 | # Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. 192 | # Use mod_remoteip instead. 193 | # 194 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 195 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined 196 | LogFormat "%h %l %u %t \"%r\" %>s %O" common 197 | LogFormat "%{Referer}i -> %U" referer 198 | LogFormat "%{User-agent}i" agent 199 | 200 | # Include of directories ignores editors' and dpkg's backup files, 201 | # see README.Debian for details. 202 | 203 | # Include generic snippets of statements 204 | IncludeOptional conf-enabled/*.conf 205 | 206 | # Include the virtual host configurations: 207 | IncludeOptional sites-enabled/*.conf 208 | 209 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 210 | -------------------------------------------------------------------------------- /roles/apache/templates/wp-mod_php.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | 4 | DirectoryIndex index.php 5 | DocumentRoot "{{ remote_wordpress_dir }}" 6 | 7 | 8 | Options Indexes FollowSymLinks 9 | 10 | # No .htaccess 11 | AllowOverride None 12 | 13 | Require all granted 14 | 15 | 16 | -------------------------------------------------------------------------------- /roles/common/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reconfigure dpkg 4 | command: /usr/sbin/dpkg-reconfigure locales -------------------------------------------------------------------------------- /roles/common/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: First apt-get update 3 | command: apt-get update 4 | 5 | - name: install python-apt (required to ansible apt module) 6 | command: apt-get install python-apt -y 7 | 8 | - name: Update Apt 9 | apt: update_cache=yes 10 | 11 | - name: Generate locale 12 | locale_gen: name="en_US.UTF-8" state=present 13 | 14 | - name: Update locale 15 | command: /usr/sbin/update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 16 | notify: reconfigure dpkg 17 | 18 | - name: Check if anything needs autoremoving 19 | shell: apt-get -y --dry-run autoremove | grep -q "0 to remove" 20 | register: check_autoremove 21 | ignore_errors: True 22 | changed_when: False 23 | always_run: True 24 | 25 | - name: Autoremove unused packages 26 | command: apt-get -y autoremove 27 | when: "check_autoremove.rc != 0" 28 | 29 | - name: Install useful software 30 | apt: name="{{ item }}" state=present 31 | with_items: 32 | - sudo 33 | - htop 34 | - screen 35 | - unzip 36 | 37 | - name: Install system packages 38 | apt: name="{{ item }}" state=present 39 | with_items: 40 | - python-software-properties 41 | - python-pycurl 42 | - build-essential 43 | - curl 44 | - git-core 45 | - wget 46 | - python-mysqldb # used for handling MariaDB from Ansible 47 | 48 | - name: Add {{ remote_deploy_group }} group 49 | group: 50 | name: "{{ remote_deploy_group }}" 51 | 52 | - name: Add {remote_deploy_user} user 53 | user: 54 | name: "{{ remote_deploy_user }}" 55 | home: "{{ remote_deploy_home }}" 56 | group: "{{ remote_deploy_group }}" 57 | 58 | - name: Add ssh keys to root and deploy accounts 59 | authorized_key: 60 | user: "{{ item }}" 61 | key: "{{ lookup('file', ssh_key_pub_path) }}" 62 | with_items: 63 | - root 64 | - "{{ remote_deploy_user }}" 65 | -------------------------------------------------------------------------------- /roles/hhvm/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add HHVM apt-key 3 | apt_key: url="http://dl.hhvm.com/conf/hhvm.gpg.key" state=present 4 | 5 | - name: Add HHVM deb 6 | apt_repository: repo="deb http://dl.hhvm.com/ubuntu {{ ansible_distribution_release }} main" 7 | state=present 8 | 9 | - name: Install HHVM 10 | apt: pkg=hhvm state=latest force=yes 11 | 12 | - name: HHVM server.ini 13 | template: src=server.ini.j2 dest=/etc/hhvm/server.ini 14 | 15 | - name: HHVM php.ini 16 | template: src=php.ini.j2 dest=/etc/hhvm/php.ini 17 | 18 | - name: Symlink mysql.sock for HHVM 19 | file: src=/var/run/mysqld/mysqld.sock dest=/tmp/mysql.sock owner=mysql group=mysql state=link force=yes 20 | 21 | - name: Disable HHVM from starting on boot 22 | service: name=hhvm state=stopped enabled=no 23 | 24 | 25 | - name: Start HHVM 26 | service: name=hhvm state=started 27 | when: hhvm_start is defined -------------------------------------------------------------------------------- /roles/hhvm/templates/php.ini.j2: -------------------------------------------------------------------------------- 1 | ; {{ ansible_managed }} 2 | 3 | ; php options 4 | session.save_handler = files 5 | session.save_path = /var/lib/php5 6 | session.gc_maxlifetime = 1440 7 | 8 | ; hhvm specific 9 | hhvm.log.level = Warning 10 | hhvm.log.always_log_unhandled_exceptions = true 11 | hhvm.log.runtime_error_reporting_level = 8191 12 | hhvm.mysql.socket = /var/run/mysqld/mysqld.sock 13 | hhvm.mysql.typed_results = false 14 | -------------------------------------------------------------------------------- /roles/hhvm/templates/server.ini.j2: -------------------------------------------------------------------------------- 1 | ; {{ ansible_managed }} 2 | 3 | ; php options 4 | 5 | pid = /var/run/hhvm/pid 6 | 7 | ; hhvm specific 8 | 9 | hhvm.server.port = 9000 10 | hhvm.server.type = fastcgi 11 | hhvm.server.default_document = index.php 12 | hhvm.log.use_log_file = true 13 | hhvm.log.file = /var/log/hhvm/error.log 14 | hhvm.repo.central.path = /var/run/hhvm/hhvm.hhbc 15 | -------------------------------------------------------------------------------- /roles/mariadb/defaults/main.yml: -------------------------------------------------------------------------------- 1 | keyserver_fingerprint: "0xcbcb082a1bb943db" 2 | mirror: nyc2.mirrors.digitalocean.com 3 | version: "10.0" 4 | -------------------------------------------------------------------------------- /roles/mariadb/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add MariaDB MySQL apt-key 3 | apt_key: url="http://keyserver.ubuntu.com/pks/lookup?op=get&fingerprint=on&search={{ keyserver_fingerprint }}" state=present 4 | 5 | - name: Add MariaDB MySQL deb and deb-src 6 | apt_repository: repo="{{ item }}" state=present 7 | with_items: 8 | - "deb http://{{ mirror }}/mariadb/repo/{{ version }}/{{ ansible_distribution | lower }} {{ mariadb_dist | default(ansible_distribution_release) }} main" 9 | - "deb-src http://{{ mirror }}/mariadb/repo/{{ version }}/{{ ansible_distribution | lower }} {{ mariadb_dist | default(ansible_distribution_release) }} main" 10 | 11 | - name: Install MariaDB MySQL server 12 | apt: name=mariadb-server state=present update_cache=yes 13 | 14 | - name: Start MariaDB MySQL Server 15 | service: name=mysql state=started enabled=true 16 | 17 | - name: Set root user password 18 | mysql_user: name=root 19 | password="{{ mysql_root_password }}" 20 | check_implicit_admin=yes 21 | login_user=root 22 | login_password="" 23 | state=present 24 | 25 | - name: Delete anonymous MySQL server user for current hostname 26 | mysql_user: user="" 27 | host="{{ ansible_hostname }}" 28 | state=absent 29 | login_user=root 30 | login_password="{{ mysql_root_password }}" 31 | 32 | - name: Remove the test database 33 | mysql_db: name=test 34 | state=absent 35 | login_user=root 36 | login_password="{{ mysql_root_password }}" 37 | -------------------------------------------------------------------------------- /roles/monit/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install Monit monitoring daemon 4 | apt: name=monit 5 | 6 | - name: Disable monit from starting on boot 7 | service: name=monit enabled=no state=stopped 8 | -------------------------------------------------------------------------------- /roles/nginx/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | logs_root: /var/log/nginx/ 3 | -------------------------------------------------------------------------------- /roles/nginx/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload nginx 4 | service: name=nginx state=reloaded 5 | 6 | - name: start nginx 7 | service: name=nginx state=started -------------------------------------------------------------------------------- /roles/nginx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add Nginx PPA 3 | apt_repository: repo="ppa:rtcamp/nginx" update_cache=yes 4 | when: ansible_distribution == 'Ubuntu' 5 | 6 | - name: Add Nginx Debian repo 7 | apt_repository: repo="{{ item }}" state=present 8 | with_items: 9 | - "deb http://ftp.debian.org/debian/ testing main contrib non-free" 10 | - "deb-src http://ftp.debian.org/debian/ testing main contrib non-free" 11 | when: ansible_distribution == 'Debian' 12 | 13 | - name: Install Nginx 14 | apt: name=nginx state=present force=yes 15 | 16 | - name: Create nginx.conf 17 | template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 18 | 19 | - name: Disable Nginx from starting on boot 20 | service: name=nginx enabled=no state=stopped 21 | 22 | - name: Disable default site 23 | file: path=/etc/nginx/sites-enabled/default state=absent 24 | 25 | - name: Create PHP-FPM WordPress site configuration 26 | template: src=wp-php-fpm.conf.j2 27 | dest=/etc/nginx/sites-available/wp-php-fpm.conf 28 | 29 | - name: Enable PHP-FPM WordPress site configuration 30 | file: src="/etc/nginx/sites-available/wp-php-fpm.conf" 31 | dest="/etc/nginx/sites-enabled/wp-php-fpm.conf" 32 | owner=root 33 | group=root 34 | state=link 35 | notify: start nginx 36 | when: wp_php_fpm is defined 37 | 38 | - name: Create HHVM WordPress site configuration 39 | template: src=wp-hhvm.conf.j2 40 | dest=/etc/nginx/sites-available/wp-hhvm.conf 41 | 42 | - name: Enable HHVM WordPress site configuration 43 | file: src="/etc/nginx/sites-available/wp-hhvm.conf" 44 | dest="/etc/nginx/sites-enabled/wp-hhvm.conf" 45 | owner=root 46 | group=root 47 | state=link 48 | notify: start nginx 49 | when: wp_hhvm is defined 50 | 51 | - name: Create HHVM WordPress site configuration with FastCGI caching 52 | template: src=wp-hhvm-fastcgi-cache.conf.j2 53 | dest=/etc/nginx/sites-available/wp-hhvm-fastcgi-cache.conf 54 | 55 | - name: Enable HHVM WordPress site configuration with FastCGI caching 56 | file: src="/etc/nginx/sites-available/wp-hhvm-fastcgi-cache.conf" 57 | dest="/etc/nginx/sites-enabled/wp-hhvm-fastcgi-cache.conf" 58 | owner=root 59 | group=root 60 | state=link 61 | notify: start nginx 62 | when: wp_hhvm_cache is defined 63 | -------------------------------------------------------------------------------- /roles/nginx/templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | # nginx Configuration File 4 | # http://wiki.nginx.org/Configuration 5 | 6 | # Run as a less privileged user for security reasons. 7 | user www-data; 8 | 9 | pid /run/nginx.pid; 10 | 11 | # How many worker threads to run; 12 | # "auto" sets it to the number of CPU cores available in the system, and 13 | # offers the best performance. Don't set it higher than the number of CPU 14 | # cores if changing this parameter. 15 | # 16 | # The maximum number of connections for Nginx is calculated by: 17 | # max_clients = worker_processes * worker_connections 18 | worker_processes auto; 19 | 20 | 21 | # Maximum open file descriptors per process; 22 | # should be > worker_connections. 23 | worker_rlimit_nofile 100000; 24 | 25 | events { 26 | # When you need > 8000 * cpu_cores connections, you start optimizing your OS, 27 | # and this is probably the point at which you hire people who are smarter than 28 | # you, as this is *a lot* of requests. 29 | worker_connections 10240; 30 | 31 | # Allow worker processes to accept all new connections at a time. 32 | multi_accept on; 33 | 34 | # Efficient connection processing method, used on Linux 2.6+ 35 | use epoll; 36 | } 37 | 38 | 39 | 40 | http { 41 | 42 | # Hide nginx version information. 43 | server_tokens off; 44 | 45 | # Define the MIME types for files. 46 | include mime.types; 47 | default_type application/octet-stream; 48 | 49 | # Speed up file transfers by using sendfile() to copy directly 50 | # between descriptors rather than using read()/write(). 51 | sendfile on; 52 | 53 | # Tell Nginx not to send out partial frames; this increases throughput 54 | # since TCP frames are filled up before being sent out. (adds TCP_CORK) 55 | tcp_nopush on; 56 | 57 | tcp_nodelay on; 58 | 59 | # How long to allow each connection to stay idle; longer values are better 60 | # for each individual client, particularly for SSL, but means that worker 61 | # connections are tied up longer. (Default: 65) 62 | keepalive_timeout 30 30; 63 | 64 | 65 | # Sets the maximum number of requests that can be served through one keep-alive connection. 66 | # After the maximum number of requests are made, the connection is closed. 67 | keepalive_requests 100000; 68 | 69 | # Enables or disables resetting timed out connections. 70 | reset_timedout_connection on; 71 | 72 | # Enables or disables the use of the primary server name, specified by the server_name directive, 73 | # in redirects issued by nginx. 74 | server_name_in_redirect off; 75 | 76 | # Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field. 77 | # If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) 78 | # error is returned to the client. 79 | client_max_body_size 512m; 80 | 81 | # Sets buffer size for reading client request body. In case the request body is larger than the buffer, 82 | # the whole body or only its part is written to a temporary file. 83 | client_body_buffer_size 10k; 84 | 85 | # Defines a timeout for reading client request body. The timeout is set only for a period between two successive 86 | # read operations, not for the transmission of the whole request body. If a client does not transmit anything 87 | # within this time, the 408 (Request Time-out) error is returned to the client. 88 | client_body_timeout 30; 89 | 90 | # Defines a timeout for reading client request header. If a client does not transmit the entire header within 91 | # this time, the 408 (Request Time-out) error is returned to the client. 92 | client_header_timeout 30; 93 | 94 | # Sets a timeout for transmitting a response to the client. The timeout is set only between two successive write 95 | # operations, not for the transmission of the whole response. If the client does not receive anything within 96 | # this time, the connection is closed. 97 | send_timeout 30; 98 | 99 | # Sets buffer size for reading client request header. For most requests, a buffer of 1K bytes is enough. 100 | client_header_buffer_size 256k; 101 | 102 | # Sets the maximum number and size of buffers used for reading large client request header. 103 | large_client_header_buffers 4 256k; 104 | 105 | # Configures a cache that can store: 106 | 107 | # - open file descriptors, their sizes and modification times; 108 | # - information on existence of directories; 109 | # - file lookup errors, such as “file not found”, “no read permission”, and so on. 110 | open_file_cache max=200000 inactive=20s; 111 | open_file_cache_valid 30s; 112 | open_file_cache_min_uses 2; 113 | open_file_cache_errors on; 114 | 115 | # Update charset_types due to updated mime.types 116 | charset_types text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml text/css application/javascript application/json; 117 | 118 | ## 119 | # Logging Settings 120 | ## 121 | 122 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 123 | '$status $body_bytes_sent "$http_referer" ' 124 | '"$http_user_agent" "$http_x_forwarded_for"'; 125 | 126 | # Default log file 127 | # (this is only used when you don't override access_log on a server{} level) 128 | 129 | # access_log {{ logs_root }}/access.log main buffer=16k; 130 | access_log off; 131 | 132 | # Default error log file 133 | # (this is only used when you don't override error_log on a server{} level) 134 | error_log {{ logs_root }}/error.log warn; 135 | 136 | ## 137 | # Gzip Settings 138 | ## 139 | 140 | # Enable Gzip compression. 141 | gzip on; 142 | 143 | # Compression level (1-9). 144 | # 5 is a perfect compromise between size and cpu usage, offering about 145 | # 75% reduction for most ascii files (almost identical to level 9). 146 | gzip_comp_level 5; 147 | 148 | # Don't compress anything that's already small and unlikely to shrink much 149 | # if at all (the default is 20 bytes, which is bad as that usually leads to 150 | # larger files after gzipping). 151 | gzip_min_length 256; 152 | 153 | # Compress data even for clients that are connecting to us via proxies, 154 | # identified by the "Via" header (required for CloudFront). 155 | gzip_proxied any; 156 | 157 | # Tell proxies to cache both the gzipped and regular version of a resource 158 | # whenever the client's Accept-Encoding capabilities header varies; 159 | # Avoids the issue where a non-gzip capable client (which is extremely rare 160 | # today) would display gibberish if their proxy gave them the gzipped version. 161 | gzip_vary on; 162 | 163 | # Sets the number and size of buffers used to compress a response. 164 | gzip_buffers 128 8k; 165 | 166 | # Compress all output labeled with one of the following MIME-types. 167 | gzip_types 168 | application/atom+xml 169 | application/javascript 170 | application/json 171 | application/rss+xml 172 | application/vnd.ms-fontobject 173 | application/x-font-ttf 174 | application/x-web-app-manifest+json 175 | application/xhtml+xml 176 | application/xml 177 | font/opentype 178 | image/svg+xml 179 | image/x-icon 180 | text/css 181 | text/plain 182 | text/x-component; 183 | # text/html is always compressed by HttpGzipModule 184 | 185 | # Disable gzip compression for IE 1-6 186 | gzip_disable "MSIE [1-6]\."; 187 | 188 | 189 | # This should be turned on if you are going to have pre-compressed copies (.gz) of 190 | # static files available. If not it should be left off as it will cause extra I/O 191 | # for the check. It is best if you enable this in a location{} block for 192 | # a specific directory, or on an individual server{} level. 193 | # gzip_static on; 194 | 195 | include sites-enabled/*; 196 | } 197 | -------------------------------------------------------------------------------- /roles/nginx/templates/wp-hhvm-fastcgi-cache.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | # FastCGI caching 4 | 5 | # Set location, zone keys, storage (in MB) and minutes to keep the cached assets if not accessed 6 | # You should put it on a tmpfs partition so it gets cached into RAM 7 | fastcgi_cache_path /run/nginx-cache levels=1:2 keys_zone=WordPress:100m inactive=60m; 8 | 9 | # Caching schema 10 | fastcgi_cache_key "$scheme$request_method$host$server_port$request_uri"; 11 | 12 | # Ignore requests to purge the cache 13 | fastcgi_ignore_headers Cache-Control Expires Set-Cookie; 14 | 15 | # Use stale (old) cached assets on error, timeout, invalid headers or when updating the cache 16 | fastcgi_cache_use_stale error timeout invalid_header updating; 17 | 18 | server { 19 | root {{ remote_wordpress_dir }}; 20 | 21 | index index.php index.html; 22 | 23 | location / { 24 | try_files $uri $uri/ /index.php; 25 | } 26 | 27 | 28 | # Don't skip cache by default 29 | set $skip_cache 0; 30 | 31 | # Skip cache if query string in URI (e.g. ?s=test) 32 | #if ($query_string != "") { 33 | # set $skip_cache 1; 34 | #} 35 | 36 | # Don't cache URIs containing the following segments 37 | if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") { 38 | set $skip_cache 1; 39 | } 40 | 41 | # Don't use the cache for logged in users or recent commenters 42 | if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { 43 | set $skip_cache 1; 44 | } 45 | 46 | location ~ \.php$ { 47 | try_files $uri =404; 48 | 49 | # FastCGI Caching 50 | 51 | # Which zone to apply 52 | fastcgi_cache WordPress; 53 | 54 | # Cache for 60 minutes 55 | fastcgi_cache_valid 60m; 56 | 57 | # Cache only GET and HEAD methods 58 | fastcgi_cache_methods GET HEAD; 59 | 60 | # Skip cache in certain conditions 61 | fastcgi_cache_bypass $skip_cache; 62 | fastcgi_no_cache $skip_cache; 63 | 64 | # Add header informing about the cache status (MISS|HIT|BYPASS) 65 | add_header X-Fastcgi-Cache $upstream_cache_status; 66 | 67 | include fastcgi_params; 68 | 69 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 70 | fastcgi_param DOCUMENT_ROOT $realpath_root; 71 | 72 | fastcgi_pass 127.0.0.1:9000; 73 | 74 | client_max_body_size 0; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /roles/nginx/templates/wp-hhvm.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | server { 4 | root {{ remote_wordpress_dir }}; 5 | 6 | index index.php index.html; 7 | 8 | location / { 9 | try_files $uri $uri/ /index.php; 10 | } 11 | 12 | 13 | location ~ \.php$ { 14 | try_files $uri =404; 15 | 16 | include fastcgi_params; 17 | 18 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 19 | fastcgi_param DOCUMENT_ROOT $realpath_root; 20 | 21 | fastcgi_pass 127.0.0.1:9000; 22 | 23 | client_max_body_size 0; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /roles/nginx/templates/wp-php-fpm.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | server { 4 | root {{ remote_wordpress_dir }}; 5 | 6 | index index.php index.html; 7 | 8 | location / { 9 | try_files $uri $uri/ /index.php; 10 | } 11 | 12 | 13 | location ~ \.php$ { 14 | try_files $uri =404; 15 | 16 | include fastcgi_params; 17 | 18 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 19 | fastcgi_param DOCUMENT_ROOT $realpath_root; 20 | 21 | fastcgi_pass 127.0.0.1:9000; 22 | 23 | client_max_body_size 0; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /roles/php-fpm/defaults/main.yml: -------------------------------------------------------------------------------- 1 | disable_default_pool: true 2 | 3 | php_error_reporting: 'E_ALL & ~E_DEPRECATED & ~E_STRICT' 4 | php_display_errors: 'Off' 5 | php_display_startup_errors: 'Off' 6 | php_max_execution_time: 120 7 | php_max_input_time: 300 8 | php_max_input_vars: 1000 9 | php_memory_limit: 96M 10 | php_mysqlnd_collect_memory_statistics: 'Off' 11 | php_post_max_size: 25M 12 | php_sendmail_path: /usr/sbin/ssmtp -t 13 | php_session_save_path: /tmp 14 | php_upload_max_filesize: 25M 15 | php_track_errors: 'Off' 16 | 17 | php_opcache_enable: 1 18 | php_opcache_enable_cli: 1 19 | php_opcache_fast_shutdown: 1 20 | php_opcache_interned_strings_buffer: 8 21 | php_opcache_max_accelerated_files: 4000 22 | php_opcache_memory_consumption: 128 23 | php_opcache_memory_consumption: 128 24 | php_opcache_revalidate_freq: 60 25 | -------------------------------------------------------------------------------- /roles/php-fpm/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: reload php-fpm 4 | service: name=php5-fpm state=reloaded -------------------------------------------------------------------------------- /roles/php-fpm/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | dependencies: 4 | - { role: php } 5 | -------------------------------------------------------------------------------- /roles/php-fpm/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install PHP-FPM v5.6 4 | apt: name="{{ item }}" state=present force=yes 5 | with_items: 6 | - php5-fpm 7 | 8 | - name: Disable PHP-FPM from starting on boot 9 | service: name=php5-fpm state=stopped enabled=no 10 | 11 | - name: Create socket directory 12 | file: path=/var/run/php5-fpm/ state=directory 13 | 14 | - name: Disable default pool 15 | command: mv /etc/php5/fpm/pool.d/www.conf /etc/php5/fpm/pool.d/www.disabled creates=/etc/php5/fpm/pool.d/www.disabled 16 | 17 | - name: Add php.ini template 18 | template: src=php.ini.j2 dest=/etc/php5/fpm/php.ini 19 | 20 | - name: Copy php-fpm configuration 21 | template: src="php-fpm.conf.j2" dest="/etc/php5/fpm/pool.d/wordpress.conf" 22 | 23 | - name: Start PHP-FPM 24 | service: name=php5-fpm state=started 25 | when: fpm_start is defined 26 | -------------------------------------------------------------------------------- /roles/php-fpm/templates/php-fpm.conf.j2: -------------------------------------------------------------------------------- 1 | ; {{ ansible_managed }} 2 | 3 | [wordpress] 4 | listen = 127.0.0.1:9000 5 | listen.owner = www-data 6 | listen.group = www-data 7 | user = www-data 8 | group = www-data 9 | pm = dynamic 10 | pm.max_children = 10 11 | pm.start_servers = 1 12 | pm.min_spare_servers = 1 13 | pm.max_spare_servers = 3 14 | pm.max_requests = 500 15 | chdir = {{ remote_www_dir }}/ 16 | php_admin_value[open_basedir] = {{ remote_www_dir }}/:/tmp 17 | 18 | -------------------------------------------------------------------------------- /roles/php-fpm/templates/php.ini.j2: -------------------------------------------------------------------------------- 1 | ; {{ ansible_managed }} 2 | 3 | [PHP] 4 | error_reporting = {{ php_error_reporting }} 5 | display_errors = {{ php_display_errors }} 6 | display_startup_errors = {{ php_display_startup_errors }} 7 | max_execution_time = {{ php_max_execution_time }} 8 | max_input_time = {{ php_max_input_time }} 9 | max_input_vars = {{ php_max_input_vars }} 10 | memory_limit = {{ php_memory_limit }} 11 | post_max_size = {{ php_post_max_size }} 12 | sendmail_path = {{ php_sendmail_path }} 13 | session.save_path = {{ php_session_save_path }} 14 | track_errors = {{ php_track_errors }} 15 | upload_max_filesize = {{ php_upload_max_filesize }} 16 | 17 | [mysqlnd] 18 | mysqlnd.collect_memory_statistics = {{ php_mysqlnd_collect_memory_statistics }} 19 | 20 | [opcache] 21 | opcache.enable = {{ php_opcache_enable }} 22 | opcache.enable_cli = {{ php_opcache_enable_cli }} 23 | opcache.memory_consumption = {{ php_opcache_memory_consumption }} 24 | opcache.interned_strings_buffer = {{ php_opcache_interned_strings_buffer }} 25 | opcache.max_accelerated_files = {{ php_opcache_max_accelerated_files }} 26 | opcache.revalidate_freq = {{ php_opcache_revalidate_freq }} 27 | opcache.fast_shutdown = {{ php_opcache_fast_shutdown }} 28 | 29 | [hhvm] 30 | hhvm.log.level = Warning 31 | hhvm.log.always_log_unhandled_exceptions = true 32 | hhvm.log.runtime_error_reporting_level = 8191 33 | hhvm.mysql.socket = /var/run/mysqld/mysqld.sock 34 | hhvm.mysql.typed_results = false 35 | -------------------------------------------------------------------------------- /roles/php/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Add PHP v5.6 apt repository 4 | apt_repository: 5 | repo: 'ppa:ondrej/php5-5.6' 6 | when: ansible_distribution == 'Ubuntu' 7 | 8 | - name: Install PHP v5.6 for WP-CLI support 9 | apt: name={{ item }} 10 | with_items: 11 | - php5 12 | - php5-common 13 | - php5-mysqlnd 14 | - php5-mcrypt 15 | - php5-curl 16 | - php5-cli 17 | - php-pear 18 | -------------------------------------------------------------------------------- /roles/redis/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | dependencies: 4 | - { role: php } 5 | -------------------------------------------------------------------------------- /roles/redis/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install Redis server and PHP-Redis library 4 | apt: name={{ item }} 5 | with_items: 6 | - redis-server 7 | - php5-redis 8 | 9 | - name: Disable Redis server from starting on boot 10 | service: name=redis-server state=stopped enabled=no 11 | -------------------------------------------------------------------------------- /roles/reset-all-configs/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: stop nginx 4 | service: name=nginx state=stopped 5 | 6 | - name: stop apache2 7 | service: name=apache2 state=stopped 8 | 9 | - name: stop php-fpm 10 | service: name=php-fpm state=stopped 11 | 12 | - name: stop hhvm 13 | service: name=hhvm state=stopped 14 | 15 | - name: stop redis-server 16 | service: name=redis-server state=stopped 17 | -------------------------------------------------------------------------------- /roles/reset-all-configs/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Reset Nginx enabled sites 4 | shell: rm -rf /etc/nginx/sites-enabled/* 5 | 6 | - name: Reset Apache2 enabled sites 7 | shell: rm -rf /etc/apache2/sites-enabled/* 8 | 9 | - name: Stop services 10 | include: stop-services.yml 11 | -------------------------------------------------------------------------------- /roles/reset-all-configs/tasks/stop-services.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Stop Nginx 4 | service: name=nginx state=stopped 5 | 6 | - name: Stop Apache2 7 | service: name=apache2 state=stopped 8 | 9 | - name: Stop PHP-FPM 10 | service: name=php5-fpm state=stopped 11 | 12 | - name: Stop HHVM 13 | service: name=hhvm state=stopped 14 | 15 | - name: Stop Redis 16 | service: name=redis-server state=stopped 17 | -------------------------------------------------------------------------------- /roles/reset-wordpress/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Drop WordPress database 4 | mysql_db: name="{{ wordpress_db_name }}" 5 | state=absent 6 | login_user=root 7 | login_password="{{ mysql_root_password }}" 8 | 9 | - name: Drop WordPress DB user 10 | mysql_user: name="{{ wordpress_db_user }}" 11 | state=absent 12 | login_user="root" 13 | login_password="{{ mysql_root_password }}" 14 | 15 | - name: Remove WordPress directory 16 | file: path="{{ remote_wordpress_dir }}" 17 | state=absent 18 | -------------------------------------------------------------------------------- /roles/web-caching/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Start Redis 4 | service: name=redis-server state=started 5 | when: wp_redis is defined 6 | remote_user: root 7 | 8 | - name: Install WP Redis WordPress plugin 9 | command: "wp plugin install wp-redis" 10 | args: 11 | chdir: "{{ remote_wordpress_dir }}" 12 | when: wp_redis is defined 13 | 14 | - name: Symlink WP Redis object-cache.php to wp-content/ 15 | file: 16 | src: "{{ remote_wordpress_dir }}/wp-content/plugins/wp-redis/object-cache.php" 17 | path: "{{ remote_wordpress_dir }}/wp-content/object-cache.php" 18 | state: link 19 | when: wp_redis is defined 20 | -------------------------------------------------------------------------------- /roles/wordpress-install/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create WordPress database 3 | mysql_db: name="{{ wordpress_db_name }}" 4 | state=present 5 | login_user=root 6 | login_password="{{ mysql_root_password }}" 7 | 8 | - name: Create WordPress DB user and grant permissions to WordPress DB 9 | mysql_user: name="{{ wordpress_db_user }}" 10 | password="{{ wordpress_db_user_pass }}" 11 | priv="{{ wordpress_db_name }}.*:ALL" 12 | state=present 13 | login_user="root" 14 | login_password="{{ mysql_root_password }}" 15 | 16 | - name: Is WordPress downloaded? 17 | stat: path="{{ remote_wordpress_dir }}/index.php" 18 | register: wp_dir 19 | 20 | - name: Create WordPress directory 21 | file: path="{{ remote_wordpress_dir }}" 22 | owner="{{ remote_deploy_user }}" 23 | group="{{ remote_deploy_group }}" 24 | mode=0755 25 | state=directory 26 | when: wp_dir.stat.isdir is not defined 27 | 28 | - name: Download WordPress 29 | command: wp core download 30 | args: 31 | chdir: "{{ remote_wordpress_dir }}/" 32 | remote_user: "{{ remote_deploy_user }}" 33 | when: wp_dir.stat.isdir is not defined 34 | 35 | - name: Configure WordPress 36 | command: wp core config 37 | --path="{{ remote_wordpress_dir }}" 38 | --dbname="{{ wordpress_db_name }}" 39 | --dbuser="{{ wordpress_db_user }}" 40 | --dbpass="{{ wordpress_db_user_pass }}" 41 | --dbprefix="{{ wordpress_db_prefix }}" 42 | remote_user: "{{ remote_deploy_user }}" 43 | when: wp_dir.stat.isdir is not defined 44 | 45 | - name: Is WordPress installed? 46 | command: wp core is-installed 47 | args: 48 | chdir: "{{ remote_wordpress_dir }}/" 49 | register: wordpress_is_installed 50 | ignore_errors: True 51 | remote_user: "{{ remote_deploy_user }}" 52 | 53 | - name: Install WordPress tables 54 | command: wp core install 55 | --url="{{ wordpress_home_url }}" 56 | --title="{{ wordpress_site_title }}" 57 | --admin_user="{{ wordpress_admin_user }}" 58 | --admin_password="{{ wordpress_admin_user_pass }}" 59 | --admin_email="{{ wordpress_admin_email }}" 60 | args: 61 | chdir: "{{ remote_wordpress_dir }}/" 62 | when: wordpress_is_installed|failed 63 | remote_user: "{{ remote_deploy_user }}" 64 | 65 | - name: Install WordPress theme 66 | command: "wp theme install {{ wordpress_theme }} --activate" 67 | args: 68 | chdir: "{{ remote_wordpress_dir }}" 69 | when: wp_advanced is defined 70 | 71 | - name: Install WordPress plugins 72 | command: "wp plugin install {{ item }} --activate" 73 | args: 74 | chdir: "{{ remote_wordpress_dir }}" 75 | with_items: wordpress_plugins 76 | when: wp_advanced is defined 77 | 78 | - name: Download WordPress dummy data 79 | get_url: 80 | url: https://raw.githubusercontent.com/manovotny/wptest/master/wptest.xml 81 | dest: "{{ remote_wordpress_dir }}/wptest.xml" 82 | when: wp_advanced is defined 83 | 84 | - name: Import WordPress dummy data 85 | command: "wp import {{ item }} --authors=create" 86 | args: 87 | chdir: "{{ remote_wordpress_dir }}" 88 | with_items: 89 | - wp-content/plugins/woocommerce/dummy-data/dummy-data.xml 90 | - wptest.xml 91 | when: wp_dummy_data is defined 92 | -------------------------------------------------------------------------------- /roles/wp-cli/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | dependencies: 4 | - { role: php } 5 | -------------------------------------------------------------------------------- /roles/wp-cli/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Download WP-CLI 4 | shell: curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar 5 | 6 | - name: Make WP-CLI executable 7 | file: 8 | path: /root/wp-cli.phar 9 | mode: u=rwx,g=rx,o=rx 10 | 11 | - name: Move WP-CLI to /usr/local/bin/wp 12 | command: mv /root/wp-cli.phar /usr/local/bin/wp 13 | 14 | -------------------------------------------------------------------------------- /wordpress_advanced.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: WordPress with WooCommerce, Jetpack, custom theme and dummy data 3 | 4 | hosts: webservers 5 | remote_user: deploy 6 | vars: 7 | wp_advanced: true 8 | wp_dummy_data: true 9 | 10 | roles: 11 | - reset-wordpress 12 | - wordpress-install 13 | 14 | -------------------------------------------------------------------------------- /wordpress_basic.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: WordPress with default theme and no dummy data. 3 | 4 | hosts: webservers 5 | remote_user: deploy 6 | 7 | roles: 8 | - reset-wordpress 9 | - wordpress-install 10 | 11 | -------------------------------------------------------------------------------- /wordpress_redis_db_cache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: WordPress with Redis database caching. Requires WordPress installed. 3 | 4 | hosts: webservers 5 | remote_user: deploy 6 | vars: 7 | wp_redis: True 8 | 9 | roles: 10 | - web-caching 11 | 12 | --------------------------------------------------------------------------------