Skip to content

Docker infra for local development #224

Open
paigewilliams wants to merge 6 commits into
mainfrom
docker
Open

Docker infra for local development #224
paigewilliams wants to merge 6 commits into
mainfrom
docker

Conversation

@paigewilliams
Copy link
Copy Markdown

@paigewilliams paigewilliams commented May 20, 2026

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.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 psycopg2 in favor of psycopg2-binary only).

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 createsuperuser is 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., --noinput with 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.

Comment thread app/portal/Dockerfile
@@ -0,0 +1,36 @@
FROM python:3.12-slim
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I'd rather use this base image and try to bump django versions than use a docker image for an older python version.

Comment thread app/portal/portal/entrypoint.sh
Comment thread app/portal/portal/entrypoint.sh Outdated
Comment on lines +24 to +29
echo "loading initial data fixtures..."
python manage.py loaddata fixtures/providers_20210524.json

echo "creating superuser if not exists..."
python manage.py createsuperuser

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I should do this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should also get/use a more up-to-date list of providers - this looks to be 5 years old.

Comment thread docker/docker-compose.yaml Outdated
Comment thread docker/docker-compose.yaml Outdated
Comment thread README.md
Comment on lines +11 to +23
## 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`
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I removed needs for local_settings.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Next step: remove the need for Vagrant 😁

Comment thread README.md Outdated
Comment thread docker/.env.template Outdated
Comment thread docker/init-db.sh Outdated
Copy link
Copy Markdown
Member

@rhodges rhodges left a comment

Choose a reason for hiding this comment

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

Looks great!

ALLOWED_HOSTS = []
ALLOWED_HOSTS_ENV = os.environ.get("ALLOWED_HOSTS")
if ALLOWED_HOSTS_ENV:
ALLOWED_HOSTS.extend(ALLOWED_HOSTS_ENV.split(","))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1

'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),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1


MIN_SEARCH_RANK=0.1
MIN_SEARCH_SIMILARITY=0.25
MAPBOX_TOKEN = os.environ.get('MAPBOX_TOKEN', default='')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What are we using MapBox for? GeoLocation?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I looked and found a commit where you, @rhodges, added MAPBOX_TOKEN to the local settings template in 2019. As well as its use for geocoding in models.py

pickleshare==0.7.5
prompt-toolkit>=3.0.30
psycopg2==2.9.10
psycopg2-binary==2.9.10
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I could be 100% wrong, too.

Comment thread README.md
Comment on lines +11 to +23
## 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`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Next step: remove the need for Vagrant 😁

Copy link
Copy Markdown
Member

@pollardld pollardld left a comment

Choose a reason for hiding this comment

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

I added a couple comments. Neither comment is breaking or blocking this PR.

Comment thread docker/.env.template
SQL_PASSWORD=
SQL_HOST=
SQL_PORT=db
MAPBOX_TOKEN=5432 No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants