An Absolute Beginner's Guide: Getting Started with DrupalVM

I’ve used DrupalVM on nearly every project over the last 4 years and it’s awesome. This post is all about getting up and running with DrupalVM. If you haven’t already setup your local machine for PHP development, I would read my post on setting up a new Macbook for Local Development first! I would also recommend having a look at the 5 critical strategies for using virtual environments on teams.

Everything we cover in this tutorial will be uploaded to this Github repository so you can easily clone the code and either follow along or review. I also want to mention that if you’re using BLT, DrupalVM support is baked in up to version 11 and available via a plugin in BLT 12 and later. That plugin basically does everything we are going to cover here with a simple recipe ($ blt vm).

I want to quickly cover a few things before we get started on this guide:

First, Jeff Geerling is a community treasure and if you don’t follow his blog / YouTube, you totally should! I had the pleasure of working with him at Acquia for a number of years and I’m still a big fan of his work.

Second, to get a DrupalVM up and running you must have sudo access to your machine (and you will need it every time you start and stop it) due to the editing of the hosts file on your machine. So if you don’t have sudo, let me save you a bit of pain! This isn’t going to work for you.

Getting Started

Assuming your machine already has composer and all the other requirements, we’ll first create a new project (or you can use an existing one if you have one.)

Warning: lots of composer output coming at you!

$ composer create-project acquia/lightning-project madison_example_drupalvm
 1/1:	http://repo.packagist.org/p/provider-latest$5686d9ec901434a1070a125ee9b807f7701a7c1537f0da971612b518e33537b8.json
    Finished: success: 1, skipped: 0, failure: 0, total: 1
    1/1:	http://repo.packagist.org/p/provider-latest$5686d9ec901434a1070a125ee9b807f7701a7c1537f0da971612b518e33537b8.json
    Finished: success: 1, skipped: 0, failure: 0, total: 1
Creating a "acquia/lightning-project" project at "./madison_example_drupalvm"
Installing acquia/lightning-project (8.8.1)
  - Installing acquia/lightning-project (8.8.1): Loading from cache
Created project in /Users/mike.madison/git/examples/madison_example_drupalvm
Loading composer repositories with package information
Updating dependencies (including require-dev)
    1/15:	https://ftp.drupal.org/files/projects/acquia_telemetry-1.0.0-alpha3.zip
    2/15:	https://ftp.drupal.org/files/projects/lightning_core-8.x-5.3.zip
    3/15:	https://ftp.drupal.org/files/projects/inline_entity_form-8.x-1.0-rc7.zip
    4/15:	https://ftp.drupal.org/files/projects/acquia_connector-8.x-1.22.zip
    5/15:	https://ftp.drupal.org/files/projects/panelizer-8.x-4.4.zip
    6/15:	https://ftp.drupal.org/files/projects/lightning_media-8.x-4.2.zip
    7/15:	https://codeload.github.com/acquia/lightning/legacy.zip/1464e1cbf69f6369fe70ecea82bfeddfcbb8f276
    8/15:	https://ftp.drupal.org/files/projects/metatag-8.x-1.14.zip
    9/15:	https://codeload.github.com/drush-ops/drush/legacy.zip/ab5e345a72c9187a7d770486a09691f6526826aa
    10/15:	https://codeload.github.com/nikic/PHP-Parser/legacy.zip/8c58eb4cd4f3883f82611abeac2efbc3dbed787e
    11/15:	https://codeload.github.com/phpDocumentor/ReflectionDocBlock/legacy.zip/da3fd972d6bafd628114f7e7e036f45944b62e9c
    12/15:	https://codeload.github.com/egulias/EmailValidator/legacy.zip/840d5603eb84cc81a6a0382adac3293e57c1c64c
    13/15:	https://codeload.github.com/doctrine/annotations/legacy.zip/bfe91e31984e2ba76df1c1339681770401ec262f
    14/15:	https://codeload.github.com/symfony/var-dumper/legacy.zip/2125805a1a4e57f2340bc566c3013ca94d2722dc
    15/15:	https://codeload.github.com/swagger-api/swagger-ui/legacy.zip/752488edf7ff5b3f98fde2d069e4cd5eff150cd0
    Finished: success: 15, skipped: 0, failure: 0, total: 15
