Skip to content

Commit

Permalink
docs(dev): provide instructions to setup Polar with DevContainers
Browse files Browse the repository at this point in the history
  • Loading branch information
uwla committed Jan 10, 2024
1 parent 223b978 commit b8b1154
Showing 1 changed file with 146 additions and 0 deletions.
146 changes: 146 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ There is some software that is required to compile and run Polar locally. You'll
- Mac and Windows: you can just install [Docker Desktop](https://www.docker.com/products/docker-desktop)
- Linux: you need to install [Docker Server](https://docs.docker.com/install/#server) and [Docker Compose](https://docs.docker.com/compose/install/) separately

You can install the software directly on your machine or use automated devcontainers with docker, as explained in [Docker Approach](#docker-approach) section of this document.

Once you have all of the required software installed, you can proceed to setup your local environment

### One-time Environment Setup
Expand Down Expand Up @@ -65,6 +67,150 @@ $ git pull
$ yarn
```

### Docker approach

The development environment for Polar can be setup with docker. First, we
describe manual setup. There are two docker devcontainer images:

- headless: allows installing packages, linting code, running tests, and
compiling Polar.
- ui: allows running graphical interface besides the same functionalities as the
headless.

To build the headless image, run:

```
docker image build --tag polardev:headless --file Dockerfile-headless ./.devcontainer/
```

The UI image works only on Linux with x11 as the display backend. To build it,
first build the headless image, then run:

```bash
docker_gid_host=$(getent group docker | awk --field-separator : '{print $3}')
docker image build --build-arg="DOCKER_GID=${docker_gid_host}" --tag polardev:ui ./.devcontainer/
```

The `docker_gid_host` gets the GID of the docker group in the host machine,
which is added to the non-root user in the container in build time. This is
required if we want to use the Polar UI during development, which needs to
connect to Docker (more on that later). This GID is not fixed but varies accross
OS: 996 on ArchLinux, 969 on Debian, 999 on Ubuntu.

If you want to use the UI, run the following command to enable forwarding
graphical applications from the container to the host:

```
xhost +local:docker
```

To start a headless container, run:

```bash
cd polar/
docker container run \
--volume "$PWD":/app \
--name polar \
--detach \
--rm \
polardev:headless \
sleep infinity
```

To start a UI container, run:

```bash
cd polar/
docker container run \
--volume "$PWD":/app \
--volume /tmp/.X11-unix:/tmp/.X11-unix \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "${HOME}/.config/polar":/home/dev/.config/polar \
--volume "${HOME}/.polar":/home/dev/.polar \
--env "DISPLAY=${DISPLAY}" \
--name polar \
--detach \
--rm \
polardev:ui \
sleep infinity
```

The above command runs a container in detached mode, putting it to sleep forever.
The sleep command does not consume CPU or RAM, so the container is kept alive and
we can execute commands in it.

Let's see an explanation of the volumes:

- `--volume "$PWD":/app` mounts the Polar application on the container.
- `--volume /tmp/.X11-unix:/tmp/.X11-unix` allows X11 graphical applications to
be forward from the container to the host.
- `--volume /var/run/docker.sock:/var/run/docker.sock` allows Docker-In-Docker,
which is required for the Polar UI to work (it needs to access Docker).
- `--volume "${HOME}/.config/polar":/home/dev/.config/polar` enables persistent
configuration storage for the GUI app during development.
- `--volume "${HOME}/.polar":/home/dev/.polar` enables persists data storage for
the GUI app during development.

Now that the container is running, we can run some commands:

Install the packages:

```bash
docker container exec polar yarn package
```

Notice that the first argument after `exec` is the container name (`polar` in our case).

Run linter:

```bash
docker container exec polar yarn lint
```

Run tests:

```bash
docker container exec polar yarn test
```

Build the app for the current platform (the container platform is Linux):

```bash
docker container exec polar yarn package
```

Start a graphical UI for development (for `polardev:ui`), which reflects
changes in real-time:

```bash
docker container exec polar yarn dev
```

The last example requires locally changing the `dev:electron` script in
`package.json` and add the `--no-sanbox` to the electron command:

```
"dev:electron": "wait-on http://localhost:3000 && nodemon -I --watch ./electron/ --watch ./src/shared/ --ext ts --exec electron --no-sandbox ./public/dev.js",
```

This is because it is not possible to run the sandbox if the container is
unprivileged. It is better to run a non-sandbox electron app in a unprivileged
docker container than to run a sandboxed electron app in a privileged docker
container (which would be granted sysadmin rights).

### Using Vscode devcontainers

Install Vscode devcontainers extension and run
`Dev Containers: Open Folder in Container...` from the command palette. This
will open the folder in the container and allow running headless commands.

If you also want to run the UI using devcontainers, then go back to the manual
approach, start the container as instructed in order to map the proper volumes
and allow X11 forwarding of graphical applications. Then, run
`Dev Containers: Attach to Running Container...` from the command palette and
select the already running container. This will open Vscode on the existing
container with UI support. You can then run `yarn dev` to launch the UI.

## Contributing to Polar

So you'd like to contribute some help to make Polar better, here's how...
Expand Down

0 comments on commit b8b1154

Please sign in to comment.