11 KiB
Drupal VM supports deploying Drupal VM to a production environment. The security of your servers is your responsibility.
(See companion blog post to this documentation: Soup to Nuts: Using Drupal VM to build local and prod.)
Production specific overrides.
Drupal VM supports loading configuration files depending on the environment variable DRUPALVM_ENV
and using this feature you can have different configurations between development and production environments.
# Loads vagrant.config.yml if available (default).
vagrant provision
# Loads prod.config.yml if available.
DRUPALVM_ENV=prod vagrant provision --provisioner=aws
If you're issuing a provision directly through ansible-playbook
as you would do for most production environments you can either set the DRUPALVM_ENV
variable on your host, or on the remote production machine.
# By default it doesn't try to load any other config file.
ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass
# Loads prod.config.yml if available.
DRUPALVM_ENV=prod ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass
If you add DRUPALVM_ENV=prod
to the /etc/environment
file on your production environment:
# Loads prod.config.yml if available.
ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass
Note: Having the variable set locally takes precedence over having it on the remote machine.
As a precaution not to accidentally provision a production server with insecure configurations, you should set your security hardening configurations in config.yml
, your local development overrides in vagrant.config.yml
and finally any additional production specific overrides in prod.config.yml
. This way, a production environment will never be provisioned with development tools, even if the prod.config.yml
is not read.
Ansible Vault support
Drupal VM will include a secrets.yml
file included in your VM's configuration directory (alongside config.yml
, local.config.yml
, etc.) that you can use to store sensitive variables (e.g. MySQL's root password, Drupal's admin password). For extra security, you can encrypt this file, and require a password whenever the variable is used.
First, you'd create an Ansible Vault encrypted file:
$ ansible-vault create secrets.yml
Create the file inside your VM's configuration directory, add any plaintext passwords, and save it. Ansible Vault will encrypt the file, and you can edit the file using ansible-vault edit
.
When running vagrant
commands, make sure you tell the Ansible provisioner to use --ask-vault-pass
, e.g.:
DRUPALVM_ANSIBLE_ARGS='--ask-vault-pass' vagrant [command]
And if you need to override one of the secrets stored in that file, you can do so through an environment-specific config file, for example:
vagrant.config.yml
prod.config.yml
[etc.]
Example: Drupal VM on DigitalOcean
The examples/prod
directory contains an example production configuration for Drupal VM which can be used to deploy Drupal VM to a production environment on a cloud provider like DigitalOcean, Linode, or AWS.
This guide contains instructions for how you can build a Drupal environment with Drupal VM on DigitalOcean.
Create a DigitalOcean Droplet
If you don't already have a DigitalOcean account, create one (you can use geerlingguy's affiliate link to sign up, otherwise, visit the normal DigitalOcean Sign Up form.
Make sure you have an SSH key you can use to connect to your DigitalOcean droplets, and if you don't already have one set up, or if you need to add your existing key to your account, follow the instructions in this guide: How to use SSH keys with DigitalOcean Droplets.
Once you are logged into DigitalOcean and have added your SSH key, click the 'Create Droplet' button on your Droplets page. For the Droplet, choose the following options:
- Image: Choose
Ubuntu 16.04.x x64
- Size: 1 GB / 1 CPU (currently $10/month; you can choose a higher plan if needed)
- Region: Choose whatever region is geographically nearest to you and your site visitors
- Settings: (Nothing here affects how Drupal VM works, choose what you'd like)
- Add SSH Keys: Select the SSH key you added to your account earlier.
- Hostname: Choose a hostname for your site (e.g.
example.drupalvm.com
)
Click 'Create Droplet', and wait a minute or so while the Droplet is booted. Once it's booted, make sure you can log into it from your local computer:
ssh root@[droplet-hostname-or-ip]
(Make sure you replace [droplet-hostname-or-ip]
) with the hostname or IP address of your Droplet!)
If you get a warning like "the authenticity of the host can't be established", answer yes to the prompt and hit enter. You should now be logged into the Droplet. Log back out by typing exit
at the prompt and hitting return.
Your DigitalOcean Droplet is booted and ready to have Drupal VM installed on it.
Customize config.yml
for production
Copy examples/prod/prod.config.yml
to config.yml
, and by looking at default.config.yml
add any other overrides you'd like. Whatever variables you have set in config.yml
will override the defaults set by default.config.yml
.
The changes outlined in the example prod.config.yml
disable development-environment tools (like Pimp My Log and Adminer) and add extra security hardening configuration (via the extra_security_enabled
variable).
You now have Drupal VM configured for production by default. This is the recommended and safest way, so that you can't accidentally provision a production server with development tools. If desired you can also use the environment variable DRUPALVM_ENV
to load an additional <ENV>.config.yml
with production specific overrides. In most cases this is not needed though.
Customize vagrant.config.yml
for local development
To re-use the same setup for local development, copy default.config.yml
to vagrant.config.yml
and configure it so that you override the security hardening configurations that were added in config.yml
. Read about how configuration files are read under Configuring Drupal VM
Customize inventory
for production
The only other thing you need to do is copy the inventory file example.inventory
to inventory
(so it is located at prod/inventory
). By default, it reads:
[drupalvm]
1.2.3.4 ansible_ssh_user=my_admin_username
Change the host 1.2.3.4
to either the IP address or the hostname of your DigitalOcean Droplet. Remember that if you would like to use a hostname, you need to make sure the hostname actually resolves to your Droplet's IP address, either in your domain's public DNS configuration, or via your local hosts file.
Initialize the server with an administrative account
Note: This guide assumes you have Ansible installed on your host machine.
The first step in setting up Drupal VM on the cloud server is to initialize the server with an administrative account (which is separate from the root
user account for better security).
Inside the examples/prod/bootstrap
folder, copy the example.vars.yml
file to vars.yml
and update the variables in that file for your own administrative account (make sure especially to update the admin_password
value!).
Then, run the following command within Drupal VM's root directory (the folder containing the Vagrantfile
):
ansible-playbook -i examples/prod/inventory examples/prod/bootstrap/init.yml -e "ansible_ssh_user=root"
Once the initialization is complete, you can test your new admin login with ssh my_admin_username@droplet-hostname-or-ip
. You should be logged in via your existing SSH key. Log back out with exit
.
Provision Drupal VM on the Droplet
Run the following command within Drupal VM's root directory (the folder containing the Vagrantfile
):
DRUPALVM_ENV=prod ansible-playbook -i examples/prod/inventory provisioning/playbook.yml --become --ask-become-pass
Note: If you have installed Drupal VM as a Composer dependency you also need to specify the path of the config directory where you have your config.yml
located.
DRUPALVM_ENV=prod ansible-playbook -i config/prod/inventory vendor/geerlingguy/drupal-vm/provisioning/playbook.yml -e "config_dir=$(pwd)/config" --become --ask-become-pass
Ansible will prompt you for your admin account's sudo
password (the same as the password you encrypted and saved as admin_password
). Enter it and press return.
After a few minutes, your Drupal-VM-in-the-cloud Droplet should be fully configured to match your local development environment! You can visit your Droplet and access the fresh Drupal site just like you would locally (e.g. http://example.drupalvm.com/
).
Known issues
-
You may need to manually create the
drupal_core_path
directory on the server at this time; it's not always created automatically due to permissions errors. -
The
files
folder that is generated during the initial Drupal installation is set to be owned by the admin account; to make it work (and to allow Drupal to generate stylesheets and files correctly), you have to manually log into the server and run the following two commands after provisioning is complete:$ sudo chown -R www-data /var/www/drupalvm/drupal/sites/default/files $ sudo chmod -R 0700 /var/www/drupalvm/drupal/sites/default/files
-
You can't synchronize folders between your host machine and DigitalOcean (at least not in any sane way); so you'll need to either have Drupal VM install a site from a given Drush make file or composer.json, or deploy the site via Git, using the
geerlingguy.drupal
role's git deployment options. -
Drupal VM doesn't include any kind of backup system. You should use one if you have any kind of important data on your server!
Go Further
You can use Ubuntu 14.04, Ubuntu 16.04, Debian 8, CentOS 6 or CentOS 7 when you build the DigitalOcean Droplet. Just like with Drupal VM running locally, you can customize almost every aspect of the server!
You may want to customize your configuration even further, to make sure Drupal VM is tuned for your specific Drupal site's needs, or you may want to change things and make the server configuration more flexible, etc. For all that, the book Ansible for DevOps will give you a great introduction to using Ansible to make Drupal VM and the included Ansible configuration do exactly what you need!