Package operations: 165 installs, 0 updates, 0 removals
  - Installing cweagans/composer-patches (1.6.7): Loading from cache
No patches supplied.
Gathering patches for dependencies. This might take a minute.
  - Installing composer/installers (v1.9.0): Loading from cache
  - Installing drupal/core-composer-scaffold (9.0.3): Loading from cache
  - Installing oomphinc/composer-installers-extender (v1.1.2): Loading from cache
  - Installing symfony/polyfill-mbstring (v1.18.1): Loading from cache
  - Installing symfony/polyfill-php80 (v1.18.1): Loading from cache
  - Installing symfony/polyfill-php72 (v1.18.1): Loading from cache
  - Installing paragonie/random_compat (v9.99.99): Loading from cache
  - Installing symfony/polyfill-php70 (v1.18.1): Loading from cache
  - Installing symfony/polyfill-intl-normalizer (v1.18.1): Loading from cache
  - Installing symfony/polyfill-intl-idn (v1.18.1): Loading from cache
  - Installing psr/log (1.1.3): Loading from cache
  - Installing pear/pear_exception (v1.0.1): Loading from cache
  - Installing pear/console_getopt (v1.4.3): Loading from cache
  - Installing pear/pear-core-minimal (v1.10.10): Loading from cache
  - Installing pear/archive_tar (1.4.9): Loading from cache
  - Installing symfony/polyfill-ctype (v1.18.1): Loading from cache
  - Installing symfony/var-dumper (v4.4.11): Loading from cache
  - Installing symfony/debug (v4.4.11): Loading from cache
  - Installing psr/container (1.0.0): Loading from cache
  - Installing symfony/polyfill-util (v1.18.1): Loading from cache
  - Installing symfony/polyfill-php56 (v1.18.1): Loading from cache
  - Installing symfony/http-foundation (v3.4.43): Loading from cache
  - Installing symfony/event-dispatcher (v3.4.43): Loading from cache
  - Installing symfony/http-kernel (v3.4.43): Loading from cache
  - Installing asm89/stack-cors (1.3.0): Loading from cache
  - Installing composer/semver (1.5.1): Loading from cache
  - Installing psr/http-message (1.0.1): Loading from cache
  - Installing laminas/laminas-zendframework-bridge (1.0.4): Loading from cache
  - Installing masterminds/html5 (2.7.3): Loading from cache
  - Installing doctrine/lexer (1.2.1): Loading from cache
  - Installing egulias/email-validator (2.1.19): Loading from cache
  - Installing stack/builder (v1.0.6): Loading from cache
  - Installing laminas/laminas-stdlib (3.2.1): Loading from cache
  - Installing laminas/laminas-escaper (2.6.1): Loading from cache
  - Installing laminas/laminas-feed (2.12.2): Loading from cache
  - Installing symfony/routing (v3.4.43): Loading from cache
  - Installing ralouphie/getallheaders (3.0.3): Loading from cache
  - Installing guzzlehttp/psr7 (1.6.1): Loading from cache
  - Installing guzzlehttp/promises (v1.3.1): Loading from cache
  - Installing guzzlehttp/guzzle (6.5.5): Loading from cache
  - Installing doctrine/annotations (1.10.4): Loading from cache
  - Installing doctrine/reflection (1.2.1): Loading from cache
  - Installing typo3/phar-stream-wrapper (v3.1.5): Loading from cache
  - Installing symfony/polyfill-iconv (v1.18.1): Loading from cache
  - Installing symfony/psr-http-message-bridge (v1.2.0): Loading from cache
  - Installing symfony/class-loader (v3.4.43): Loading from cache
  - Installing laminas/laminas-diactoros (1.8.7p2): Loading from cache
  - Installing easyrdf/easyrdf (0.9.1): Loading from cache
  - Installing symfony-cmf/routing (1.4.1): Loading from cache
  - Installing doctrine/event-manager (1.1.1): Loading from cache
  - Installing doctrine/collections (1.6.7): Loading from cache
  - Installing doctrine/cache (1.10.2): Loading from cache
  - Installing doctrine/persistence (1.3.8): Loading from cache
  - Installing doctrine/inflector (1.4.3): Loading from cache
  - Installing doctrine/common (2.13.3): Loading from cache
  - Installing twig/twig (v1.43.1): Loading from cache
  - Installing symfony/yaml (v3.4.43): Loading from cache
  - Installing symfony/process (v3.4.43): Loading from cache
  - Installing symfony/translation (v3.4.43): Loading from cache
  - Installing symfony/validator (v3.4.43): Loading from cache
  - Installing symfony/serializer (v3.4.43): Loading from cache
  - Installing symfony/dependency-injection (v3.4.43): Loading from cache
  - Installing symfony/console (v3.4.43): Loading from cache
  - Installing drupal/core (8.9.3): Loading from cache
  - Applying patches for drupal/core
    https://www.drupal.org/files/issues/2020-02-07/2869592-remove-update-warning-34.patch (2869592 - Disabled update module shouldn't produce a status report warning)
    https://www.drupal.org/files/issues/2019-11-27/2815221-125.patch (2815221 - Add quickedit to the latest-revision route)
    https://www.drupal.org/files/issues/2019-11-05/1356276-531-8.8.x-4.patch (1356276 - Allow profiles to define a base/parent profile and load them in the correct order)
    https://www.drupal.org/files/issues/2018-07-09/2914389-8-do-not-test.patch (2914389 - Allow profiles to exclude dependencies of their parent)
  - Installing webmozart/assert (1.9.1): Loading from cache
  - Installing phpdocumentor/reflection-common (2.2.0): Loading from cache
  - Installing phpdocumentor/type-resolver (1.3.0): Loading from cache
  - Installing phpdocumentor/reflection-docblock (4.3.4): Loading from cache
  - Installing drupal/moderation_sidebar (1.4.0): Loading from cache
  - Installing drupal/ctools (3.4.0): Loading from cache
  - Installing drupal/panels (4.4.0): Loading from cache
  - Applying patches for drupal/panels
    https://www.drupal.org/files/issues/panels-ipe-2878684-3.patch (2878684 - Use String.match to correlate regions when switching Layouts in Panels IPE)
  - Installing drupal/page_manager (4.0.0-beta6): Loading from cache
  - Installing drupal/moderation_dashboard (1.0.0-beta2): Loading from cache
  - Installing kub-at/php-simple-html-dom-parser (1.9.1): Loading from cache
  - Installing ezyang/htmlpurifier (v4.13.0): Loading from cache
  - Installing caxy/php-htmldiff (v0.1.9): Loading from cache
  - Installing mkalkbrenner/php-htmldiff-advanced (0.0.8): Loading from cache
  - Installing drupal/diff (1.0.0): Loading from cache
  - Installing drupal/conflict (2.0.0-alpha2): Loading from cache
  - Installing drupal/autosave_form (1.1.0): Loading from cache
  - Applying patches for drupal/autosave_form
    https://www.drupal.org/files/issues/2020-05-15/autosave_form-1.1-core-version-requirement.patch (3109317 - Run tests against Drupal 9)
  - Installing drupal/token (1.7.0): Loading from cache
  - Installing drupal/search_api (1.17.0): Loading from cache
  - Installing drupal/redirect (1.6.0): Loading from cache
  - Installing drupal/pathauto (1.8.0): Loading from cache
  - Installing drupal/metatag (1.14.0): Loading from cache
  - Installing drupal/contact_storage (1.1.0): Loading from cache
  - Installing drupal/acquia_telemetry-acquia_telemetry (1.0.0-alpha3): Loading from cache
  - Installing drupal/lightning_core (5.3.0): Loading from cache
  - Installing drupal/acquia_connector (1.22.0): Loading from cache
  - Installing drupal/lightning_workflow (3.15.0): Loading from cache
  - Installing vardot/blazy (1.8.2.1): Loading from cache
  - Installing drupal/video_embed_field (2.4.0): Loading from cache
  - Installing drupal/blazy (2.1.0): Loading from cache
  - Installing drupal/slick (2.2.0): Loading from cache
  - Installing drupal/slick_entityreference (2.0.0): Loading from cache
  - Installing j7mbo/twitter-api-php (1.0.6): Loading from cache
  - Installing drupal/media_entity_twitter (2.4.0): Loading from cache
  - Installing drupal/media_entity_instagram (2.1.0): Loading from cache
  - Installing drupal/libraries (3.0.0-alpha1): Loading from cache
  - Installing drupal/crop (2.1.0): Loading from cache
  - Installing drupal/image_widget_crop (2.3.0): Loading from cache
  - Installing drupal/embed (1.4.0): Loading from cache
  - Installing drupal/dropzonejs (2.1.0): Loading from cache
  - Installing bower-asset/jquery (3.5.1): Loading from cache
  - Installing bower-asset/slick-carousel (v1.8.1): Loading from cache
  - Installing bower-asset/dropzone (v5.7.2): Loading from cache
  - Installing bower-asset/cropper (v2.3.4): Loading from cache
  - Installing drupal/views_infinite_scroll (1.7.0): Loading from cache
  - Installing drupal/inline_entity_form (1.0.0-rc7): Loading from cache
  - Installing drupal/entity_embed (1.1.0): Loading from cache
  - Installing drupal/entity_browser (2.5.0): Loading from cache
  - Installing drupal/lightning_media (4.2.0): Loading from cache
  - Installing drupal/simple_gmap (3.0.0): Loading from cache
  - Installing drupal/panels_ipe (4.4.0)
  - Installing drupal/ctools_block (3.4.0)
  - Installing drupal/panelizer (4.4.0): Loading from cache
  - Applying patches for drupal/panelizer
    https://www.drupal.org/files/issues/2020-03-23/2778565-47.patch (2778565 - Multilingual support for Panelizer)
  - Installing drupal/layout_library (1.0.0-beta2): Loading from cache
  - Installing drupal/layout_builder_st (1.0.0-alpha2): Loading from cache
  - Installing drupal/entity_browser_block (1.1.0): Loading from cache
  - Installing drupal/entity_block (1.0.0-beta3): Loading from cache
  - Installing drupal/bg_image_formatter (1.14.0): Loading from cache
  - Installing drupal/layout_builder_styles (1.0.0-beta2): Loading from cache
  - Installing drupal/layout_builder_restrictions (2.7.0): Loading from cache
  - Installing drupal/lightning_layout (2.7.0): Loading from cache
  - Installing drupal/schemata (1.0.0-beta2): Loading from cache
  - Installing drupal/schemata_json_schema (1.0.0-beta2)
  - Installing drupal/openapi (2.0.0-rc3): Loading from cache
  - Installing drupal/openapi_rest (2.0.0-rc2): Loading from cache
  - Installing drupal/consumers (1.11.0): Loading from cache
  - Installing defuse/php-encryption (v2.2.1): Loading from cache
  - Installing lcobucci/jwt (3.3.2): Loading from cache
  - Installing league/event (2.2.0): Loading from cache
  - Installing league/oauth2-server (7.4.0): Loading from cache
  - Installing drupal/simple_oauth (4.5.0): Loading from cache
  - Installing swagger-api/swagger-ui (v3.31.1): Loading from cache
  - Installing drupal/openapi_ui (1.0.0-rc2): Loading from cache
  - Installing drupal/openapi_ui_swagger (1.0.0-rc3): Loading from cache
  - Installing drupal/openapi_ui_redoc (1.0.0-rc2): Loading from cache
  - Installing drupal/openapi_jsonapi (2.0.0-rc2): Loading from cache
  - Installing drupal/lightning_api (4.6.0): Loading from cache
  - Installing acquia/lightning (4.1.6): Loading from cache
  - Installing webmozart/path-util (2.3.0): Loading from cache
  - Installing webflo/drupal-finder (1.2.0): Loading from cache
  - Installing symfony/finder (v4.4.11): Loading from cache
  - Installing nikic/php-parser (v4.8.0): Loading from cache
  - Installing dnoegel/php-xdg-base-dir (v0.1.1): Loading from cache
  - Installing psy/psysh (v0.10.4): Loading from cache
  - Installing container-interop/container-interop (1.2.0): Loading from cache
  - Installing league/container (2.4.1): Loading from cache
  - Installing dflydev/dot-access-data (v1.1.0): Loading from cache
  - Installing grasmash/yaml-expander (1.4.0): Loading from cache
  - Installing grasmash/expander (1.0.0): Loading from cache
  - Installing consolidation/config (1.2.1): Loading from cache
  - Installing consolidation/site-alias (3.0.1): Loading from cache
  - Installing consolidation/site-process (2.1.0): Loading from cache
  - Installing symfony/filesystem (v4.4.11): Loading from cache
  - Installing consolidation/self-update (1.2.0): Loading from cache
  - Installing consolidation/output-formatters (3.5.0): Loading from cache
  - Installing consolidation/log (1.1.1): Loading from cache
  - Installing consolidation/annotated-command (2.12.0): Loading from cache
  - Installing consolidation/robo (1.4.12): Loading from cache
  - Installing consolidation/filter-via-dot-access-data (1.0.0): Loading from cache
  - Installing chi-teck/drupal-code-generator (1.32.1): Loading from cache
  - Installing drush/drush (9.7.2): Loading from cache
