Docker infra for local development #224
Conversation
There was a problem hiding this comment.
Pull request overview
Adds Docker-based infrastructure intended to run the OH4S portal locally (alongside the existing Vagrant workflow), plus a few supporting app changes to improve startup behavior.
Changes:
- Add Dockerfile, docker-compose stack, and DB init script for local development.
- Add an entrypoint script to run migrations/static collection/seed data on container start.
- Adjust Django form initialization to avoid DB queries at import-time; tweak Python deps (remove
psycopg2in favor ofpsycopg2-binaryonly).
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds Docker local-dev instructions (currently missing a required local_settings.py step). |
| docker/init-db.sh | Imports a SQL dump during first DB initialization. |
| docker/docker-compose.yaml | Defines db (PostGIS) + web services for local dev. |
| docker/.env.template | Template for docker-compose environment variables. |
| app/portal/requirements.txt | Removes duplicate psycopg2 dependency (keeps psycopg2-binary). |
| app/portal/providers/forms.py | Moves dynamic choice generation into __init__ (avoids import-time queries). |
| app/portal/portal/entrypoint.sh | Container startup script (migrate/collectstatic/seed/superuser/runserver). |
| app/portal/Dockerfile | Builds the Django app image (currently pinned to an incompatible Python version). |
| .gitignore | Ignores .env.dev and db_dump.sql. |
Comments suppressed due to low confidence (1)
app/portal/portal/entrypoint.sh:29
python manage.py createsuperuseris interactive by default and will hang/fail in Docker, and it’s not actually checking “if not exists”. Use a non-interactive/idempotent approach (e.g.,--noinputwith env-provided credentials, or a small Django management command that creates the user only if missing).
echo "creating superuser if not exists..."
python manage.py createsuperuser
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,36 @@ | |||
| FROM python:3.12-slim | |||
There was a problem hiding this comment.
I'd rather use this base image and try to bump django versions than use a docker image for an older python version.
| echo "loading initial data fixtures..." | ||
| python manage.py loaddata fixtures/providers_20210524.json | ||
|
|
||
| echo "creating superuser if not exists..." | ||
| python manage.py createsuperuser | ||
|
|
There was a problem hiding this comment.
We should also get/use a more up-to-date list of providers - this looks to be 5 years old.
| ## Choose your development environment: Vagrant or Docker | ||
|
|
||
| ## Docker | ||
|
|
||
| - In order to run the application with production data, locate a database dump of a production install. Add the dump to the `docker` directory and name it `db_dump.sql`. This is necessary for the `init-db.sh` script to run correctly. | ||
|
|
||
| - Create an copy the `.env.template` file to a `.env` file in the `docker` directory. Add your environment variables to that file. | ||
|
|
||
| - Move to the docker directory: `cd docker` | ||
|
|
||
| - Start the docker containers: `docker compose up` | ||
|
|
||
| - View the app at `http://localhost:8000` |
There was a problem hiding this comment.
I removed needs for local_settings.py
There was a problem hiding this comment.
Next step: remove the need for Vagrant 😁
| ALLOWED_HOSTS = [] | ||
| ALLOWED_HOSTS_ENV = os.environ.get("ALLOWED_HOSTS") | ||
| if ALLOWED_HOSTS_ENV: | ||
| ALLOWED_HOSTS.extend(ALLOWED_HOSTS_ENV.split(",")) |
| 'USER': 'set_in_local_settings.py' | ||
| 'NAME': os.environ.get('SQL_DATABASE', default='postgres'), | ||
| 'USER': os.environ.get('SQL_USER', default='postgres'), | ||
| 'PASSWORD': os.environ.get('SQL_PASSWORD', default=None), |
There was a problem hiding this comment.
PASSWORD, HOST, and PORT were omitted in the past to support the database using postgres as the owner and default user, which also bypassed the need for a password (providing these fields actually broke that workflow).
Explicitly creating a new PostgreSQL user with a password and making them the owner of the tables is MUCH more secure, and I like that you are re-investing some of the gains from the streamlining gains of dockerizing this tool into making deployments follow best practices!
| MAPBOX_TOKEN = os.environ.get('MAPBOX_TOKEN', default='') | ||
|
|
||
| from .local_settings import * | ||
| try: |
|
|
||
| MIN_SEARCH_RANK=0.1 | ||
| MIN_SEARCH_SIMILARITY=0.25 | ||
| MAPBOX_TOKEN = os.environ.get('MAPBOX_TOKEN', default='') |
There was a problem hiding this comment.
What are we using MapBox for? GeoLocation?
| pickleshare==0.7.5 | ||
| prompt-toolkit>=3.0.30 | ||
| psycopg2==2.9.10 | ||
| psycopg2-binary==2.9.10 |
There was a problem hiding this comment.
I thought the pendulum had swung and psycopg2 was now being preferred over psycopg2-binary -- maybe this shift was between Django 3.2 and Django 4.2?
| ## Choose your development environment: Vagrant or Docker | ||
|
|
||
| ## Docker | ||
|
|
||
| - In order to run the application with production data, locate a database dump of a production install. Add the dump to the `docker` directory and name it `db_dump.sql`. This is necessary for the `init-db.sh` script to run correctly. | ||
|
|
||
| - Create an copy the `.env.template` file to a `.env` file in the `docker` directory. Add your environment variables to that file. | ||
|
|
||
| - Move to the docker directory: `cd docker` | ||
|
|
||
| - Start the docker containers: `docker compose up` | ||
|
|
||
| - View the app at `http://localhost:8000` |
There was a problem hiding this comment.
Next step: remove the need for Vagrant 😁
pollardld
left a comment
There was a problem hiding this comment.
I added a couple comments. Neither comment is breaking or blocking this PR.
| SQL_PASSWORD= | ||
| SQL_HOST= | ||
| SQL_PORT=db | ||
| MAPBOX_TOKEN=5432 No newline at end of file |
There was a problem hiding this comment.
Looks like a couple values got swapped in the env template:
MAPBOX_TOKEN and SQL_PORT
| @@ -113,8 +116,11 @@ | |||
| DATABASES = { | |||
| 'default': { | |||
| 'ENGINE': 'django.db.backends.postgresql', | |||
There was a problem hiding this comment.
I see a SQL_ENGINE variable in .env.template
have you considered pulling that in like you do for setting the values for Name, User, etc.?
Adds dockerfile and docker-compose for running locally. Also includes necessary changes to start the web server successfully. Includes documentation to run locally with docker. Also includes removing local_settings.py in favor of environment variables.
I am not sure if this is because of the database dump, but I am not seeing some images locally.