Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Docker Compose setup for development. #128

Merged
merged 14 commits into from
Jul 1, 2021
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.venv
.vscode
__pycache__/
*.py[cod]
*$py.class
venv
.eggs
.pytest_cache
*.egg-info
.DS_Store
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM python:3.9

WORKDIR /app

# Set up the minimum structure needed to install
# django_sql_dashboard's dependencies and the package itself
# in development mode.
COPY setup.py README.md .
RUN mkdir django_sql_dashboard && pip install -e '.[test]'

# We need to have postgres installed in this container
# because the automated test suite actually spins up
# (and shuts down) a database inside the container.
RUN apt-get update && apt-get install -y \
postgresql postgresql-contrib \
&& rm -rf /var/lib/apt/lists/*

# Install dependencies needed for editing documentation.
COPY docs/requirements.txt .
RUN pip install -r requirements.txt

# Set up a non-root user. Aside from being best practice,
# we also need to do this because the test suite refuses to
# run as the root user.
RUN groupadd -g 1000 appuser && useradd -r -u 1000 -g appuser appuser
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this assumes that the UID of the current user is 1000, which it usually is on individual OS X and Linux machines (it's the UID of the first non-root account). However, if it's different, the user could run into some really annoying permission issues.

There are some funky workarounds to set this to the UID of the user who is currently active, I think. I can try looking into it.


USER appuser
34 changes: 34 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: "2"
services:
app:
build: .
links:
- db
volumes:
- .:/app
environment:
- DATABASE_URL=postgres://appuser:test123@db/test_project
- DJANGO_SETTINGS_MODULE=config.settings_interactive
- PYTHONUNBUFFERED=yup
working_dir: /app
entrypoint: ["./test_project/wait-for-postgres.sh"]
toolness marked this conversation as resolved.
Show resolved Hide resolved
ports:
- "${APP_PORT:-8000}:${APP_PORT:-8000}"
command: python test_project/manage.py runserver 0.0.0.0:${APP_PORT:-8000}
docs:
build: .
volumes:
- .:/app
working_dir: /app/docs
ports:
- "${DOCS_PORT:-8001}:${DOCS_PORT:-8001}"
command: make SPHINXOPTS="--host 0.0.0.0 --port ${DOCS_PORT:-8001}" livehtml
db:
# Note that this database is only used when we use
# test_project interactively; automated tests spin up
# their own database inside the app container.
image: postgres:13-alpine
environment:
- POSTGRES_PASSWORD=test123
- POSTGRES_USER=appuser
- POSTGRES_DB=test_project
90 changes: 90 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,93 @@ To build the documentation locally, run the following:
make livehtml

This will start a live preview server, using [sphinx-autobuild](https://pypi.org/project/sphinx-autobuild/).

## Using Docker Compose

If you're familiar with Docker--or even if you're not--you may awnt to consider using our optional Docker Compose setup.

An advantage of this approach is that it relieves you of setting up any dependencies, such as ensuring that you have the proper version of Python and Postgres and so forth. On the downside, however, it does require you to familiarize yourself with Docker, which, while relatively easy to use, still has its own learning curve.

To try out the Docker Compose setup, you will first want to [get Docker][] and [install Docker Compose][].

Then, after checking out the code, run the following:

```
cd django-sql-dashboard
docker-compose build
```

At this point, you can start editing code. To run any development tools such as `pytest` or `black`, just prefix everything with `docker-compose run app`. For instance, to run the test suite, run:

```
docker-compose run app python pytest
```

If this is a hassle, you can instead run a bash shell inside your container:

```
docker-compose run app bash
```

At this point, you'll be in a bash shell inside your container, and can run development tools directly.

[get Docker]: https://docs.docker.com/get-docker/
[install Docker Compose]: https://docs.docker.com/compose/install/

### Using the dashboard interactively

The Docker Compose setup is configured to run a simple test project that you can use to tinker with the dashboard interactively.

To set this up, first run:

```
docker-compose run app python test_project/manage.py migrate
docker-compose run app python test_project/manage.py createsuperuser
```

You will now be prompted to enter details about a new superuser. Once you've done that, run:

```
docker-compose up
```

You can now visit the example app's dashboard at http://localhost:8000/dashboard/.
toolness marked this conversation as resolved.
Show resolved Hide resolved

### Editing the documentation

Running `docker-compose up` also starts the documentation system's live preview server. You can visit it at http://localhost:8001/.

### Changing the default ports

If you are already using ports 8000 and/or 8001 for other things, you can change them. To do this, create a file in the repository root called `.env` and populate it with the following:

```
APP_PORT=9000
DOCS_PORT=9001
```

You can change the above port values to whatever makes sense for your setup.

Once you next run `docker-compose up` again, the services will be running on the ports you specified in `.env`.

### Updating

The project's Python dependencies are all baked into the container image, which means that whenever they change (or to be safe, whenever you `git pull` new changes to the codebase), you will want to run:

```
docker-compose build
```

You may also want to apply any new migrations that were added to the codebase:

```
docker-compose run app python test_project/manage.py migrate
```

### Cleaning up

If you somehow get your Docker Compose setup into a broken state, or you decide that you never use Docker Compose again, you can clean everything up by running:

```
docker-compose down -v
```
14 changes: 14 additions & 0 deletions test_project/config/settings_interactive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Normally test_project is used as scaffolding for
# django_sql_dashboard's automated tests. However, it can
# be useful during development to have a sample project to
# tinker with interactively. These Django settings can be
# useful when we want to do that.

from .settings import *

# Just have our dashboard use the exact same credentials for
# our database, there's no need to bother with read-only
# permissions when using test_project interactively.
DATABASES["dashboard"] = DATABASES["default"]

LOGIN_URL="/admin/login/"
toolness marked this conversation as resolved.
Show resolved Hide resolved
11 changes: 11 additions & 0 deletions test_project/wait-for-postgres.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh
# wait-for-postgres.sh

set -e

until psql $DATABASE_URL -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done

exec "$@"