paragonie/random_compat suggests installing ext-libsodium (Provides a modern crypto API that can be used to generate random bytes.)
pear/archive_tar suggests installing ext-xz (Lzma2 compression support.)
symfony/http-kernel suggests installing symfony/browser-kit
symfony/http-kernel suggests installing symfony/config
laminas/laminas-feed suggests installing laminas/laminas-cache (Laminas\Cache component, for optionally caching feeds between requests)
laminas/laminas-feed suggests installing laminas/laminas-db (Laminas\Db component, for use with PubSubHubbub)
laminas/laminas-feed suggests installing laminas/laminas-http (Laminas\Http for PubSubHubbub, and optionally for use with Laminas\Feed\Reader)
laminas/laminas-feed suggests installing laminas/laminas-servicemanager (Laminas\ServiceManager component, for easily extending ExtensionManager implementations)
laminas/laminas-feed suggests installing laminas/laminas-validator (Laminas\Validator component, for validating email addresses used in Atom feeds and entries when using the Writer subcomponent)
symfony/routing suggests installing symfony/config (For using the all-in-one router or any loader)
symfony/routing suggests installing symfony/expression-language (For using expression matching)
guzzlehttp/psr7 suggests installing zendframework/zend-httphandlerrunner (Emit PSR-7 responses)
symfony/psr-http-message-bridge suggests installing nyholm/psr7 (For a super lightweight PSR-7/17 implementation)
symfony/class-loader suggests installing symfony/polyfill-apcu (For using ApcClassLoader on HHVM)
easyrdf/easyrdf suggests installing ml/json-ld (~1.0)
doctrine/cache suggests installing alcaeus/mongo-php-adapter (Required to use legacy MongoDB driver)
symfony/translation suggests installing symfony/config
symfony/validator suggests installing psr/cache-implementation (For using the metadata cache.)
symfony/validator suggests installing symfony/intl
symfony/validator suggests installing symfony/config
symfony/validator suggests installing symfony/property-access (For accessing properties within comparison constraints)
symfony/validator suggests installing symfony/expression-language (For using the Expression validator)
symfony/serializer suggests installing psr/cache-implementation (For using the metadata cache.)
symfony/serializer suggests installing symfony/property-info (To deserialize relations.)
symfony/serializer suggests installing symfony/config (For using the XML mapping loader.)
symfony/serializer suggests installing symfony/property-access (For using the ObjectNormalizer.)
symfony/dependency-injection suggests installing symfony/config
symfony/dependency-injection suggests installing symfony/expression-language (For using expressions in service container configuration)
symfony/dependency-injection suggests installing symfony/proxy-manager-bridge (Generate service proxies to lazy load them)
symfony/console suggests installing symfony/lock
drupal/search_api suggests installing drupal/facets (Adds the ability to create faceted searches.)
drupal/search_api suggests installing drupal/search_api_autocomplete (Allows adding autocomplete suggestions to search fields.)
drupal/search_api suggests installing drupal/search_api_solr (Adds support for using Apache Solr as a backend.)
drupal/dropzonejs suggests installing enyo/dropzone (Required to user drupal/dropzonejs. Dropzone is an easy to use drag'n'drop library.)
psy/psysh suggests installing ext-pdo-sqlite (The doc command requires SQLite to work.)
psy/psysh suggests installing hoa/console (A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit.)
consolidation/robo suggests installing henrikbjorn/lurker (For monitoring filesystem changes in taskWatch)
consolidation/robo suggests installing patchwork/jsqueeze (For minifying JS files in taskMinify)
consolidation/robo suggests installing natxet/CssMin (For minifying CSS files in taskMinify)
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Writing lock file
Generating autoload files
36 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
Scaffolding files for drupal/core:
  - Copy [project-root]/.editorconfig from assets/scaffold/files/editorconfig
  - Copy [project-root]/.gitattributes from assets/scaffold/files/gitattributes
  - Copy [web-root]/.csslintrc from assets/scaffold/files/csslintrc
  - Copy [web-root]/.eslintignore from assets/scaffold/files/eslintignore
  - Copy [web-root]/.eslintrc.json from assets/scaffold/files/eslintrc.json
  - Copy [web-root]/.ht.router.php from assets/scaffold/files/ht.router.php
  - Copy [web-root]/.htaccess from assets/scaffold/files/htaccess
  - Copy [web-root]/example.gitignore from assets/scaffold/files/example.gitignore
  - Copy [web-root]/index.php from assets/scaffold/files/index.php
  - Copy [web-root]/INSTALL.txt from assets/scaffold/files/drupal.INSTALL.txt
  - Copy [web-root]/README.txt from assets/scaffold/files/drupal.README.txt
  - Copy [web-root]/robots.txt from assets/scaffold/files/robots.txt
  - Copy [web-root]/update.php from assets/scaffold/files/update.php
  - Copy [web-root]/web.config from assets/scaffold/files/web.config
  - Copy [web-root]/sites/README.txt from assets/scaffold/files/sites.README.txt
  - Copy [web-root]/sites/development.services.yml from assets/scaffold/files/development.services.yml
  - Copy [web-root]/sites/example.settings.local.php from assets/scaffold/files/example.settings.local.php
  - Copy [web-root]/sites/example.sites.php from assets/scaffold/files/example.sites.php
  - Copy [web-root]/sites/default/default.services.yml from assets/scaffold/files/default.services.yml
  - Copy [web-root]/sites/default/default.settings.php from assets/scaffold/files/default.settings.php
  - Copy [web-root]/modules/README.txt from assets/scaffold/files/modules.README.txt
  - Copy [web-root]/profiles/README.txt from assets/scaffold/files/profiles.README.txt
  - Copy [web-root]/themes/README.txt from assets/scaffold/files/themes.README.txt
