-
-
Notifications
You must be signed in to change notification settings - Fork 645
Best practices for using Drupal VM in a project repository / with teams #305
Comments
Yep.
Not so much that I've seen... one pattern some projects use is to have the box in a subdir (as you seem to be using); other patterns are to have Drupal VM installed completely independently, just referencing the project's docroot. There are a couple other projects (like a Node.js UI in front of Drupal VM for a very MAMP-like experience for adding/managing sites) that are trying to set a few different standards too.
Unfortunately, no; I haven't seen any way to configure a particular Vagrant setup using something like npm, composer, pip, rubygems, etc., though I do think that would be awesome. I built (and maintain) Drupal VM as a completely independent project divorced from any single project configuration because I develop it first and foremost for myself :) For my own usage I:
Would love to hear how other projects and teams are incorporating Drupal VM into their workflow and/or project repositories themselves. I know for a fact that some teams just fork Drupal VM in its entirety and include everything in the root directory of the project. |
One other note I forgot to mention: For my real big Drupal sites (e.g. ones that aren't personal, for fun, or for friends, like Server Check.in or Hosted Apache Solr), I actually do fork Drupal VM and create the entire project directory based around Drupal VM. Of course, I also use the Drupal VM configuration (hacked a bit to just include Nginx, and just include the things/configuration I install on prod servers) to actually build my local, dev (cloud-based) and prod (cloud-based) environments... some teams just use Drupal VM for local environments, so their needs are a bit different. |
Our team has set it up with the following structure:
Makefile vm:
cp -r lib/drupal-vm vm
ln -sf ../config/config.yml vm/config.yml
ln -sf ../config/Vagrantfile vm/Vagrantfile Root Vagrantfile dir = File.dirname(__FILE__) + '/'
load dir + "vm/Vagrantfile" This way it's somewhat easier to bring in VM updates from upstream, while being able to run My wishlist:
Btw, I'll take the opportunity and thank you @geerlingguy for an amazing project! We're currently using it for all our Drupal projects as well as all our Wordpress projects :) It's by far the most flexible VM solution I've come across. |
We are using it as part of a custom gulp based project builder. Gulp downloads all dependencies according to their kind and builds it all and puts it all in its place. This allows us to build things that are not built around any specific tech. |
Well, I've already shared what my team is currently doing. Here's how I would like things to work:
I'll give some more thought to how these goals might be accomplished in terms of mechanics. |
I've got a proof of concept working: Create a dir = File.dirname(File.expand_path(__FILE__))
# Override the default config.yml location by specifying it's location globally.
$vconfig_file = "#{dir}/config.yml"
# Load the real Vagrantfile, this could also be within a composer vendor directory.
load "#{dir}/vm/Vagrantfile" Modify drupal-vm diff --git a/Vagrantfile b/Vagrantfile
index 1243c26..0f68471 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -17,10 +17,13 @@ end
# Use config.yml for basic VM configuration.
require 'yaml'
dir = File.dirname(File.expand_path(__FILE__))
-if !File.exist?("#{dir}/config.yml")
+if !defined?($vconfig_file)
+ $vconfig_file = "#{dir}/config.yml"
+end
+if !File.exist?($vconfig_file)
raise 'Configuration file not found! Please copy example.config.yml to config.yml and try again.'
end
-vconfig = YAML::load_file("#{dir}/config.yml")
+vconfig = YAML::load_file($vconfig_file)
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.hostname = vconfig['vagrant_hostname']
@@ -86,6 +89,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
if which('ansible-playbook')
config.vm.provision "ansible" do |ansible|
ansible.playbook = "#{dir}/provisioning/playbook.yml"
+ ansible.extra_vars = {
+ config_file: $vconfig_file
+ }
ansible.sudo = true
end
# Provision using shell provisioner and JJG-Ansible-Windows otherwise. Modify the playbook to include the config file dynamically at runtime instead. diff --git a/provisioning/playbook.yml b/provisioning/playbook.yml
index 60b00de..77a1c15 100644
--- a/provisioning/playbook.yml
+++ b/provisioning/playbook.yml
@@ -1,10 +1,8 @@
---
- hosts: all
- vars_files:
- - ../config.yml
-
pre_tasks:
+ - include_vars: "{{config_file}}"
- include: tasks/init-debian.yml
when: ansible_os_family == 'Debian'
- include: tasks/init-redhat.yml This could be cleaned up a bit (maybe use an environment variable instead), but would support storing the drupal-vm in an unmodified tree either as a git submodule, or as a composer library. The only thing the user needs to do is to create a secondary |
I have to say that I disagree with this approach. I my team's workflow The project is managed by gulp. Gulp downloads drupalvm along with all our In the end this keeps projects separate and allow the tools to be updated On Sat, Nov 14, 2015, 06:22 Oskar Schöldström notifications@github.com
|
@frob if the approach you mentioned is the one I posted, it does exactly that no? Separating Only difference is it uses a delegating |
@oxyc Sorry, I didn't see the vagrantfile delegation, and I didn't know that was possible. If none of those modifications break drupal-vm working as a standalone part, then I think they would make good additions. As it stands my I have gulp commands that modify the config based on the project; this should let us specify an outside location for project specific config. @TravisCarden "All support files would be stored in the location(s) an active member of the Vagrant open source community would expect to find them in. I prefer to observe conventions and best practices from the domain a technology belongs to rather than inventing my own paradigms" How about a pull request or some direction as to where these locations are. |
@oxyc I tried your Vagrantfile delegation. I found it lead to unstable results. I am running on osx 10.10. When I ran that, and I provisioned without going through the delegate Vagrant file, vagrant would give me an incorrect status when I ran |
@frob ah, nice research! Maybe the |
And, @frob, my remark about wanting things to be stored where an active member of the Vagrant community would expect to find them was not meant to imply that I know where those locations are. I don't, as I'm only starting out with Vagrant myself. My reason for creating this issue was to see if others could supply that knowledge of best practices that I lack in this instance. :) |
@oxyc I think you assumption about the I noticed that there where |
Also, check out a tool like Lunchbox, which @nateswart has been working on as a kind of GUI wrapper around Drupal VM. I know there are a few different tools set up like this to 'wrap' Drupal VM, and it would be interesting to see if there are some ways we can make the core of Drupal VM be flexible and work well with all these tools. |
this is orthogonal to Drupal VM, but its solving the same problem I've been looking into tsuru.io, a Heroku esque paas I noticed Heroku provide dev - prod parity using Docker for local dev secondly, I use Aegir 3 git provisioning with direct git remotes to Pantheon from a Vagrant VM using many of the Drupal VM Ansible roles its a good local development environment and it has a deployment system built in it also has the advantage of using Aegir and so I have 1 VM, not many.. easier to manage imho |
Over the past 12 months, I've created and am currently maintaining fairly complicated DrupalVM setup The process in which the supported machines work is that a bash script goes and git clone/pull various repositories before copying the configuration files and performing many sed commands to modify and change settings. I've got some interesting things going on such as a random IP address and several custom ansible roles. The provisioning process isn't configured to build any sites but I've created lots of integrated scripts for various functions such as building new sites from an acquia account, rebuilding, killing off, database download/upload, file download/upload, remaking all the virtual hosts on nginx and apache if the respective file system exists... There are dozens of utility scripts I've created which all communicate with each other and a command line interface menu style script. During this process it'll also git pull the respective "code bases" on the acquia account so that when commits are made they're up to date... Reprovisioning is kinda like maintenance, it'll go through and fix anything that shouldn't be as it is, update any packages or software and most importantly update all the scripts stored in git we use for development. Yeah it's all command line, and a GUI would be incredible, but it's a matter of application to the needs of the user. I get paid to look after this thing as well as develop websites, so I have to commit my time to the best use of my organisation. A web GUI isn't feasible in my case. |
I would also add Laravel's Homestead and Joomla's Joomla Box are worth looking at http://laravel.com/docs/4.2/homestead https://github.com/joomlatools/joomlatools-vagrant |
Could those involved in this thread have a look at #378 from @frob and give some feedback? This method would allow Drupal VM to exist on its own or within another project inside a directory (e.g. For my own needs, when I have Drupal VM in a project, I add a second example.config.yml for devs to clone inside a |
Had a look at beetbox and saw they loaded a This could be pretty useful for teams to track a shared config and then let individual developers override things with the untracked Edit: Just noticed something similiar was suggested before. #317 |
@oxyc - At a minimum, I like this idea as well. I currently hack I think Drupal VM's solidly used by many teams now, whereas I originally built it only for individual usage patterns. |
If we add support for a Could then merge all the docs from those issues into a Using Drupal VM with teams section. |
A big +1 to the idea of support for Just to offer another use-case, I usually need to work on several projects concurrently, and (provided the environments don't need to differ substantially) I find an individual VM per project to be too heavy. So I typically have 1-3 VMs containing a couple or several projects, with More on-topic, if my team were all using the same dev environment (we don't...), I think we'd probably structure the files so that we could include at most
...with a
This means setup for anyone to join or test the project is cloning drupal-vm into the boxes directory and creating a symlink. But I'm not even sure we'd want any of the dev environment configuration in the actual repo. |
I've gotten around this problem by adding a local variables file in /provisioning/vars/vars.yml or something to that effect and including it. There's no need for a full new config file when you can simply override everything by redeclaring the variables in question. It helps with maintainability when you need to upgrade the config files.... Which I need to do again soon! |
@fubarhouse I think that is exactly what they are using the config.local.yml for. |
I've updated the docs a bit to highlight some of the tools that can help manage Drupal VM (either for individuals or as part of a team): http://docs.drupalvm.com/en/latest/other/management-tools/ But a lot of the work @oxyc and others have been working on will make Drupal VM much more flexible in a team environment, most especially the idea of a 'local' Vagrantfile and a 'local' config.yml (just like Drupal 8 now has a baked in local settings.php option). |
I'd like to talk specifically about this issue (but also anything that's related) at DrupalCon NOLA—please come to the BoF: Drupal VM and local Drupal development for teams
|
Thought I'd describe my ideal setup for teams: repository
- lib/
- drupal-vm/ # git submodule
- example.config.yml
- company-conf/ # git submodule
- drupal-vm.config.yml # company specific configurations
- config/
- drupal-vm.config.yml # This is a project specific config
- drupal.make.yml #
- deploy.rb
- ....
- docroot/
- index.php
- ....
- Vagrantfile
- local.config.yml
Project specific vagrant_hostname: project.dev
vagrant_machine_name: project
vagrant_ip: 192.168.87.77 Company shared vagrant_box: geerlingguy/ubuntu1404
vagrant_user: vagrant
vagrant_synced_folder_default_type: nfs
... and the rest of the configuration. User specific vagrant_memory: 2048 This would make it very easy to share configurations across multiple projects and keep them all up to date with Drupal VM. It still is able to lock all versions of everything not to break on updates. Except for the inheritable config files this is the structure we use where I work at the moment. We just have a |
This looks like it is becoming a new project all on its own. I would hope the goal for drupalvm is to be flexible enough to allow for this, but not dictate it. |
Yes for sure. It needs to be easy to get started. Once Vagrant 1.8.2 comes out the delegating Vagrantfile PR would be possible. The only other feature needed would be to allow multiple config files to be read. There's a related task for this already #455 |
I'm still in the process of upgrading our ~20 repos to use php5-fpm instead of mod_php since that became the default in Drupal VM. Having a company wide base config to inherit from would make it a lot easier to maintain :) |
Looking forward to a sprint to get this nailed down at Drupalcon. I've been testing #378 to ease the upgrade situation across many projects. |
@oxyc I've also adopted the use of php5-fpm when using nginx, and mod_php with apache2 on the drupal vm platform. I don't actually know if there's an equivalent for php v7, but if in the event there is no equal, a solution will be needed. @geerlingguy will the speech be available afterwards for us international people who're interested? |
@fubarhouse - I'll try to do so... will also try to find a way to connect to a Hangout or something like that too, so more people can remotely participate. |
I wanted to throw yeoman into the discussion, such as |
I have seen this thread - I recently updated the yeoman generator to be in line with the 2.4.0 release of DrupalVM. That yeoman script started as a more friendly assistant to non technical people who don't know much about conf names and values to guide them through setting up a config.yml for DrupalVM. For us, every new project starts with the 'yo drupalvm' to generate the configuration. It is then committed into the project under tools/drupalvm, so anyone who checks out the project simply navigates to that directory and does vagrant up. These folks have vagrant autonetwork and hostsupdater plugin installed before hand, so 0.0.0.0 in the config.yml poses no conflict to them (which is how I will do any project I start). Our projects look as such:
We don't use one VM to run multiple sites. We run one VM dedicated to the project being worked on. We try to mirror the setup on Acquia, so when it is time to lift from local to dev, it's as smooth as it could be. We have not run into an instance yet where Vagrantfile needed to be changed for particular team members. The only real pain point at the moment is winnfsd not working on all Windows machines. It only works for certain people and I cannot determine why yet - it causes us to have to use rsync instead in config.yml which I do not particularly enjoy at all - which is not an issue for DrupalVM but in that plugin. From here it just takes a couple of minutes to hook up PHPStorm to point to the remote PHP interpreter in this vagrant machine, plus any additional things you'd like to set up (Behat, PHPCS, PHPMD, etc). |
I've been watching this thread with interest as it's the primary reason Drupal VM was not suitable for our use case as we needed a centralised provisioning system across multiple projects each with their own configuration differences. The provisioning system also needed to be independent to each project so all dependencies were available to any single project. This was the initial concept behind All provisioning scripts live inside the base box and don't need to be managed within the project, only overrides need to be set, upgrades are managed when updating the base box and project versions are in sync with the box versions. Unprovisioned base boxes are also supported if you need a very customised build. There was also some unintended benefits - linked clones means we only need a single master VM of the base box and each VM is a lightweight clone + we're able to reuse the configuration to build out our CI environment which immediately fixed "only fails in CI" tests and any failed tests are easy to replicate locally. Here's an example of a project which implements Only overrides are set in the project's This project also has a custom post provisioning task to setup And the CI build reuses the same Very interested in hearing the outcome of the BoF @ DC, will try to attend via hangouts if possible. |
I started playing around with d8 base repo to work from and so far came up with a heavily opinionated fork of drupal-project. In case someone is looking for ideas. A lot of it is based on the conventions in roots/bedrock. I've learned to enjoy them and as our team uses both Drupal and Wordpress it helps to have a common structure.
|
@oxyc Is the delegating Vagrantfile committed to the project? Seems that this should moved into place as part of the make process. A couple of things less on-topic - I like the way the drush aliases read from the yaml file. Slick. Curious if local drush site-install plays nicely with the .env and config/environments? Seems that Drush/Drupal install overwrite the settings.php file. good stuff, thanks. |
@joestewart yes it's committed as it only contains a single
Yeah I like the |
@oxyc with the correct command, you can specify the install profile through site-install. http://drushcommands.com/drush-7x/core/site-install/ I've actually moved many of my scripts into jenkins on my vm, but I'm yet to approach the issue of getting the jenkins install on any other vms using the same system working with acquia, ssh and everything... The VM can communicate with almost 200 independent websites and scripts can be made to do exactly that and also make local versions - and ansible could even template one based on variables and run it after completion - if users of drupal-vm are wanting to do something more unique. I suppose the best way forward for automation would be to have some solid data demonstrating the demands of the users of drupal-vm and then discussing options... |
Thank you, everyone, for your amazing amount of input in this issue, outside this issue, in the halls of DrupalCon, etc. And thanks especially for @oxyc and @thom8 (among others) in pushing up some of the code to implement suggestions in here. While we will have an ongoing discussion over ways to optimize Drupal VM for teams moving forward, I think a few of the more recent developments feature-wise will make team-based usage extremely efficient:
I'm missing a few of the other improvements here—forgive me, DrupalCon this year was quite a whirlwind, and I'm still compiling all my notes!—but I'll be wrapping things up a bit more in a blog post soon, and I think any further improvements will be best suited to their own dedicated issues. Just to add a final summary of what I currently see as the best way of utilizing Drupal VM for a team:
|
@geerlingguy Thanks for the description above. The steps you intend on providing will actually allow me to update my system without having to assess each line of code separately on each upgrade. I look forward to this, but it's useful to know the way I've implemented a system like this is already the best possible method to date. |
I'm working on a project where
drupal-vm
has been added to the application repository in abox
directory, and I would like to know if that reflects best practices in the Vagrant community. It would make much more sense to me to have theVagrantfile
in the repo root so that I could issue commands against the VM from anywhere inside my project's directory tree rather than having tocd
intobox
. Would I be correct to assume that projects with from scratch Vagrant setups tend to do it that way? Is there a precedent for Vagrant "distributions" likedrupal-vm
? Is there any way to managedrupal-vm
as a dependency, as with Composer--or is it even intended to be included inside other projects in the way I'm talking about it?The text was updated successfully, but these errors were encountered: