Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions TEKDB/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Python
__pycache__/
*.py[cod]
*.pyo
*.pyd

# Virtual environments
env/
venv/
.venv/

# Editor & OS files
.DS_Store
.vscode/
.idea/

# Git
.git
.gitignore

# Build/dist
build/
dist/
*.egg-info

# Static/local settings
media/
static/
local_settings.py
*.sqlite3
*.log

# Node
node_modules/

# Docker
Dockerfile
docker-compose*.yml
Comment on lines +36 to +38
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The .dockerignore file excludes Dockerfile and docker-compose*.yml files from the Docker build context. While docker-compose.yml doesn't need to be in the image, the Dockerfile exclusion is unusual and could cause issues if the build process references it. Consider removing the Dockerfile line from .dockerignore.

Copilot uses AI. Check for mistakes.
2 changes: 1 addition & 1 deletion TEKDB/.env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ SECRET_KEY=foo
ALLOWED_HOSTS=localhost,127.0.0.1,[::1]
SQL_ENGINE=django.contrib.gis.db.backends.postgis
SQL_DATABASE=tekdb
SQL_USER=tekdb_user
SQL_USER=postgres
SQL_PASSWORD=tekdb_password
SQL_HOST=db
SQL_PORT=5432
45 changes: 45 additions & 0 deletions TEKDB/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
FROM python:3.11-slim

# Prevent Python from writing .pyc files and enable unbuffered stdout/stderr
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PIP_NO_CACHE_DIR=1

# Install system dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-client \
gcc \
gdal-bin \
libgdal-dev \
libgeos-dev \
&& rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /usr/src/app

# Copy requirements first (cache pip install step when dependencies don't change)
COPY requirements.txt requirements_linux.txt /usr/src/app/

# Upgrade pip and install Python dependencies
RUN pip install --upgrade pip \
&& pip install -r requirements.txt -r requirements_linux.txt

# Copy the application code
COPY . /usr/src/app

# Copy and make entrypoint executable. The repository contains `docker/entrypoint.sh`
# which runs collectstatic, migrations and launches uWSGI.
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Expose the port the app runs on (entrypoint starts django development server or uWSGI on 8000)
EXPOSE 8000

# Default settings module (can be overridden at runtime)
ENV DJANGO_SETTINGS_MODULE=TEKDB.settings

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

# use development server by default
CMD ["dev"]
22 changes: 15 additions & 7 deletions TEKDB/TEKDB/local_settings.py.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,21 @@ ALLOWED_HOSTS = [
# SECRET_KEY='fixthisdjango'

# DATABASES = {
# 'default': {
# 'ENGINE': 'django.contrib.gis.db.backends.postgis',
# 'NAME': 'DB Name',
# 'USER': 'add user',
# 'PASSWORD': 'add password',
# 'HOST': 'add host',
# 'PORT': add number,
# "default": {
# "ENGINE": os.environ.get("SQL_ENGINE", "django.contrib.gis.db.backends.postgis"),
# "NAME": os.environ.get("SQL_DATABASE", "tekdb"),
# "USER": os.environ.get("SQL_USER", "postgres"),
# "PASSWORD": os.environ.get("SQL_PASSWORD", ""),
# "HOST": (
# os.environ.get("SQL_HOST")
# or os.environ.get("DB_HOST")
# or "localhost"
# ),
# "PORT": (
# os.environ.get("SQL_PORT")
# or os.environ.get("DB_PORT")
# or "5432"
# ),
# }
# }

Expand Down
5 changes: 5 additions & 0 deletions TEKDB/TEKDB/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
Expand Down Expand Up @@ -183,6 +184,10 @@

STATIC_ROOT = os.path.join(BASE_DIR, "static")

# Use WhiteNoise to serve static files when DEBUG is False (container / production)
STATICFILES_STORAGE = os.environ.get(
"STATICFILES_STORAGE", "whitenoise.storage.CompressedStaticFilesStorage"
)
###########################################
## FILEBROWSER ###
###########################################
Expand Down
35 changes: 0 additions & 35 deletions TEKDB/docker-compose.yml

This file was deleted.

8 changes: 0 additions & 8 deletions TEKDB/docker/entrypoint.sh

This file was deleted.

17 changes: 0 additions & 17 deletions TEKDB/docker/local_settings.py

This file was deleted.

43 changes: 43 additions & 0 deletions TEKDB/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/sh

# Exit on errors
set -e

# If a SQL_HOST is provided, wait for Postgres to become available before running
# migrations. This prevents race conditions when using docker-compose where the
# web container starts before the DB is ready.
if [ -n "$SQL_HOST" ]; then
echo "Waiting for database at ${SQL_HOST}:${SQL_PORT:-5432}..."
# pg_isready is available after installing postgresql-client in the image
until pg_isready -h "$SQL_HOST" -p "${SQL_PORT:-5432}" >/dev/null 2>&1; do
echo "Postgres is unavailable - sleeping"
sleep 1
done
echo "Postgres is up"
fi

echo "Collecting static files..."
python manage.py collectstatic --noinput
echo "Applying database migrations..."
python manage.py migrate --noinput
# Load default users only if no users exist
echo "Checking for existing users..."
if [ "$(python manage.py shell -c 'from django.contrib.auth import get_user_model; print(get_user_model().objects.count())')" = "0" ]; then
python manage.py loaddata TEKDB/fixtures/default_users_fixture.json
fi
# Load default lookups only if no lookups exist. Use LookupPlanningUnit as the check.
echo "Checking for existing lookups..."
if [ "$(python manage.py shell -c 'from TEKDB.models import LookupPlanningUnit; print(LookupPlanningUnit.objects.count())')" = "0" ]; then
python manage.py loaddata TEKDB/fixtures/default_lookups_fixture.json
fi

if [ "$1" = "prod" ]; then
echo "Starting uWSGI (HTTP) on :8000"
uwsgi --http :8000 --master --enable-threads --module TEKDB.wsgi
elif [ "$1" = "dev" ]; then
echo "Starting python development server on :8000"
python manage.py runserver 0.0.0.0:8000
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rhodges added some logic to the entrypoint to support dev or prod servers. The Dockerfile uses test by default, but added a docker-compose.prod.yaml to pass the prod arg

else
# Default to the passed command if not 'prod' or 'dev'
exec "$@"
fi
1 change: 1 addition & 0 deletions TEKDB/explore/templatetags/disk_space_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def bytes_to_readable(num_bytes, suffix="B"):
return f"{num_bytes:.2f} {unit}{suffix}"
num_bytes /= 1024


@register.simple_tag(name="disk_space_report")
def disk_space_report():
"""Returns a dictionary with disk space and memory usage information."""
Expand Down
5 changes: 4 additions & 1 deletion TEKDB/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,8 @@ urllib3>=1.26.5
#OPTIONAL, BUT LOVELY FOR DEBUGGING
ipdb
ipython

# Serve static files in production containers
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The whitenoise dependency should be pinned to a specific version or version range for reproducible builds, similar to other dependencies in the file (e.g., django >=4.2.16,<4.3). Consider specifying a version like whitenoise>=6.0.0,<7.0.0.

Copilot uses AI. Check for mistakes.
whitenoise>=6.0.0,<7.0.0
# FORMATTING AND LINTING
ruff
ruff
9 changes: 9 additions & 0 deletions docker/.env.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DEBUG=1
SECRET_KEY=foo
ALLOWED_HOSTS=localhost,127.0.0.1,[::1]
SQL_ENGINE=django.contrib.gis.db.backends.postgis
SQL_DATABASE=tekdb
SQL_USER=postgres
SQL_PASSWORD=tekdb_password
SQL_HOST=db
SQL_PORT=5432
46 changes: 46 additions & 0 deletions docker/docker-compose.prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
services:
db:
image: postgis/postgis:15-3.4
restart: always
platform: linux/amd64
environment:
POSTGRES_DB: ${SQL_DATABASE}
POSTGRES_USER: ${SQL_USER}
POSTGRES_PASSWORD: ${SQL_PASSWORD}
volumes:
- tekdb_db_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SQL_USER} -d ${SQL_DATABASE} -h localhost -p ${SQL_PORT}"]
interval: 10s
timeout: 5s
retries: 5

web:
build:
context: ../TEKDB/
dockerfile: ../TEKDB/Dockerfile
command: ["prod"]
restart: unless-stopped
depends_on:
- db
env_file:
- .env.dev
environment:
ALLOWED_HOSTS: ${ALLOWED_HOSTS}
DEBUG: ${DEBUG}
SQL_ENGINE: ${SQL_ENGINE}
SQL_HOST: ${SQL_HOST}
SQL_PORT: ${SQL_PORT}
SQL_DATABASE: ${SQL_DATABASE}
SQL_USER: ${SQL_USER}
SQL_PASSWORD: ${SQL_PASSWORD}
SECRET_KEY: ${SECRET_KEY}
ports:
- "8000:8000"
volumes:
- ../TEKDB:/usr/src/app

volumes:
tekdb_db_data:
45 changes: 45 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
services:
db:
image: postgis/postgis:15-3.4
restart: always
platform: linux/amd64
environment:
POSTGRES_DB: ${SQL_DATABASE}
POSTGRES_USER: ${SQL_USER}
POSTGRES_PASSWORD: ${SQL_PASSWORD}
volumes:
- tekdb_db_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SQL_USER} -d ${SQL_DATABASE} -h localhost -p ${SQL_PORT}"]
interval: 10s
timeout: 5s
retries: 5

web:
build:
context: ../TEKDB/
dockerfile: ../TEKDB/Dockerfile
restart: unless-stopped
depends_on:
- db
env_file:
- .env.dev
environment:
ALLOWED_HOSTS: ${ALLOWED_HOSTS}
DEBUG: ${DEBUG}
SQL_ENGINE: ${SQL_ENGINE}
SQL_HOST: ${SQL_HOST}
SQL_PORT: ${SQL_PORT}
SQL_DATABASE: ${SQL_DATABASE}
SQL_USER: ${SQL_USER}
SQL_PASSWORD: ${SQL_PASSWORD}
SECRET_KEY: ${SECRET_KEY}
ports:
- "8000:8000"
volumes:
- ../TEKDB:/usr/src/app

volumes:
tekdb_db_data:
Loading