> rm -r -f .travis.yml behat.yml .travis-ci

At this point, I have a project that is all ready to go using the Acquia Lightning Project. Now we’re going to add DrupalVM to this project so we can get a VM up and running!

From here, CD into the directory.

$ cd madison_example_drupalvm/



And we’ll go ahead and require DrupalVM as a dev dependency in composer.

$ composer require --dev geerlingguy/drupal-vm
    1/1:	https://asset-packagist.org/p/provider-latest/cb0378f8cc9054dd18142ad0a9756da5f4ec6caec37b83950e372e17c0917319.json
    Finished: success: 1, skipped: 0, failure: 0, total: 1
    1/2:	http://repo.packagist.org/p/provider-latest$81f9d06a9e38347f3cf1a46070e9974ff43c819f1240bca6a4aa9def9bf45527.json
    2/2:	http://repo.packagist.org/p/provider-2020-04$71909829e9f67f89071634f5f93733db4a73297aac017b5c4f877c91a7e7297d.json
    Finished: success: 2, skipped: 0, failure: 0, total: 2
Using version ^6.0 for geerlingguy/drupal-vm
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
    1/1:	https://codeload.github.com/geerlingguy/drupal-vm/legacy.zip/0257c5dfaaca71f2125d3076976b143a4fd63a86
    Finished: success: 1, skipped: 0, failure: 0, total: 1
