Skip to content
Merged
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
16 changes: 16 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.git
.github
.idea
.claude
.venv
.pytest_cache
**/__pycache__
**/*.pyc
.DS_Store
local.env
frontends
staticfiles
Dockerfile
.dockerignore
spatialite.Dockerfile
*.dump
45 changes: 2 additions & 43 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,11 @@ on:
branches: [ main ]

jobs:
build:
test:

runs-on: ubuntu-latest

services:
db_service:
image: postgis/postgis
env:
POSTGRES_USER: postgres
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

steps:
- uses: actions/checkout@v2
- name: Install system dependencies (geospatial libraries)
run: |
sudo apt-get update
sudo apt-get install binutils libproj-dev gdal-bin
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: .python-version
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
- name: Install Python Dependencies
run: |
uv sync --locked --all-groups
- name: Migrate database
run: |
uv run python manage.py migrate
env:
SECRET_KEY: secret
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
- name: Run Tests
env:
SECRET_KEY: secret
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
run: |
uv run pytest
run: make test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
local.env
.DS_Store
dumpstermap-frontend-*
db.sqlite3
40 changes: 40 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Multi-stage build.

# Stages:
# - deps: Prepares the runtime environment
# - app: Adds application code

# Stage `deps`
FROM ghcr.io/astral-sh/uv:0.9.26-python3.12-trixie-slim AS deps

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
# GeoDjango dependencies:
gdal-bin libsqlite3-mod-spatialite \
# sqlite CLI enables consistent database backups (even with concurrent writers):
sqlite3 \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

ENV PYTHONDONTWRITEBYTECODE=1
ENV UV_COMPILE_BYTECODE=1
# Keep the virtualenv outside /app, so the code can be bind-mounted over /app (e.g. for tests)
ENV UV_PROJECT_ENVIRONMENT=/opt/venv
COPY pyproject.toml uv.lock ./
RUN uv sync --locked --no-dev
ENV PATH="/opt/venv/bin:$PATH"

# Stage `app`
FROM deps

COPY . .

ENV DATABASE_URL=spatialite:////data/db.sqlite3

RUN SECRET_KEY=collectstatic python manage.py collectstatic --no-input

VOLUME /data
EXPOSE 8000

CMD ["./start.sh"]
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.PHONY: build build-deps test runserver

IMAGE ?= dumpstermap-backend
PORT ?= 8000

build:
docker build -t $(IMAGE) .

build-deps:
docker build --target deps -t $(IMAGE)-deps .

test: build-deps
docker run --rm -v "$(CURDIR)":/app $(IMAGE)-deps pytest -p no:cacheprovider $(ARGS)

DEV_ENV = -e DEBUG=True -e SECRET_KEY=insecure-dev-key
DOCKER_CMD = docker run --rm $(DEV_ENV) -v "$(CURDIR)":/app

migrate: build-deps
$(DOCKER_CMD) $(IMAGE)-deps python manage.py migrate

runserver: build-deps migrate
$(DOCKER_CMD) -p $(PORT):8000 $(IMAGE)-deps python manage.py runserver 0.0.0.0:8000
1 change: 0 additions & 1 deletion Procfile

This file was deleted.

25 changes: 9 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
## Built with
### Backend
* Python, Django, Django REST framework (with [geospatial add-ons](https://github.com/openwisp/django-rest-framework-gis))
* PostgreSQL, PostGIS, Docker
* Deployed to Heroku
* SQLite, SpatiaLite
* Deployed to [Fly.io](https://fly.io)

### Frontend
* TypeScript, Angular, Leaflet
Expand All @@ -20,18 +20,12 @@
The development setup requires:
* [uv](https://docs.astral.sh/uv/) (installs the required Python version automatically)
* [Geospatial libraries required by GeoDjango](https://docs.djangoproject.com/en/4.1/ref/contrib/gis/install/geolibs/)
* Docker to run a Postgres database with [GIS extension](https://postgis.net/).
* [SpatiaLite](https://docs.djangoproject.com/en/5.2/ref/contrib/gis/install/spatialite/)

To install the required python version and all python dependencies (including dev tools), run:

uv sync --all-groups

### Database

In order to start a basic docker container capable of serving a PostGIS-enabled database (with `postgres` as default
user and database), run:

docker run -p 5432:5432 --name some-postgis -e POSTGRES_PASSWORD=mysecretpassword -d imresamu/postgis

### Configuration

Expand All @@ -40,19 +34,18 @@ optional variables.

### Migrate database

Run `uv run manage.py migrate` to create all database tables.
Run `make migrate` to create all database tables.

### Development server

Run `uv run manage.py runserver` for a dev server.
Run `make test` for a dev server.

### Running tests
Run `uv run pytest` to execute the unit tests.

Run `make pytest` to execute the unit tests.

## Deployment

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
fly deploy

## License
tbd
## License
tbd
54 changes: 0 additions & 54 deletions app.json

This file was deleted.

5 changes: 3 additions & 2 deletions dumpstermap/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@
ALLOWED_HOSTS = [
"dumpstermap.org",
"dumpstermap.vercel.app",
"dumpstermap.herokuapp.com",
"dumpstermap-backend.fly.dev",
env.str("HOST_NAME", ""),
]
CSRF_TRUSTED_ORIGINS = [f"https://{host}" for host in ALLOWED_HOSTS if host]

# Application definition

Expand Down Expand Up @@ -71,7 +72,7 @@
"django.middleware.common.CommonMiddleware",
]

DATABASES = {"default": env.db(engine="django.contrib.gis.db.backends.postgis")}
DATABASES = {"default": env.db(default=f"spatialite:///{BASE_DIR / 'db.sqlite3'}")}
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

ROOT_URLCONF = "dumpstermap.urls"
Expand Down
17 changes: 17 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
app = "dumpstermap-backend"
primary_region = "fra"
swap_size_mb = 512

[http_service]
internal_port = 8000
force_https = true
auto_stop_machines = "off"
auto_start_machines = true

[[mounts]]
source = "dumpstermap_data"
destination = "/data"

[[vm]]
size = "shared-cpu-1x"
memory = "256mb"
7 changes: 3 additions & 4 deletions local.env.sample
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# ℹ️ Required variables
# ---------------------
# DATABASE_URL schema:
# postgresql://user:password@localhost:5432/db_name
SECRET_KEY=<REQUIRED>
DATABASE_URL=<REQUIRED>

# ℹ️ Optional variables
# ---------------------
DEBUG=<REQUIRED>
# For supported URL schemas, refer to https://django-environ.readthedocs.io/en/latest/types.html#environ-env-db-url
# DATABASE_URL=spatialite:///db.sqlite3
# DEBUG=False
4 changes: 1 addition & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ dependencies = [
"django-cors-headers",
"djangorestframework",
"djangorestframework-gis",
"psycopg2-binary",
"requests",
"gunicorn",
"dj-database-url",
"django-environ",
"pytest",
"factory-boy",
Expand All @@ -26,12 +24,12 @@ dependencies = [
"bucketstore",
"geojson",
"freezegun",
"pytest-env>=1.8.0",
]

[dependency-groups]
dev = [
"pre-commit",
"pytest-dotenv",
]

[tool.uv]
Expand Down
4 changes: 2 additions & 2 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[pytest]
DJANGO_SETTINGS_MODULE = dumpstermap.settings
python_files = tests.py test_*.py *_test.py
env_files =
local.env
env =
SECRET_KEY=test
5 changes: 5 additions & 0 deletions start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh
set -e

python manage.py migrate --no-input
exec gunicorn dumpstermap.wsgi --bind 0.0.0.0:8000
Loading
Loading