/dotrun

Primary LanguagePython

dotrun

A tool for developing Node.js and Python projects

dotrun

dotrun makes use of snap confinement to provide a predictable sandbox for running Node and Python projects.

Features:

  • Make use of standard package.json script entrypoints:
    • dotrun runs yarn run start within the snap confinement
    • dotrun foo runs yarn run foo within the snap confinement
  • Detect changes in package.json and only run yarn install when needed
  • Detect changes in requirements.txt and only run pip3 install when needed
  • Run scripts using environment variables from .env and .env.local files
  • Keep python dependencies in .venv in the project folder for easy access

Usage

$ dotrun          # Install dependencies and run the `start` script from package.json
$ dotrun clean    # Delete `node_modules`, `.venv`, `.dotrun.json`, and run `yarn run clean`
$ dotrun install  # Force install node and python dependencies
$ dotrun exec     # Start a shell inside the dotrun environment
$ dotrun exec {command}          # Run {command} inside the dotrun environment
$ dotrun {script-name}           # Install dependencies and run `yarn run {script-name}`
$ dotrun -s {script}             # Run {script} but skip installing dependencies
$ dotrun --env FOO=bar {script}  # Run {script} with FOO environment variable

Installation

Ubuntu

The best way to install dotrun with all the requirements is by running the following script:

curl -s https://raw.githubusercontent.com/canonical-web-and-design/dotrun/master/scripts/install-dotrun-docker.sh | bash

What the script does

  • Add the user to the docker group
  • Install the dotrun snap and the docker snap
  • It will also set the needed plugs:
    • dotrun:dot-npmrc gives the snap access to read the ~/.npmrc
    • dotrun:dot-yarnrc gives the snap access to read the ~/.yarnrc
    • dotrun:docker-executables docker:docker-executables dotrun:docker-cli docker:docker-daemon will make it possible to the dotrun snap to use docker. These docker plugs and the docker snap are optional but needed for projects with docker-compose.yaml files.

MacOS

On MacOS, dotrun should be installed and run inside a multipass VM, using sudo snap install dotrun as above. Any server running within the multipass VM will then be available at the VM's IP address, which can be obtained from multipass list.

Given that file access over a virtual network share is incredibly slow in MacOS, it is recommended to keep your project files inside the multipass VM directly and then share them with your host system from there if you want to open them in a graphical editor.

See @hatched's guide for how to achieve this setup.

Automated installation with Multipass

We are maintaining a bash script that will install Multipass in your system and configure your machine to proxy the dotrun command to a Multipass instance.

To use it:

curl -s https://raw.githubusercontent.com/canonical-web-and-design/dotrun/master/scripts/install-with-multipass.sh | bash

It will create a dotrun-projects folder in your home directory, you can clone projects here and use dotrun transparently.

Converting existing projects

On the whole, our existing projects should run out of the box with:

dotrun build
dotrun serve

A caveat to this for our Python website projects is that dotrun will only work with Gunicorn >= 20.0.0. To achieve this, our projects should upgrade to using at least version 0.4.3 of flask-base.

Updating projects

To fully support it you should do the following:

  • For Python projects, ensure Talisker is at 0.16.0 or greater in requirements.txt
  • Add .dotrun.json and .venv to .gitignore
  • Create a start script in package.json to do everything needed to set up local development. E.g.: "start": "concurrently --raw 'yarn run watch' 'yarn run serve'"
    • The above command makes use of concurrently - you might want to consider this
  • Older versions of Gunicorn are incompatible with strict confinement so we need Gunicorn >= 20
    • The update landed in Talisker but at the time of writing hasn't made it into a new version
    • If there's no new version of Talisker, simply add gunicorn==20.0.4 to the bottom of requirements.txt

These steps can be completed without effecting the old ./run script, which should continue working.

However, once you're ready to completely switch over to dotrun, simply go ahead and remove the run script.

Testing

The test folder contains a bunch of tests, written in Python, against the dotrun binary, using example projects in the test/fixtures folder.

These tests can be run against the current codebase in a couple of different ways:

Testing the python module

This is the quickest way to test the code, but it's not as complete as it won't find error that might relate to the snap confinement.

python3 -m venv .venv  # Create a python environment for testing
source .venv/bin/activate
pip3 install -e .  # Install the dotrun module as a python package
python3 -m unittest discover --start-directory tests  # Run the tests against the installed python package

Testing the snap

To do a complete test, it's wise to build the snap from the current codebase and then test the snap itself.

If you have multipass installed, you can do this using multipass for confinement pretty simply:

scripts/test-snap-using-multipass

This runs the same tests in the tests directory against an actual snap installed into multipass.

Automated tests of pull requests

The "PR" action builds the snap and runs the tests, similar to the "multipass" solution above. This will run against every pull request.

Publish

All the changes made to the master branch will be automatically published in the candidate track of the snap. To use candidate:

sudo snap install dotrun --candidate