Package operations: 1 install, 0 updates, 0 removals
No patches supplied.
Gathering patches for dependencies. This might take a minute.
  - Installing geerlingguy/drupal-vm (6.0.0): Loading from cache
Package container-interop/container-interop is abandoned, you should avoid using it. Use psr/container instead.
Writing lock file
Generating autoload files
37 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

The next step is to configure your VM. DrupalVM ships with an example config file which you can find here: vendor/geerlingguy/drupal-vm/default.config.yml

We are going to make a local copy of this config file so you can customize it as needed for your project. In your project root, make a folder (I usually call it box, thanks to BLT’s default) and copy the default.config.yml folder into this new folder and rename it to box.config.

I’m not going to cover customizing the config file in this tutorial, right now the goal is just to get up and running with the VM. But there are a couple of minor tweaks I would recommend for now just to better align with the Lightning Project composer setup:

  • drupal_composer_install_dir: "/var/www/drupalvm"
  • drupal_core_path: "{{ drupal_composer_install_dir }}/docroot"

There are a TON of really powerful customizations that you can make to DrupalVM (and this config file is the place to do it). Just remember: any config file changes you make require a reprovision. If you do them all up front, no big deal. But once you’ve build the VM, every change in config.yml requires you to run:

 $ vagrant reload --provision. 

