aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar MarkKoz <[email protected]>2021-02-03 12:12:20 -0800
committerGravatar MarkKoz <[email protected]>2021-02-04 16:19:45 -0800
commitd274d25c2da31fd6cf5b8a86f81d9d79c4545e8c (patch)
tree95fee110c8c7071c875e7db9bda22a068d9830e6
parentCategorise and sort scripts in Pipfile (diff)
Replace dev.sh with Docker Compose
Managing development containers through Docker Compose is convenient. However, it isn't quite flexible enough to facilitate both development and normal use. It's not really worth accommodating the latter since the container gets pushed to a registry and that's the intended way to run the service. Anyone that is checking out the repository and therefore has access to the compose file is likely a developer, not a user.
-rw-r--r--DEVELOPING.md46
-rw-r--r--Pipfile18
-rw-r--r--docker-compose.yml15
-rwxr-xr-xscripts/dev.sh65
4 files changed, 38 insertions, 106 deletions
diff --git a/DEVELOPING.md b/DEVELOPING.md
index 934369c..4e47b84 100644
--- a/DEVELOPING.md
+++ b/DEVELOPING.md
@@ -22,33 +22,27 @@ pipenv run lint
## Running snekbox
-The Docker image can be built with:
-
-```
-pipenv run build
-```
-
-Use Docker Compose to start snekbox:
+Use Docker Compose to start snekbox in development mode. The optional `--build` argument can be passed to force the image to be rebuilt.
```
docker-compose up
```
-## Running Tests
+The container has all development dependencies. The repository on the host is mounted within the container; changes made to local files will also affect the container.
+
+Note that the compose file depends on the environment variable `PWD` being set to the current working directory. It needs it to create the aforementioned bind mount. Unix shells normally have this set already. If for some reason it is not set, it needs to be manually set. A convenient way to set it is to define it in a `.env` file which Docker Compose will automatically read.
-Tests are run through coverage.py using unittest. Before tests can run, the dev venv Docker image has to be built:
+To build a normal container that can be used in production, run
```
-pipenv run builddev
+pipenv run build
```
-Alternatively, the following command will build the image and then run the tests:
+Refer to the [README] for how to run the container normally.
-```
-pipenv run testb
-```
+## Running Tests
-If the image doesn't need to be built, the tests can be run with:
+Tests are run through coverage.py using unittest. To run the tests within a development container, run
```
pipenv run test
@@ -62,7 +56,7 @@ To see a coverage report, run
pipenv run report
```
-Alternatively, a report can be generated as HTML:
+Alternatively, a report can be generated as HTML with
```
pipenv run coverage html
@@ -70,20 +64,21 @@ pipenv run coverage html
The HTML will output to `./htmlcov/` by default
+## Launching a Shell in the Container
-## The `devsh` Helper Script
-
-This script starts a `bash` shell inside the venv Docker container and attaches to it. Unlike the production image, the venv image that is built by this script contains dev dependencies too. The project directory is mounted inside the container so any filesystem changes made inside the container affect the actual local project.
-
-### Usage
+A bash shell can be launched in the development container using
```
-pipenv run devsh [--build [--clean]] [bash_args ...]
+pipenv run devsh
```
-* `--build` Build the venv Docker image
-* `--clean` Clean up dangling Docker images (only works if `--build` precedes it)
-* `bash_args` Arguments to pass to `/bin/bash` (for example `-c "echo hello"`). An interactive shell is launched if no arguments are given
+This creates a new container which will get deleted once the shell session ends.
+
+It's possible to run a command directly; it supports the same arguments that `bash` supports.
+
+```bash
+pipenv run devsh -c 'echo hello'
+```
### Invoking NsJail
@@ -96,3 +91,4 @@ python -m snekbox 'print("hello world!")' --time_limit 0
With this command, NsJail uses the same configuration normally used through the web API. It also has an alias, `pipenv run eval`.
[pipenv]: https://docs.pipenv.org/en/latest/
+[readme]: README.md
diff --git a/Pipfile b/Pipfile
index bc504e2..41bb811 100644
--- a/Pipfile
+++ b/Pipfile
@@ -39,24 +39,14 @@ precommit = "pre-commit install"
# Testing
report = "coverage report"
-test = "sh scripts/dev.sh -c 'pipenv run coverage run -m unittest'"
-testb = """
- sh scripts/dev.sh \
- --build \
- --clean \
- -c 'pipenv run coverage run -m unittest'
+test = """
+ docker-compose run --entrypoint /bin/bash --rm snekbox -c \
+ 'coverage run -m unittest'
"""
# Docker
build = "docker build -t ghcr.io/python-discord/snekbox:latest ."
-builddev = """
- docker build \
- -t ghcr.io/python-discord/snekbox-venv:dev \
- --target venv \
- --build-arg DEV=1 \
- .
-"""
-devsh = "sh scripts/dev.sh"
+devsh = "docker-compose run --entrypoint /bin/bash --rm snekbox"
# Other
protoc = "sh scripts/protoc.sh"
diff --git a/docker-compose.yml b/docker-compose.yml
index a7747a6..d073dd1 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,17 +2,28 @@ version: "3.7"
services:
snekbox:
- container_name: snekbox
+ container_name: snekbox_dev
+ hostname: snekbox_dev
privileged: true
- image: ghcr.io/python-discord/snekbox:latest
+ image: ghcr.io/python-discord/snekbox:dev
ports:
- 8060:8060
init: true
ipc: none
+ working_dir: $PWD
+ environment:
+ DEBUG: 1
+ PIPENV_PIPFILE: /snekbox/Pipfile
+ PYTHONDONTWRITEBYTECODE: 1
build:
context: .
dockerfile: Dockerfile
+ args:
+ DEV: 1
+ cache_from:
+ - ghcr.io/python-discord/snekbox:latest
volumes:
+ - $PWD:$PWD
- user-base:/snekbox/user_base
volumes:
diff --git a/scripts/dev.sh b/scripts/dev.sh
deleted file mode 100755
index efbd93a..0000000
--- a/scripts/dev.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env sh
-
-# Sets up a development environment and runs a shell in a docker container.
-# Usage: dev.sh [--build [--clean]] [bash_args ...]
-
-if [ "$1" = "--build" ]; then
- shift
- printf "Building ghcr.io/python-discord/snekbox-venv:dev..."
-
- docker build \
- -t ghcr.io/python-discord/snekbox-venv:dev \
- -f Dockerfile \
- --build-arg DEV=1 \
- --target venv \
- -q \
- . \
- >/dev/null \
- && printf " done!\n" || exit "$?"
-
- if [ "$1" = "--clean" ]; then
- shift
- dangling_imgs=$(docker images -f "dangling=true" -q)
-
- if [ -n "${dangling_imgs}" ]; then
- printf "Removing dangling images..."
-
- # shellcheck disable=SC2086
- docker rmi $dangling_imgs >/dev/null \
- && printf " done!\n" || exit "$?"
- fi
- fi
-fi
-
-# Keep the container up in the background so it doesn't have to be restarted
-# for the ownership fix.
-# The volume is mounted to same the path in the container as the source
-# directory on the host to ensure coverage can find the source files.
-docker run \
- --tty \
- --detach \
- --name snekbox_test \
- --privileged \
- --hostname pdsnk-dev \
- --ipc="none" \
- -e PYTHONDONTWRITEBYTECODE=1 \
- -e PIPENV_PIPFILE="/snekbox/Pipfile" \
- --volume "${PWD}":"${PWD}" \
- --workdir "${PWD}"\
- --entrypoint /bin/bash \
- ghcr.io/python-discord/snekbox-venv:dev \
- >/dev/null \
-
-# Execute the given command(s)
-docker exec -it snekbox_test /bin/bash "$@"
-
-# Fix ownership of coverage file
-# BusyBox doesn't support --reference for chown
-docker exec \
- -it \
- -e CWD="${PWD}" \
- snekbox_test \
- /bin/bash \
- -c 'chown "$(stat -c "%u:%g" "${CWD}")" "${CWD}/.coverage"'
-
-docker rm -f snekbox_test >/dev/null # Stop and remove the container