Development environment setup¶
We use a bunch of tools while developing Reahl itself. Some are just useful, some enable remote pair programming, and others make sure our tests consistently run the same way.
To ensure things always work, and always work consistently, we employ Docker. The Reahl dev Docker image has all of these development tools pre-installed and configured as well as a clean venv with Reahl itself.
If you just want to develop on your own project (even if it does not use Reahl), you can still use the same tools as we do.
The Reahl dev Docker image¶
To use the Reahl dev Docker image, install Docker and docker-compose, then put the following docker-compose.yaml file in your development directory:
version: "3.9"
services:
# BUILDKIT_PROGRESS=plain COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build reahl
reahl:
container_name: reahl
restart: always
init: true
image: iwanvosloo/reahl-dev:5.2
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
- "8383:8383"
volumes:
- .:/home/developer/reahl
- type: bind
source: ~/.ssh/authorized_keys_docker
target: /home/developer/.ssh/authorized_keys2
Inside the Docker dev image¶
Inside the Docker container, we have:
Projects installed that Reahl depends on;
A Python3 virtualenv prepared for Reahl development;
A version of Firefox for tests;
A matching version of Geckodriver to enable Selenium tests;
Various ways to access the GUI on the Docker container; and
Configuration for pip to allow local installation of what is built (useful for tox tests).
Using the container¶
Run the container:
touch ~/.bash_history_docker
touch ~/.ssh/authorized_keys_docker
docker-compose up -d
docker exec -u developer -ti reahl bash -l
Note
The first time you do this might take a while, since the image needs to be downloaded and prepared.
Run an example inside the container:
cd ~/reahl
reahl example tutorial.hello
cd hello
reahl setup develop -N
reahl createdbuser etc
reahl createdb etc
reahl createdbtables etc
reahl serve etc
On your own machine, navigate to the example at: http://localhost:8000
Ssh to the dev container¶
Ssh-ing into the container is needed for pair programming or to see the GUI of the browser that runs selenium tests.
To be able to ssh, put your public ssh key on your host machine into ~/.ssh/authorized_keys_docker:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys_docker
Test your ssh connection to the container:
DOCKER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' reahl)
ssh developer@$DOCKER_IP -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
Browsers and seeing stuff¶
The webserver ports of the Docker dev container are forwarded to your local machine. To surf to your app, start your app inside the container and point your usual browser to http://localhost:8000.
When tests are run inside the container, you may want to see the browser used for testing.
We use an Xpra display server for the Docker dev container. It allows headless operation and sharing of GUI windows for pair programming.
When you run a login shell inside the container an xpra display server is automatically started on :100.
If you are working alone, you can bypass the headless server by forwarding your local X display server by adding a -X to the ssh command:
DOCKER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' reahl)
ssh -X developer@$DOCKER_IP -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
Editing code¶
There’s no IDE installed inside the Docker dev container.
Edit the source code outside the container in your development directory - the changes will be visible inside the container.
For more advanced use, such as running and debugging code in an IDE, use an IDE that is able to connect to a docker container or a ssh host. Your IDE also needs to be able to work with Python code inside a specific virtualenv on the remote host.
To find the IP address of the running container do:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' reahl
To know which virtualenv to connect to, run:
docker container exec -u developer reahl bash -l -c 'echo $VIRTUAL_ENV'
The virtualenv is the last line output, something like: /home/developer/.venvs/python3.8
Pair programming¶
We often pair program remotely. Doing this requires a bit more know-how. Here’s how we do it:
Lets assume John and Jane want to work together, and decide to do so on Jane’s computer. In order to do this, Jane needs to expose her Docker dev container on the Internet and allow John to log into it. From there on, John can share various things with Jane via an ssh connection to Jane’s Docker dev container.
From a security point of view, Jane never puts her real workstation at risk of tampering by John.
Install reahl-workstation on your development machine¶
The reahl-workstation component of Reahl is meant to be installed separately on your own development workstation. It contains the reahl command line and a few commands that are useful for pair programming.
If you are on ubuntu install it like this:
sudo apt-get install python-pip
sudo pip install reahl-workstation
(The rest of this text assumes that you have reahl-workstation installed.)
Use ngrok to make a local Docker dev container accessible to remote co-workers¶
We use ngrok to make a local Docker dev container accessible on the Internet to all the tools we use.
Jane must have an account at ngrok, and share her Docker dev container.
In order to setup ngrok, download it–our scripts expect its executable to be in your PATH. Follow the instructions on the ngrok website to create an account and save your credentials locally.
To share a locally running Docker dev container (assuming ngrok is all set up), Jane can then run reahl ngrok start -D. This command will provide output in the form of a DNS name and port number that the remote party can use to access. Make a note of these for use later on.
Let the remote user connect securely¶
We do not allow login via password for security reasons 1. For John to be able to log in, his ssh public key needs to be installed into Jane’s Docker dev container. To do this, John should send his public key to Jane. John’s public key is in ~/.ssh/id_rsa.pub on his computer.
To enable John to log in, Jane edits the ~/.ssh/authorized_keys_docker file on her host and append the contents of John’s public key to whatever’s in that file already.
Now John will be allowed in. John also needs to make sure when connecting that he is connecting to the correct machine and not some impostor. When Jane logs into her Docker dev container, the various fingerprints belonging to the Docker dev container are printed out. Jane should send this to John.
John can now ssh as the user called developer to the host and port reported to Jane when she started ngrok. John will be presented with one of the fingerprints of the machine he is connecting to. This fingerprint should match one of the ones Jane sent earlier. If it matches, John can say ‘yes’ to ssh, which will now remember the fingerprint was OK, and not ask again.
Editing code together¶
There are a couple of IDEs and tools that allow collaborative editing. We know of these:
- 1
Once you expose a Docker dev container to the Internet, malicious parties will discover it and start trying user name and password combinations to try and log in. We configured the Docker dev container to disallow password access via ssh altogether to guard against such attacks. What password would we have used out-of-the-box anyway?