diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6a139e..614c140 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,48 +8,55 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [2.2.0] - 2018-06-02
### Added
-- Enabled private network settings
-- Added configuration parameters for RSA key and github authentication
-- Added vagrant-hostsupdater to set host's `/etc/hosts` file automatically
+
+ - Enabled private network settings
+ - Added configuration parameters for RSA key and github authentication
+ - Added vagrant-hostsupdater to set host's `/etc/hosts` file automatically
### Changed
-- Changed php role to setup xdebug properly
-- Changed the order and depedencies for apache and php roles
-- Changed roles include in the playbook to be configurable in
-- Changed `variables.yml` into `default.config.yml` and requires it to be copied
- into `config.yml` for configuration of devbox
-- Cleaned up `projects` variable
+
+ - Changed php role to setup xdebug properly
+ - Changed the order and depedencies for apache and php roles
+ - Changed roles include in the playbook to be configurable in
+ - Changed `variables.yml` into `default.config.yml` and requires it to be copied into `config.yml` for configuration of devbox
+ - Cleaned up `projects` variable
### Removed
-- Removed temporarly enabed public network
+
+ - Removed temporarly enabed public network
## [2.1.0] - 2017-04-08
### Added
-- New project role to handle project specific configuration
-- Added `php-mbstring`
-- Changed host with new Ansible variable syntax (> 2.0)
-- Splits several YAML files into multiple and adds include statements to
- individual `main.yml` files.
+
+ - New project role to handle project specific configuration
+ - Added `php-mbstring`
+ - Changed host with new Ansible variable syntax (> 2.0)
+ - Splits several YAML files into multiple and adds include statements to
+ individual `main.yml` files.
### Removed
-- All configuration regarding projects (vhost and database) now resides with the
-project role.
+
+ - All configuration regarding projects (vhost and database) now resides with the
+ project role.
## [2.0.0] - 2017-04-06
### Added
-- Split the code into roles to be more manageable
-- Adds CHANGELOG.md
-- Tags release 1.0.0
+
+ - Split the code into roles to be more manageable
+ - Adds CHANGELOG.md
+ - Tags release 1.0.0
### Change
-- Changes to ansible code syntax to be compatible with Ansible 2.2.1
-- Changes to vagrant code syntax to be compatible with Vagrant 1.9.2
-- Changes to vagrant to use Ubuntu Xenial 16.04
+
+ - Changes to ansible code syntax to be compatible with Ansible 2.2.1
+ - Changes to vagrant code syntax to be compatible with Vagrant 1.9.2
+ - Changes to vagrant to use Ubuntu Xenial 16.04
## [1.0.0] - 2015-08-24
### Added
-- First release of code
+
+ - First release of code
diff --git a/README.md b/README.md
index e386756..a5bfd7f 100644
--- a/README.md
+++ b/README.md
@@ -2,22 +2,19 @@
## Prerequisites
-Devbox is a virtual devevelopment box for PHP and JavaScruipt development
+Devbox is a virtual devevelopment box for PHP and JavaScript development
(including frameworks like Hugo, Symfony, WordPress and Drupal). Using the LAMP
stack provided you can start development without worrying about setting up your
computer as a development environment.
Devbox works with the following software:
- - Vagrant >= 2.1.1
- - Ansible >= 2.5
- - VirtualBox
- - Ubuntu Xenial 16.04
+ - Vagrant >= 2.2.10
+ - Ansible >= 2.9.6
+ - VirtualBox >= 6.1
+ - Ubuntu 20.04.1 LTS (Focal Fossa)
-Devbox assumes that projects are developed with Git and requires a valid RSA key
-from the local user which has been added in Github.
-
-## Usage
+## Install
Get devbox in your local machine:
@@ -38,69 +35,120 @@ environment:
vagrant up
```
-You can login to the devbox with the following command:
+## Basic usage
+
+Login to devbox via SSH:
```
vagrant ssh
```
-Happy coding! See below for configuration parameters.
+For server changes in `config.yml` to take effect (e.g. add a new project) you
+need to reprovision the environment:
+
+```
+vagrant provision
+```
+
+For virtual machine changes in `config.yml` to take effect (e.g. change the IP
+address) you need to reload the configuration:
+
+```
+varnish reload
+```
+
+To access vagrant help:
+
+```
+vagrant help
+```
## Configuration
The development environment can be customised via the `config.yml` file and the
-variables contained within.
+variables contained within.
+
+### Configuring the VM
-### Configuring a remote user
+The virtual machine can be automatically configured via the variables in
+**Machine** and **Folder mapping**. There are a number of options that allow
+devbox to operate in various conditions.
-The `remote_user` variable is used to set the user in the guest machine. The
-default user in Vagrant is ubuntu and is reccomended to be left as is.
+Folder mapping is achieved through NFS and bindfs to ensure that permisions are
+set as expected. By default devbox is using 775 for directories and 644 for
+files but behaviour can be overriden via `vm_folder_perm`.
-### Configuring an RSA key
+### Configuring Git, an RSA key and repositories
-The `rsa_key` variable accepts as input a path from the host machine which
-should resolve to an rsa key. It is used to authenticate in github and should be
-added there prior to any git related operations in the development server.
+The git configuration section contains variables that control the configuration
+of Git and RSA keys. You can control how your local key is named in devbox so
+you can add your development key indepedently of any other key already set.
+
+The repositories configuration section contains a variable that is used to setup
+the devbox `~/.ssh/config` file. Public key fingerprints can be used to validate
+a connection to a remote server. Devbox automatically adds RSA fingerprints
+in `~/.ssh/known_hosts` for the repositories declared.
### Configuring the server stack
The `config_roles` variable is used to customise the software stack configured
in the server. Comment out roles not needed.
-### Configuring your projects
+### Configuring projects
Vagrant allows to share directories between the host and the guest
systems. Devbox takes advantage of that feature to expose local projects which
can then be served through the LAMP stack.
-Devbox expects a `projects` folder to exist in the same contains directory with
-devbox:
-
-```
-.
-├── devbox
-└── projects
- ├── projectA
- ├── projectB
- └── projectC
-```
-
-All directories contained withing projects will be exposed in `~/projects` in
-the guest system.
-
-For each project the following parameters can be set:
-
-- domain (string): The URI to access project.
-- docroot (string) The path of the project in devbox (user `{{ remote_user }}`
- for indepedence
-- db_user (string): The name of the database user to be used (root will be used
- if empty)
-- db_pass (string): The passwrd of the database user to be used (root will be used if empty)
-- db_name (string): The database name to be used (if empty database creation is skipped)
-- tech (string): The technology used in the project. Options include:
- - hugo
- - drupal
- - symfony
+Devbox is configurable to act as a standalone server hosting many projects or as
+a development environment within a particular project. In either case it expects
+that the folder containing the project or projects to be declared via
+`projects_path`.
+
+Each project is configured via the `projects` dictionary which accepts the
+following parameters:
+
+ - **domain** (_string_): The URI to access project in the browser. The value is
+ automatically picked up and added to `/etc/hosts`.
+ - **docroot** (_string_) The path of the project in devbox. Can be any
+ location or combined with `projects_path`.
+ - **type** (_string_): The technology used in the project. Options include:
+ empty, hugo, drupal, wordpress, symfony.
+ - **database** (_string_): The database to be used. If empty database creation is skipped
+ - **repo** (_string_): a git path to checkout existing projects (uses path)
+
+### Configuring Xdebug
+Xdebug is enabled by default but you would need to set it up to your IDE. For
+Eclipse you need to do the following:
+
+ 1. Add a new server
+ 2. Configure the new server with xdebug
+ 3. Run the debugger
+
+To setup a server go to `Window > Preferences > PHP > Servers` and add new. It
+will ask for the following:
+
+ - Server tab
+ - Server name: add the individual project name
+ - Base url: the domain configured in project
+ - Document root: the location of the project on your host system
+ - Debbuger tab
+ - Debugger: xdebug
+ - Port: 9000
+
+Next locate a file from your project in PHP Explorer, right click and select
+`Debug as > Debug configurations`. It will ask for the following:
+
+ - Server tab
+ - PHP server: select the one you just created
+ - File: select the project index file
+ - Debuger tab
+ - Ensure XDebug is selected
+ - Enable 'Break At First Line'
+ - Click debug
+
+This will launch a new window and a dialog box will appear informing about the
+debug perspective in Eclipse. Accept and start debugging.
### Configuring additional software to be added
@@ -109,63 +157,12 @@ the main build. It is intended for smaller packages that do not require
customisation. If more software with significant customisation is needed
consider to open a pull request.
-### Configuring Vagrant
-
-Devbox offers a complete development environment out of the box. Vagrant is
-controled through a `Vagrantfile` bunlded at the root of the repository. Within
-that file there are parameters about:
-
- - vagrant options about the base image, synchronising folders, network, etc
- - virtual machine options about memory, etc
- - provision options about ansible
-
-Please follow through [vagrant documentation](https://www.vagrantup.com/docs/)
-for a more thorough understanding of how it can be tweaked.
-
-## Usage
-
-### Using Vagrant
-
-To connect to the VM use the following:
-
-```
-vagrant ssh
-```
-
-For changes in `config.yml` to take effect use:
-
-```
-vagrant provision
-```
-
-For changes in `Vagrantfile` to take effect vagrant configuration need to be roloaded:
-
-```
-varnish reload
-```
-
-Access help via:
-
-```
-vagrant help
-```
-
-### Accessing projects
-
-Devbox listens to a private network with IP set to 10.10.10.10. Add an entry per
-project in your `/etc/hosts` file:
-
-```
-10.10.10.10 PROJECT_DOMAIN
-```
-
-Then point your browser to the domain in port 8000:
-
-```
-http://PROJECT_DOMAIN
-```
+### Configuring additional tasks to be performed
-You should see the homepage of your project.
+The `additional_tasks` variable allows additional tasks to be performed after
+the server has been provisioned. This can be used for some adhoc configuration
+like downloading emacs configuration specific to the user or adding custom
+aliases to `.bashrc`.
## Contributions
diff --git a/Vagrantfile b/Vagrantfile
index d1c31d0..6594b09 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -1,9 +1,25 @@
# Devbox Vagrant file.
-#
+require 'yaml'
+
# Look at default.config.yml for setting configuration parameters on this file.
VAGRANTFILE_API_VERSION = "2"
-required_plugins = %w(vagrant-hostsupdater)
+# Load configuration parameters from config file.
+config_yml = YAML.load_file("config.yml")
+
+# Project domains
+project_domains = []
+
+config_yml['projects'].each do |project|
+ project.each do |key, value|
+ if key == 'domain' and value != ""
+ project_domains.push(value)
+ end
+ end
+end
+
+# Install if required and load plugins.
+required_plugins = %w(vagrant-hostsupdater vagrant-bindfs vagrant-vbguest)
plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
if not plugins_to_install.empty?
@@ -15,31 +31,48 @@ if not plugins_to_install.empty?
end
end
+# Start configuring Vagrant
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
- # Create devbox with vagrant parameters
- config.vm.define "devbox" do |devbox|
- devbox.vm.box = "ubuntu/xenial64"
- devbox.vm.hostname = "dev.box"
- devbox.vm.network "private_network", ip: "10.10.10.10"
- devbox.vm.synced_folder "~/projects", "/home/ubuntu/projects",
- owner: "ubuntu", group: "www-data", mount_options: ["dmode=775,fmode=664"]
+ # Define VM parameters
+ config.vm.define config_yml['vm_name'] do |devbox|
+
+ # Operating system
+ devbox.vm.box = "ubuntu/focal64"
+
+ # Network
+ devbox.vm.network "private_network", ip: config_yml['vm_ip']
+ devbox.vm.hostname = config_yml['vm_hostname']
+ devbox.hostsupdater.aliases = project_domains
+
+ # Folders
+ devbox.vm.synced_folder config_yml['host_path'], config_yml['tmp_path'], type: config_yml['vm_network_type']
+
+ devbox.bindfs.bind_folder config_yml['tmp_path'], config_yml['guest_path'],
+ perms: config_yml['vm_folder_perm'],
+ force_user: config_yml['vm_user'],
+ force_group: config_yml['vm_group'],
+ create_as_user: true
end
# Virtualbox parameters
config.vm.provider "virtualbox" do |vb|
- vb.name = "devbox"
- vb.cpus = 2
- vb.customize ["modifyvm", :id, "--memory", "1024"]
+ vb.name = config_yml['vm_name']
+ vb.cpus = config_yml['vm_cpus']
+ vb.customize ["modifyvm", :id, "--memory", config_yml['vm_ram']]
+
+ # Workaround for ubuntu/focal64 and virtualbox 6.1
+ vb.customize ["modifyvm", :id, "--uartmode1", "file", File::NULL]
end
- # Workaround for ubuntu/xenial not having /usr/bin/python
- config.vm.provision "shell",
- inline: "if [[ ! -f /usr/bin/python ]]; then sudo ln -s /usr/bin/python3 /usr/bin/python; fi"
+ # # Workaround for ubuntu/xenial not having /usr/bin/python
+ # config.vm.provision "shell",
+ # inline: "if [[ ! -f /usr/bin/python ]]; then sudo ln -s /usr/bin/python3 /usr/bin/python; fi"
# Provision with Ansible
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbook.yml"
+ ansible.compatibility_mode = "2.0"
end
end
diff --git a/default.config.yml b/default.config.yml
index daf8253..a3c370b 100644
--- a/default.config.yml
+++ b/default.config.yml
@@ -2,65 +2,90 @@
# Configuration variables. #
############################
-# Remote user name used in devbox
-remote_user: ubuntu
+# Machine
+vm_name: "devbox"
+vm_hostname: "dev.box"
+vm_cpus: "4"
+vm_ram: "2048"
+vm_ip: "10.10.10.10"
+vm_user: "vagrant"
+vm_group: "www-data"
-# RSA key location
-rsa_key: "~/.ssh/id_rsa"
+# Folder mapping
+vm_network_type: "nfs"
+vm_folder_perm: "u=rwX:g=rwD"
+host_path: "~/projects"
+guest_path: "/home/vagrant/projects"
+tmp_path: "/home/vagrant/nfs"
-# Configuration of server stack
-#
-# Configuration of devbox functionality.
-#
-# Comment out the parameters that are not needed to ensure that roles are not
-# included in the project.
+# Git configuration
+git_user: ""
+git_email: ""
+git_rsa_key: "~/.ssh/id_rsa"
+git_rsa_key_dest: "~/.ssh/id_rsa"
+
+# Repositories
+repositories:
+ - { name: github, host: github.com }
+ - { name: bitbucket, host: bitbucket.com }
+
+repositories_count: "{{ repositories | length }}"
+rebuild_known_hosts: false
+
+# Environment variables
#
+# Append to add more
+# name - string (required) - name of environment variable
+# value - string (required) - value of environment variable
+
+environment_variables:
+ - { name: "ENV", value: "local" }
+
+# Software stack
config_roles:
+ - nodejs
- apache
- php
- mysql
- projects
-# Projects root
-projects_root: "/home/{{ remote_user }}/projects"
+# PHP
+php_memory_limit: "1536M"
+php_timezone: "Europe/London"
+php_xdebug: true
+php_laravel: false
+php_symfony: false
+php_drupal: false
+php_wp: false
# Projects
-#
-# Dictionary to add projects.
-# Parameters:
-# domain - string - URL to be used from host machine to access project.
-# docroot - string - the location of the project in devbox. It's syntax
-# contains {{ remote_user }} to make it box indepedent.
-# db_user - string - the name of the database user to be used (empty for root)
-# db_pass - string - the passwrd of the database user to be used (empty for
-# root)
-# db_name - string - the database name to be used (if empty database is
-# skipped)
-# tech - string - the technology used in the project (hugo, drupal, symfony)
-
-projects:
-
- - domain: "d8.demo"
- project: "{{ projects_root }}/D8/00-DEMO"
- docroot: "tech/web"
- db_user: ""
- db_pass: ""
- db_name: "d8demo"
- tech: "drupal"
-
- # - domain: ""
- # project: ""
- # docroot: ""
- # db_user: ""
- # db_pass: ""
- # db_name: ""
- # tech: ""
+
+# Projects path
+projects_path: "{{ guest_path }}"
+
+# Project parameters
+#
+# domain - string (required) - the local domain to access the project
+# path - string (required) - the location of the project
+# docroot - string (required) - the location of docroot within the project
+# type - string (required) - the technology used in the project (generic, hugo, drupal, symfony, wp, laravel)
+# version - string (optional) - the software version required by composer
+# database - string (optional) - the database name to be used
+# repo - string (optional) - a git path to checkout existing projects (uses path)
+
+#projects:
+
+ #- domain: ""
+ #path: ""
+ #docroot: ""
+ #type: ""
+ #version: ""
+ #database: ""
+ #repo: ""
## TODO
-
+
# Additional packages
-#
-# Add additional packages in the variable below to be included in the server,
-additional_packages:
- # - uncomment here
+
+# Additional tasks
diff --git a/host_vars/devbox.yml b/host_vars/devbox.yml
index f14f26a..8cc35f0 100644
--- a/host_vars/devbox.yml
+++ b/host_vars/devbox.yml
@@ -1,6 +1,6 @@
---
-ansible_host: "127.0.0.1"
-ansible_port: "2222"
-ansible_user: "ubuntu"
-ansible_private_key_file: ".vagrant/machines/devbox/virtualbox/private_key"
\ No newline at end of file
+# ansible_host: "127.0.0.1"
+# ansible_port: "2222"
+# ansible_user: "vagrant"
+# ansible_private_key_file: ".vagrant/machines/devbox/virtualbox/private_key"
diff --git a/playbook.yml b/playbook.yml
index 20a7704..75305e9 100644
--- a/playbook.yml
+++ b/playbook.yml
@@ -5,7 +5,7 @@
##########################################
- hosts: all
- remote_user: "{{ remote_user }}"
+ remote_user: "{{ vm_user }}"
vars_files:
- config.yml
gather_facts: yes
@@ -21,3 +21,4 @@
- "{{ config_roles }}"
loop_control:
loop_var: "roles"
+ when: config_roles is defined
diff --git a/roles/apache/tasks/main.yml b/roles/apache/tasks/main.yml
index f9e07ef..3411627 100644
--- a/roles/apache/tasks/main.yml
+++ b/roles/apache/tasks/main.yml
@@ -1,18 +1,25 @@
---
-- name: Install packages
+- name: Install Apache Web Server packages
become: yes
apt:
- name: "{{ item }}"
+ name: "{{ apache_packages }}"
state: present
- with_items: "{{ packages_apache }}"
notify: restart apache
-- name: Enable Apache mod_rewrite
+- name: Enable Apache modules
become: yes
apache2_module:
- name: rewrite
+ name: "{{ item }}"
state: present
+ with_items: "{{ apache_modules }}"
+ notify: restart apache
+
+- name: Register environment variables with Apache
+ become: yes
+ blockinfile:
+ path: /etc/apache2/envvars
+ block: ". /home/{{ vm_user }}/.envvars"
notify: restart apache
# TODO: Add configuration to harden the server (signature off, etc)
diff --git a/roles/apache/vars/main.yml b/roles/apache/vars/main.yml
index af8e0c8..3e8f60b 100644
--- a/roles/apache/vars/main.yml
+++ b/roles/apache/vars/main.yml
@@ -3,6 +3,12 @@
server_admin: admin@example.com
# Software packages to be installed.
-packages_apache:
+apache_packages:
- apache2
- apache2-utils
+
+apache_modules:
+ - rewrite
+ - proxy
+ - proxy_fcgi
+
diff --git a/roles/common/files/motd b/roles/common/files/motd
new file mode 100644
index 0000000..e5de228
--- /dev/null
+++ b/roles/common/files/motd
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+cat << 'EOF'
+
+ .o8 .o8
+ "888 "888
+.oooo888 .ooooo. oooo ooo 888oooo. .ooooo. oooo ooo
+d88' `888 d88' `88b `88. .8' d88' `88b d88' `88b `88b..8P'
+888 888 888ooo888 `88..8' 888 888 888 888 Y888'
+888 888 888 .o `888' 888 888 888 888 .o8"'88b
+`Y8bod88P" `Y8bod8P' `8' `Y8bod8P' `Y8bod8P' o88' 888o
+
+EOF
diff --git a/roles/common/files/ssh_config b/roles/common/files/ssh_config
deleted file mode 100644
index 101dc72..0000000
--- a/roles/common/files/ssh_config
+++ /dev/null
@@ -1,3 +0,0 @@
-Host github.com
- HostName github.com
- IdentityFile ~/.ssh/id_rsa
diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml
index 9a095f4..897de84 100644
--- a/roles/common/tasks/main.yml
+++ b/roles/common/tasks/main.yml
@@ -2,16 +2,23 @@
- name: Update apt
become: yes
- apt:
- update_cache: yes
- cache_valid_time: 8400
+ apt:
+ upgrade: "yes"
+ update_cache: yes
+ cache_valid_time: 86400 #one day
- name: Install utilities
become: yes
- apt:
- name: "{{ item }}"
+ apt:
+ name: "{{ packages_utils }}"
state: present
- with_items: "{{ packages_utils }}"
+
+- name: Update devbox motd
+ become: yes
+ copy:
+ src: "motd"
+ dest: "/etc/update-motd.d/00-devbox-motd"
+ mode: a+x
- name: Create ~/bin directory
file:
@@ -19,27 +26,61 @@
state: directory
mode: 0775
-- name: Add ~/bin to PATH
- lineinfile:
- dest: "~/.profile"
- regexp: "PATH"
- line: "PATH=\"$HOME/bin:$PATH\""
- backup: yes
+- name: Create enviromental variables
+ file:
+ path: "~/.envvars"
+ state: touch
+ mode: 0700
+
+- name: Add config enviromental variables
+ blockinfile:
+ path: "~/.envvars"
+ block: |
+ export {{ item.name }}={{ item.value }}
+ marker: "# {mark} ANSIBLE MANAGED BLOCK {{ item.name }}"
+ with_items:
+ - "{{ environment_variables }}"
+ when:
+ - environment_variables is defined
+
+- name: Add enviromental variables to .bashrc
+ blockinfile:
+ path: "~/.bashrc"
+ block: |
+ # Source environmental variables set by user
+ if [ -f ~/.envvars ]; then
+ . ~/.envvars
+ fi
- name: Add user RSA key
copy:
- src: "{{ rsa_key }}"
- dest: "~/.ssh/id_rsa"
+ src: "{{ git_rsa_key }}"
+ dest: "{{ git_rsa_key_dest }}"
mode: 0400
- name: Add SSH config
- copy:
- src: ssh_config
+ template:
+ src: "ssh_config"
dest: "~/.ssh/config"
backup: yes
-- name: Add Github fingerprint to known_hosts file
- shell: "ssh-keyscan -H github.com >> ~/.ssh/known_hosts"
+- name: Add global Git config file
+ template:
+ src: "gitconfig"
+ dest: "~/.gitconfig"
+
+- name: Register number of entries in known_hosts
+ shell: "cat ~/.ssh/known_hosts | wc -l"
+ register: number_of_known_hosts
+
+- name: Remove known_hosts
+ shell: "rm -fr ~/.ssh/known_hosts"
+ when: rebuild_known_hosts
args:
- creates: "~/.ssh/known_hosts"
+ warn: false
+- name: Add RSA fingerprint of repositories to known_hosts
+ shell: "ssh-keyscan -H {{ item.host }} >> ~/.ssh/known_hosts"
+ with_items:
+ - "{{ repositories }}"
+ when: rebuild_known_hosts or repositories_count > number_of_known_hosts.stdout
diff --git a/roles/common/templates/gitconfig b/roles/common/templates/gitconfig
new file mode 100644
index 0000000..526e84c
--- /dev/null
+++ b/roles/common/templates/gitconfig
@@ -0,0 +1,4 @@
+[user]
+ name = {{ git_user }}
+ email = {{ git_email }}
+
diff --git a/roles/common/templates/ssh_config b/roles/common/templates/ssh_config
new file mode 100644
index 0000000..42c6e93
--- /dev/null
+++ b/roles/common/templates/ssh_config
@@ -0,0 +1,7 @@
+{% for repo in repositories %}
+Host {{ repo.name }}
+ HostName {{ repo.host }}
+ IdentityFile {{ git_rsa_key_dest }}
+
+{% endfor %}
+
diff --git a/roles/common/vars/main.yml b/roles/common/vars/main.yml
index d4c55ac..949d9b6 100644
--- a/roles/common/vars/main.yml
+++ b/roles/common/vars/main.yml
@@ -12,3 +12,6 @@ packages_utils:
- git
- tmux
- shellcheck
+ - unzip
+ - htop
+
diff --git a/roles/mysql/tasks/main.yml b/roles/mysql/tasks/main.yml
index 57fad71..016ac7a 100644
--- a/roles/mysql/tasks/main.yml
+++ b/roles/mysql/tasks/main.yml
@@ -12,9 +12,8 @@
- name: Install MySQL packages
become: yes
apt:
- name: "{{ item }}"
+ name: "{{ packages_mysql }}"
state: present
- with_items: "{{ packages_mysql }}"
notify: restart mysql
- name: Create MySQL root password
@@ -42,3 +41,28 @@
dest: "~/.my.cnf"
mode: 0600
when: not mysql_pass.stat.exists
+
+- name: Add DB environmental variables to .envvars
+ blockinfile:
+ path: "~/.envvars"
+ block: |
+ export {{ item.name }}={{ item.value }}
+ marker: "# {mark} ANSIBLE MANAGED BLOCK {{ item.name }}"
+ loop:
+ - { name: "DB_USER", value: "root" }
+ - { name: "DB_PASS", value: "{{ mysql_root_pass.stdout }}" }
+ when: not mysql_pass.stat.exists
+ notify: restart apache
+
+- name: Create Adminer directory
+ become: yes
+ file:
+ path: "/var/www/html/adminer"
+ state: directory
+
+- name: Download and install Adminer
+ become: yes
+ shell: "wget -q -O /var/www/html/adminer/index.php https://github.com/vrana/adminer/releases/download/v4.7.5/adminer-4.7.5-mysql-en.php"
+ args:
+ creates: "/var/www/html/adminer/index.php"
+ warn: false
diff --git a/roles/mysql/templates/apache-envvars.j2 b/roles/mysql/templates/apache-envvars.j2
new file mode 100644
index 0000000..c83a53d
--- /dev/null
+++ b/roles/mysql/templates/apache-envvars.j2
@@ -0,0 +1,2 @@
+export DB_USER=root
+export DB_PASS={{ mysql_root_pass.stdout }}
diff --git a/roles/mysql/vars/main.yml b/roles/mysql/vars/main.yml
index 6ba33e7..61066ca 100644
--- a/roles/mysql/vars/main.yml
+++ b/roles/mysql/vars/main.yml
@@ -7,5 +7,5 @@ mysql_user: "root"
packages_mysql:
- mysql-server
- php-mysql
- - python-mysqldb
+ - python3-mysqldb
\ No newline at end of file
diff --git a/roles/nodejs/tasks/main.yml b/roles/nodejs/tasks/main.yml
new file mode 100644
index 0000000..24c5093
--- /dev/null
+++ b/roles/nodejs/tasks/main.yml
@@ -0,0 +1,27 @@
+---
+
+- name: Add NodeSource apt repository key
+ become: yes
+ apt_key:
+ url: "https://deb.nodesource.com/gpgkey/nodesource.gpg.key"
+ state: present
+
+- name: Install NodeSource apt repository
+ become: yes
+ apt_repository:
+ repo: "deb https://deb.nodesource.com/node_14.x focal main"
+ state: present
+
+- name: Install NodeJS packages
+ become: yes
+ apt:
+ name: "{{ packages_node }}"
+ state: present
+
+- name: Install NPM packages
+ become: yes
+ npm:
+ name: "{{ item }}"
+ global: yes
+ state: present
+ with_items: "{{ packages_npm }}"
diff --git a/roles/nodejs/vars/main.yml b/roles/nodejs/vars/main.yml
new file mode 100644
index 0000000..c713b52
--- /dev/null
+++ b/roles/nodejs/vars/main.yml
@@ -0,0 +1,9 @@
+---
+
+# NodeJS packages to be installed.
+packages_node:
+ - nodejs
+
+# NPM packages to be installed.
+packages_npm:
+ - grunt
diff --git a/roles/php/defaults/main.yml b/roles/php/defaults/main.yml
index e69de29..0c68d93 100644
--- a/roles/php/defaults/main.yml
+++ b/roles/php/defaults/main.yml
@@ -0,0 +1,5 @@
+php_xdebug: true
+php_laravel: true
+php_symfony: true
+php_drupal: true
+php_wp: true
diff --git a/roles/php/files/xdebug.ini b/roles/php/files/xdebug.ini
index ce6fe0d..bd50eff 100644
--- a/roles/php/files/xdebug.ini
+++ b/roles/php/files/xdebug.ini
@@ -1,5 +1,6 @@
zend_extension=xdebug.so
-xdebug.remote_enable=1
-xdebug.remote_port=9000
-xdebug.remote_handle=dbgp
-xdebug_remote_connect_back=1
+xdebug.remote_enable = On
+xdebug.remote_port = 9000
+xdebug.remote_handle = dbgp
+xdebug.remote_connect_back = On
+xdebug.remote_autostart = On
diff --git a/roles/php/handlers/main.yml b/roles/php/handlers/main.yml
index 2b9b744..c9955ae 100644
--- a/roles/php/handlers/main.yml
+++ b/roles/php/handlers/main.yml
@@ -2,4 +2,4 @@
- name: restart php
become: yes
- service: name=php7.0-fpm state=restarted
+ service: name=php7.4-fpm state=restarted
diff --git a/roles/php/meta/main.yml b/roles/php/meta/main.yml
deleted file mode 100644
index db4223c..0000000
--- a/roles/php/meta/main.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-
-dependencies:
- - { role: apache }
\ No newline at end of file
diff --git a/roles/php/tasks/main.yml b/roles/php/tasks/main.yml
index e49632f..75c75d3 100644
--- a/roles/php/tasks/main.yml
+++ b/roles/php/tasks/main.yml
@@ -1,12 +1,45 @@
---
-- name: Install packages
+- name: Install PHP packages
become: yes
apt:
- name: "{{ item }}"
+ name: "{{ packages_php }}"
state: present
- with_items: "{{ packages_php }}"
- notify: restart apache
+ notify: restart php
+
+- name: Register PHP config path
+ shell: "php --ini | grep 'Configuration File (php.ini) Path:' | cut -d ':' -f2 | tr -d ' ' | cut -d '/' -f1-4"
+ register: php_config_path
+
+- set_fact:
+ php_config_dir: "{{ php_config_path.stdout }}"
+
+- name: Update PHP memory limit
+ become: yes
+ lineinfile:
+ path: "{{ php_config_dir }}/fpm/php.ini"
+ regexp: "^memory_limit"
+ line: "memory_limit = {{ php_memory_limit }}"
+ notify: restart php
+
+- name: Update PHP timezone
+ become: yes
+ lineinfile:
+ path: "{{ php_config_dir }}/fpm/php.ini"
+ regexp: "^;date.timezone"
+ line: "date.timezone = {{ php_timezone }}"
+ notify: restart php
-- include: php-xdebug.yml
- include: php-composer.yml
+
+- name: Enable xdebug
+ include_tasks: php-xdebug.yml
+ when: php_xdebug == true
+
+- name: Enable laravel integration
+ include_tasks: php-laravel.yml
+ when: php_laravel == true
+
+- name: Enable Drupal tools
+ include_tasks: php-drupal.yml
+ when: php_drupal == true
diff --git a/roles/php/tasks/php-composer.yml b/roles/php/tasks/php-composer.yml
index 4deae42..8f86004 100644
--- a/roles/php/tasks/php-composer.yml
+++ b/roles/php/tasks/php-composer.yml
@@ -1,17 +1,37 @@
---
-- name: Install composer
+- name: Download and install composer
shell: "curl -sS https://getcomposer.org/installer | php"
args:
- creates: "~/bin/composer"
+ creates: "/usr/local/bin/composer"
+ warn: false
-- name: Move composer to ~/bin
- shell: "mv ~/composer.phar ~/bin/composer"
+- name: Move composer to /usr/local/bin
+ become: yes
+ shell: "mv composer.phar /usr/local/bin/composer"
args:
- creates: "~/bin/composer"
+ chdir: "/home/{{ vm_user }}"
+ creates: "/usr/local/bin/composer"
- name: Make composer executable
+ become: yes
file:
- path: "~/bin/composer"
+ path: "/usr/local/bin/composer"
mode: a+x
state: file
+
+- name: Add Composer's system-wide vendor dir to path
+ blockinfile:
+ path: "~/.profile"
+ block: |
+ # set PATH so it includes Composer's system-wide vendor directory if it exists
+ if [ -d "$HOME/.config/composer/vendor/bin/" ] ; then
+ PATH="$HOME/.config/composer/vendor/bin/:$PATH"
+ fi
+ backup: yes
+
+- name: Update composer to latest version
+ composer:
+ command: self-update
+ arguments: --no-interaction
+ global-command: yes
diff --git a/roles/php/tasks/php-drupal.yml b/roles/php/tasks/php-drupal.yml
new file mode 100644
index 0000000..65f0b5e
--- /dev/null
+++ b/roles/php/tasks/php-drupal.yml
@@ -0,0 +1,7 @@
+---
+
+- name: Install Drush
+ composer:
+ command: require
+ global_command: yes
+ arguments: "drush/drush:^10.0.0"
diff --git a/roles/php/tasks/php-laravel.yml b/roles/php/tasks/php-laravel.yml
new file mode 100644
index 0000000..8fe8cfc
--- /dev/null
+++ b/roles/php/tasks/php-laravel.yml
@@ -0,0 +1,7 @@
+---
+
+- name: Install Laravel installer
+ composer:
+ command: require
+ global_command: yes
+ arguments: "laravel/installer"
diff --git a/roles/php/tasks/php-xdebug.yml b/roles/php/tasks/php-xdebug.yml
index 2235b2a..b665671 100644
--- a/roles/php/tasks/php-xdebug.yml
+++ b/roles/php/tasks/php-xdebug.yml
@@ -1,20 +1,9 @@
---
-# - name: Update xdebug config file
-# blockinfile:
-# path: "{{ php_config_dir }}/mods_available/xdebug.ini"
-# block: |
-# xdebug.remote_enable=1
-# xdebug.remote_port=9000
-# xdebug.remote_handle=dbgp
-# xdebug_remote_connect_back=1
-# create: yes
-# state: present
-# backup: yes
-
- name: Copy xdebug.ini to appropriate location
become: yes
copy:
src: xdebug.ini
dest: "{{ php_config_dir }}/mods-available/xdebug.ini"
backup: yes
+ notify: restart php
diff --git a/roles/php/vars/main.yml b/roles/php/vars/main.yml
index d8a50e9..fa57b11 100644
--- a/roles/php/vars/main.yml
+++ b/roles/php/vars/main.yml
@@ -1,18 +1,18 @@
---
-# PHP configuration directory.
-php_config_dir: "/etc/php/7.0/"
# PHP packages to be installed.
packages_php:
- - php7.0
- - php7.0-mcrypt
- - php7.0-cli
- - php7.0-common
- - php7.0-curl
- - php7.0-dev
- - php7.0-fpm
- - php7.0-gd
- - php7.0-zip
- - php7.0-mbstring
+ - php
+ - php-cli
+ - php-common
+ - php-curl
+ - php-dev
+ - php-fpm
+ - php-gd
+ - php-zip
+ - php-mbstring
+ - php-mailparse
+ - php-imap
+ - php-bcmath
+ - php-intl
- php-xdebug
- - libapache2-mod-php
diff --git a/roles/projects/meta/main.yml b/roles/projects/meta/main.yml
index 8516a7b..653c41f 100644
--- a/roles/projects/meta/main.yml
+++ b/roles/projects/meta/main.yml
@@ -1,5 +1,6 @@
---
-dependencies:
- - { role: php }
- - { role: mysql }
+# dependencies:
+# - { role: apache }
+# - { role: php }
+# - { role: mysql }
diff --git a/roles/projects/tasks/main.yml b/roles/projects/tasks/main.yml
index 76f7daf..5c0f54b 100644
--- a/roles/projects/tasks/main.yml
+++ b/roles/projects/tasks/main.yml
@@ -1,4 +1,62 @@
---
-- include: projects-conf-apache.yml
-- include: projects-conf-mysql.yml
+- name: Register PHP FPM socket
+ shell: "cat {{ php_config_dir }}/fpm/pool.d/www.conf | grep 'fpm.sock' | cut -f2 -d '=' | tr -d ' '"
+ register: php_fpm_socket
+
+- name: Create project path or ensure it exists
+ file:
+ path: "{{ item.path }}"
+ group: www-data
+ mode: 0775
+ state: directory
+ with_items: "{{ projects }}"
+
+- name: Discover which projects have .git files
+ stat:
+ path: "{{ item.path }}/.git"
+ with_items: "{{ projects }}"
+ register: dot_git
+
+# - debug:
+# var: dot_git
+
+# Project setup behaviour
+#
+# IF a git repository has been declared in projects configuration
+# THEN repository gets checkout
+#
+# IF a git repository has not been declared in projects configuration
+# AND a .git directory does not exist in the directory
+# THEN the task is run based on tech value chosen
+
+- name: Initialise projects with repositories
+ include_tasks: projects-project-git.yml
+ with_items: "{{ dot_git.results }}"
+ when: (item.stat.exists == false) and (item.item.repo != '')
+
+# - name: Initialise custom or empty projects
+# include_tasks: projects-project-custom.yml
+# with_items: "{{ dot_git.results }}"
+# when: (item.stat.exists == false) and (item.repo == '') and (item.type == '' or item.type == 'custom')
+
+# - name: Initialise Hugo projects
+# include_tasks: projects-project-hugo.yml
+# with_items: "{{ dot_git.results }}"
+# when: (item.stat.exists == false) and (item.repo == '') and (item.type == 'hugo')
+
+- name: Initialise Drupal projects
+ include_tasks: projects-project-drupal.yml
+ with_items: "{{ dot_git.results }}"
+ when: (item.stat.exists == false) and (item.item.repo == '') and (item.item.type == 'drupal')
+
+# - name: Initialise Symfony projects
+# include_tasks: projects-project-symfony.yml
+# with_items: "{{ dot_git.results }}"
+# when: (item.stat.exists == false) and (item.item.repo == '') and (item.type == 'symfony')
+
+- name: Execute Apache config
+ include_tasks: projects-conf-apache.yml
+
+- name: Execute MySQL config
+ include_tasks: projects-conf-mysql.yml
diff --git a/roles/projects/tasks/projects-conf-apache.yml b/roles/projects/tasks/projects-conf-apache.yml
index 42c97c4..ced0b16 100644
--- a/roles/projects/tasks/projects-conf-apache.yml
+++ b/roles/projects/tasks/projects-conf-apache.yml
@@ -3,7 +3,7 @@
- name: Create project docroots
become: yes
file:
- path: "{{ item.project }}/{{ item.docroot }}"
+ path: "{{ item.path }}/{{ item.docroot }}"
group: www-data
mode: 0775
state: directory
@@ -12,7 +12,7 @@
- name: Create project vhosts
become: yes
template:
- src: "generic.vhost.j2"
+ src: "{{ item.type }}.vhost.j2"
dest: "/etc/apache2/sites-available/{{ item.domain }}.conf"
owner: root
group: root
diff --git a/roles/projects/tasks/projects-conf-mysql.yml b/roles/projects/tasks/projects-conf-mysql.yml
index d1f03aa..b90d72e 100644
--- a/roles/projects/tasks/projects-conf-mysql.yml
+++ b/roles/projects/tasks/projects-conf-mysql.yml
@@ -2,19 +2,11 @@
- name: Create project databases
mysql_db:
- name: "{{ item.db_name }}"
+ name: "{{ item.database }}"
state: present
+ collation: utf8mb4_unicode_ci
+ encoding: utf8mb4
with_items:
- "{{ projects }}"
-
-- name: Add users and privileges to project databases
- mysql_user:
- name: "{{ item.db_user }}"
- host: localhost
- password: "{{ item.db_pass }}"
- priv: "{{ item.db_name }}.*:ALL,GRANT"
- state: present
- append_privs: yes
- with_items:
- - "{{ projects }}"
- when: item.db_user is defined
+ when: (item.database is defined) and (item.database != "")
+
\ No newline at end of file
diff --git a/roles/projects/tasks/projects-project-custom.yml b/roles/projects/tasks/projects-project-custom.yml
new file mode 100644
index 0000000..cb5df26
--- /dev/null
+++ b/roles/projects/tasks/projects-project-custom.yml
@@ -0,0 +1,5 @@
+---
+
+- debug:
+ msg: "Project {{ item.domain }} is a custom or empty project."
+
diff --git a/roles/projects/tasks/projects-project-drupal.yml b/roles/projects/tasks/projects-project-drupal.yml
new file mode 100644
index 0000000..baecd34
--- /dev/null
+++ b/roles/projects/tasks/projects-project-drupal.yml
@@ -0,0 +1,75 @@
+---
+
+- name: Create codebase with specific package version
+ composer:
+ command: create-project
+ arguments: drupal/recommended-project:{{ item.item.version }} .
+ working-dir: "{{ item.item.path }}"
+ when: ( item.item.version is defined ) and ( item.item.version != "")
+
+- name: Create codebase with latest stable
+ composer:
+ command: create-project
+ arguments: drupal/recommended-project .
+ working-dir: "{{ item.item.path }}"
+ when: ( item.item.version is not defined ) or ( item.item.version == "")
+
+- name: Create settings.php
+ copy:
+ src: "{{ item.item.path }}/{{ item.item.docroot }}/sites/default/default.settings.php"
+ dest: "{{ item.item.path }}/{{ item.item.docroot }}/sites/default/settings.php"
+ remote_src: yes
+ force: no
+
+- name: Update Drupal's hash_salt setting
+ lineinfile:
+ path: "{{ item.item.path }}/{{ item.item.docroot }}/sites/default/settings.php"
+ regexp: "^\\$settings\\['hash_salt"
+ line: "$settings['hash_salt'] = 'DvkOcqLrxtGYNv25npi1r2+UEF43EASGk4JdSTVRCx4KSvygbbRWRps6WbLwP2NnZeOhJ36X0g==';"
+
+- name: Update Drupal's config directory setting
+ lineinfile:
+ path: "{{ item.item.path }}/{{ item.item.docroot }}/sites/default/settings.php"
+ regexp: "^\\#\\ \\$settings\\['config_sync_directory"
+ line: "$settings['config_sync_directory'] = '../config/sync';"
+
+- name: Add database config into Drupal's settings
+ blockinfile:
+ path: "{{ item.item.path }}/{{ item.item.docroot }}/sites/default/settings.php"
+ block: |
+ $databases['default']['default'] = [
+ 'database' => getenv('DB_NAME'),
+ 'username' => getenv('DB_USER'),
+ 'password' => getenv('DB_PASS'),
+ 'host' => 'localhost',
+ 'port' => '3306',
+ 'driver' => 'mysql',
+ 'prefix' => '',
+ 'collation' => 'utf8mb4_general_ci',
+ ];
+
+ if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
+ include $app_root . '/' . $site_path . '/settings.local.php';
+ }
+
+- name: Create settings.local.php
+ copy:
+ src: "{{ item.item.path }}/{{ item.item.docroot }}/sites/example.settings.local.php"
+ dest: "{{ item.item.path }}/{{ item.item.docroot }}/sites/default/settings.local.php"
+ remote_src: yes
+ force: no
+
+- name: Create cached twig files templates
+ become: yes
+ file:
+ path: /tmp/twig-cache
+ owner: www-data
+ group: www-data
+ state: directory
+
+- name: Update cache twig definition on settings.local.php
+ blockinfile:
+ path: "{{ item.item.path }}/{{ item.item.docroot }}/sites/default/settings.local.php"
+ block: |
+ $settings['php_storage']['twig']['directory'] = '/tmp/twig-cache/php';
+ $settings['php_storage']['twig']['secret'] = $settings['hash_salt'];
diff --git a/roles/projects/tasks/projects-project-git.yml b/roles/projects/tasks/projects-project-git.yml
new file mode 100644
index 0000000..569a62a
--- /dev/null
+++ b/roles/projects/tasks/projects-project-git.yml
@@ -0,0 +1,7 @@
+---
+
+- name: Clone repositories
+ git:
+ repo: "{{ item.item.repo }}"
+ dest: "{{ item.item.path }}"
+
diff --git a/roles/projects/tasks/projects-project-hugo.yml b/roles/projects/tasks/projects-project-hugo.yml
new file mode 100644
index 0000000..9afc772
--- /dev/null
+++ b/roles/projects/tasks/projects-project-hugo.yml
@@ -0,0 +1,5 @@
+---
+
+- debug:
+ msg: "Project {{ item.domain }} is a hugo project."
+
diff --git a/roles/projects/tasks/projects-project-symfony.yml b/roles/projects/tasks/projects-project-symfony.yml
new file mode 100644
index 0000000..d6d2f16
--- /dev/null
+++ b/roles/projects/tasks/projects-project-symfony.yml
@@ -0,0 +1,17 @@
+---
+
+- debug:
+ msg: "Project {{ item.item.path }} is a symfony project."
+
+- composer:
+ command: "create-project"
+ arguments: "symfony/skeleton . --quiet"
+ working_dir: "{{ item.item.path }}"
+
+- name: Initialise git repo in the Symfony application
+ command: "git init ."
+ chdir: "{{ item.item.path }}"
+ args:
+ creates: "{{ item.item.path }}/.git"
+
+
diff --git a/roles/projects/templates/drupal.vhost.j2 b/roles/projects/templates/drupal.vhost.j2
new file mode 100644
index 0000000..4be1488
--- /dev/null
+++ b/roles/projects/templates/drupal.vhost.j2
@@ -0,0 +1,26 @@
+
+
+ ServerName {{ item.domain }}
+ DocumentRoot {{ item.path }}/{{ item.docroot }}
+
+
+ Options FollowSymLinks
+ AllowOverride All
+ Require all granted
+
+
+
+ SetHandler "proxy:unix:{{ php_fpm_socket.stdout }}|fcgi://localhost/"
+
+
+
+
+
+ ErrorLog ${APACHE_LOG_DIR}/{{ item.domain }}_error.log
+ CustomLog ${APACHE_LOG_DIR}/{{ item.domain }}_access.log combined
+
+ SetEnv DB_USER ${DB_USER}
+ SetEnv DB_PASS ${DB_PASS}
+ SetEnv DB_NAME {{ item.database }}
+
+
diff --git a/roles/projects/templates/generic.vhost.j2 b/roles/projects/templates/generic.vhost.j2
index f626edc..8f546f1 100644
--- a/roles/projects/templates/generic.vhost.j2
+++ b/roles/projects/templates/generic.vhost.j2
@@ -1,14 +1,21 @@
ServerName {{ item.domain }}
-DocumentRoot {{ item.project }}/{{ item.docroot }}
+DocumentRoot {{ item.path }}/{{ item.docroot }}
-
+
Options FollowSymLinks
AllowOverride All
Require all granted
+
+ SetHandler "proxy:unix:{{ php_fpm_socket.stdout }}|fcgi://localhost/"
+
+
+
+
+
ErrorLog /var/log/apache2/{{ item.domain }}_error.log
CustomLog /var/log/apache2/{{ item.domain }}_access.log combined