Two of the most important keys are (especially if you’re planning on having multiple VMs running across multiple projects):

  • vagrant_ip
  • vagrant_hostname

The next step is to place a Vagrantfile in the root of your project as well. In this instance, we do NOT want to change the default file that DrupalVM ships with, we just need to override a few specific variables to tell Vagrant where to find all the good stuff (since it’s in the vendor directory). Simply download this file from the BLT plugin and place it in your repo root. Not change the DRUPALVM_CONFIG_DIR if you are planning on using a folder other than ‘box.’

Provisioning Your First VM

OK! Quick checklist time.

  • project to build in (for this example, Acquia’s Lightning Project) w/ composer dependencies installed

  • DrupalVM added as a dependency and installed

  • config file placed

  • Vagrantfile placed

Now it’s time for the magic! Run the command

$ vagrant up

This will take a while. Like 5-20 minutes depending on your host machine’s power and your internet connection. You will be prompted during this process to enter your administrative password for your host machine. You will also most likely be prompted to allow Finder to mount the drive for the VM. So, this isn’t just a set it and forget it process! You do need to semi keep an eye on it.

I will spare you 20 minutes of composer output, but when the process is done, you should see this:

Screen Shot 2020-08-14 at 2.15.45 PM.png

If you didn’t muck about with the config.yml file, you should be able to open your web browser and go to http://drupalvm.test and visit your new shiny vm!

