Using multipass To Create A WriteFreely Dev VM
If you've ended up at this blog post, you're probably like me: you've found a change you'd like to make to WriteFreely, but you can't (or don't want to) install all of its development dependencies on your machine. This guide will show you how to use
multipass to set up a WriteFreely development VM so that you don't need to make changes to your host.
Note: If you run into any problems with this guide, feel free to reach out to me on the fediverse, I'm Odd_Bloke@wrestle.town. I can't promise I'll be able to help, but I will at the very least be sympathetic.
Updated (2019/08/19): This guide was updated to use
multipass shell <vm> instead of
multipass exec <vm> /bin/bash. This is more idiomatic, and avoids some known bugs.
- A system with multipass installed
- If you're on a system with
snapd(e.g. Ubuntu), this is as simple as
sudo snap install --classic --beta multipass
- For reference, I'm using the Ubuntu development release with the multipass beta snap (v0.8.0).
- multipass is cross-platform, though, so hopefully you'll be able to follow this guide on Windows or macOS too! You can find installers for these platforms on multipass' GitHub releases page. (Let me know if you hit problems!)
- If you're on a system with
- Enough RAM to give a VM 4GB of it
- multipass' default is 1GB, and I ran out of memory during the installation of WriteFreely's Go dependencies when I tried 2GB as well.
- It's certainly possible you could tune this down some. If you do so successfully, please let me know so I can update this guide!
That's it! We're going to do everything else inside our VM.
Creating our development VM
This is pretty simple:
$ multipass launch bionic --name writefreely-dev --mem 4G
This is going to fetch the latest Ubuntu 18.04 LTS (Bionic Beaver) image and create a VM named
writefreely-dev from it, giving that VM 4GB of memory. (If you want to name your VM something different, go ahead! But: don't forget to use that name in later steps.)
(This step can sometimes take a while, if the Ubuntu data centre is under heavy network load (which it often is!). Don't worry if the progress is slow because that is, unfortunately, normal.)
Installing prerequisites in our development VM
First, let's get a shell in our development VM:
$ multipass shell writefreely-dev <... long MOTD content ...> multipass@writefreely-dev:~$
Again, nice and simple!
OK, so now we can go and look at the Prerequisites section of the WriteFreely Development Setup guide and see what we need:
- Go 1.10+
OK, so let's do these one at a time.
Installing Go 1.10+
We're going to use the go snap to install Go:
$ sudo snap install --classic go go 1.12.9 from Michael Hudson-Doyle (mwhudson) installed
$ go version go version go1.12.9 linux/amd64
Great, nailed it! On to the next thing.
From my testing so far, node.js 8.x is sufficient for WriteFreely so we can just use the Ubuntu packages for it (make sure to install both
npm; unlike upstream, they don't come bundled together in Ubuntu):
$ sudo apt update ... $ sudo apt install -y nodejs npm ... $ node -v v8.10.0 $ npm -v 3.5.2
OK, prerequisites sorted, on to getting our WriteFreely development environment set up.
apt update might tell you that there are upgrades available; you may as well apply those by running
sudo apt upgrade.)
Setting up our WriteFreely development environment
Nobody wants to have to run their IDE or editor inside of their development VM, so we're going to have a WriteFreely tree on our host that we mount into the development VM.
(Note that these instructions diverge from the Development Setup guide because we're splitting things across host and VM.)
On the host
Let's start by cloning the WriteFreely repo. You can put this wherever you want (I use
~/personal_dev), just make sure to make a note of the path to the repo for the next step. Run this command:
$ git clone https://github.com/writeas/writefreely/ \ ~/personal_dev/writefreely
Now, we want to create the directory for multipass to mount to (multipass should handle this itself, I think, so I'll be filing a bug in the near future):
multipass exec writefreely-dev -- \ mkdir -p go/src/github.com/writeas/writefreely
Next, we're going to ask
mount the host's directory into the directory we just created in our development VM:
$ multipass mount \ ~/personal_dev/writefreely \ writefreely-dev:/home/multipass/go/src/github.com/writeas/writefreely
And we can check that that's worked:
$ multipass exec writefreely-dev -- \ head -n1 go/src/github.com/writeas/writefreely/CONTRIBUTING.md # Contributing to WriteFreely
Great! So now we have a WriteFreely tree that we can easily edit from our host, mounted in to our VM so we can actually run WriteFreely there.
(BTW, did you notice that we used
multipass exec to run
head directly within the VM? If you don't need a full shell, use
Oh, there's one last piece of information we need to grab before we jump into installing and configuring WriteFreely: the IP address of our development VM. You can find this by running
$ multipass list Name State IPv4 Image writefreely-dev Running 10.76.88.177 Ubuntu 18.04 LTS
In my case, the address is
10.76.88.177. Make a note of yours!
In our VM
OK, let's get back in the VM:
$ multipass shell writefreely-dev multipass@writefreely-dev:~$
And let's change to our mounted directory:
$ cd go/src/github.com/writeas/writefreely/
We're now basically at the point after the first two commands in the “Setting up” section of the Development Setup guide, and we are effectively going to run through those commands in sequence. However, as we aren't running our development server on our host, there are a couple of specific choices we need to make.
First, though, let's install all of our dependencies and compile WriteFreely. To do that, we first need to do a little bit of house-keeping. Go will install binaries into
~/go/bin, and we need to make sure that those binaries are available to run by adding them to our PATH. We'll also modify
.bashrc so that we don't have to remember to do this every time we log in:
$ export PATH=$PATH:~/go/bin $ echo 'export PATH=$PATH:~/go/bin' >> ~/.bashrc
We can then install our dependencies and compile WriteFreely:
$ export GO111MODULE=on # Save ourselves some time next time we login $ echo 'export GO111MODULE=on' >> ~/.bashrc $ make build
This will take a couple of minutes. (
GO111MODULE=on is required to be set, and we also add it to our .bashrc so we don't have to remember this every time.)
Once this is complete, we're ready to configure our development WriteFreely instance by running:
$ make install
This is going to prompt you with a few questions. The important answers are:
- Environment: “Development”
- Database driver: “SQLite”
- Public URL:
http://<IP ADDRESS>:8080, replacing
<IP ADDRESS>with the VM's IP address you made a note of earlier
Other than those, you can just accept the defaults. (Of course, make sure you remember your username/password, you'll need them to log in to your development site once it's running.)
We're very, very close to having a running site! The last change we need to make is to configure the development server to accept connections from our host. (The default configuration will only accept connections from the machine that it's running on, which is a very sensible default if you're running this on your host directly, but doesn't work for us.)
To do this, open up
config.ini in your editor of choice (in or out of the VM, either should work fine) and change the
bind value to “0.0.0.0”. After editing, that line should look like this:
bind = 0.0.0.0
And now, finally, in our VM, we can start the development server:
$ make run
This will print out a bunch of logging with the line
Serving on http://0.0.0.0:8080 towards the end. Once you see that, you should be able to browse to the Public URL you configured before (
http://<IP ADDRESS>:8080, remember?) and see your development instance!
Log in using the username/password you configured during
make install and start making WriteFreely even better!