Screen Shot 2020-08-14 at 2.21.49 PM.png

What to do next

Get it into Git

The very first thing you should do is commit the work we just did! It’s important for your VM config to live in your git repository so that your team (and you) can benefit from version control. If it’s working, we want to keep it working (and if it stops working, we want to revert to a working state). You can also reference the example repository I’ve posted to Github.

Note: the Lightning Project .gitignore file is missing a rule for the .vagrant folder. We do not want to commit this directory, so add the following to your .gitignore file at the project root:

# Ignore Vagrant Folder
.vagrant/

We do want to commit these two files:

  • box/config.yml

  • Vagrantfile

Run your first Drush Command

As a general rule when working with VMs, you want to work “inside” the container. For DrupalVM this is accomplished via your terminal by running:

$ vagrant ssh

You can exit the container again by running:

$ exit

From inside the container, you can run your first drush command!

$ drush status
Drupal version   : 8.9.3                                          
 Site URI         : http://default                               DB driver        : mysql                                        DB hostname      : localhost                                    DB port          :                                              DB username      : drupal                                       DB name          : drupal                                       Database         : Connected                                    Drupal bootstrap : Successful                                   Default theme    : bartik                                       Admin theme      : seven                                        PHP binary       : /usr/bin/php7.4                              PHP config       : /etc/php/7.4/cli/php.ini                     PHP OS           : Linux                                        Drush script     : /usr/local/bin/drush                         Drush version    : 10.3.2                                       Drush temp       : /tmp                                         Drush configs    : /home/vagrant/.drush/drush.yml                           /var/www/drupalvm/vendor/drush/drush/drush.yml 
 Install profile  : standard                                     Drupal root      : /var/www/drupalvm/docroot                    Site path        : sites/default                                Files, Public    : sites/default/files                          Files, Temp      : /tmp                      

From here, you can now start building your first Drupal site inside of a VM.

Just use:

$ drush uli 

to log into the site (you will likely have to replace the http://default in the url with http://drupalvm.test manually). Just copy and paste the url out of your terminal window and into your browser to log into Drupal.

Happy site building!

Photo by Bruce Mars from StockSnap

Related Content