From 155a473222f39903fb1f105af790fb66a8dbef89 Mon Sep 17 00:00:00 2001 From: bergi Date: Tue, 21 Dec 2021 15:47:20 +0100 Subject: [PATCH] issue #3: - use python-decouple for environment settings - add .env.example file to get started - remove default db user and password mentionings - update README documentation --- .dockerignore | 4 --- .gitignore | 16 ++++++---- Dockerfile | 41 ------------------------- README.md | 64 +++++++++++++--------------------------- requirements.txt | 1 + web/.env.example | 25 ++++++++++++++++ web/park_api/settings.py | 36 ++++++++++------------ web/start-server.sh | 8 +---- 8 files changed, 74 insertions(+), 121 deletions(-) delete mode 100644 .dockerignore delete mode 100644 Dockerfile create mode 100644 web/.env.example diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 0688614..0000000 --- a/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -# exclude localhost related files -web/park_api/settings_local.py -web/static/ -*.sqlite3 diff --git a/.gitignore b/.gitignore index 3b62833..66c044f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,14 @@ -.idea/ -*.iml -__pycache__/ -*.pyc env/ venv/ +.env* + cache/ -web/static/ -settings_local.py +/web/static/ +/web/media/ *credentials* + +.idea/ +*.iml + +__pycache__/ +*.pyc diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index a6ae332..0000000 --- a/Dockerfile +++ /dev/null @@ -1,41 +0,0 @@ -FROM ubuntu:bionic -# MAINTAINER Makina Corpus "contact@makina-corpus.com" -# from https://github.com/makinacorpus/docker-geodjango/blob/master/Dockerfile - -ENV PYTHONUNBUFFERED 1 -ENV DEBIAN_FRONTEND noninteractive -ENV LANG C.UTF-8 - -RUN apt-get update -qq && apt-get install -y -qq \ - # std libs - git less nano curl \ - ca-certificates \ - wget build-essential\ - # python basic libs - python3.8 python3.8-dev python3.8-venv gettext \ - # geodjango - gdal-bin binutils libproj-dev libgdal-dev \ - # postgresql - libpq-dev postgresql-client - ##&& \ - ##apt-get clean all && rm -rf /var/apt/lists/* && rm -rf /var/cache/apt/* - -# link default python -RUN ln -s /usr/bin/python3.8 /usr/bin/python - -# install pip -RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && rm get-pip.py -RUN pip3 install --no-cache-dir setuptools wheel -U - -# --- install python packages --- - -COPY ./requirements.txt /app/requirements.txt -WORKDIR /app/ - -RUN pip3 install --upgrade pip -RUN pip3 install -r requirements.txt - -# --- copy code and run --- - -COPY ./web /app -ENTRYPOINT ["/app/start-server.sh"] diff --git a/README.md b/README.md index 6bc55d8..ea2b310 100644 --- a/README.md +++ b/README.md @@ -134,29 +134,37 @@ Alternatively, you can run the docker run --name some-postgis -e POSTGRES_PASSWORD= -d postgis/postgis ``` -#### Create and setup database +#### Setup and create database -```shell script +First copy the [web/.env.example](web/.env.example) file to `web/.env` and edit. +Specifically `POSTGRES_USER` and `POSTGRES_PASSWORD` must be defined. + +The create the database execute these commands and replace `` and `` +with your values: + +```sh # start psql sudo -u postgres psql -CREATE USER "park_api" WITH PASSWORD '...'; -CREATE DATABASE "parkapi2" ENCODING=UTF8 OWNER="park_api"; +CREATE USER "" WITH PASSWORD ""; +CREATE DATABASE "parkapi2" ENCODING=UTF8 OWNER=""; +CREATE DATABASE "parkapi2-test" ENCODING=UTF8 OWNER=""; + +# connect to each database and enable postgis +\c parkapi2 +CREATE EXTENSION postgis; -# allow park_api user to create the unittest database and -# enable the postgis extension -ALTER USER "park_api" SUPERUSER; +\c parkapi2-test +CREATE EXTENSION postgis; ``` -> Note that `ALTER USER "park_api" CREATEDB;` is usually enough for -> running the unittests but the `postgis` extension -> [can only be enabled by a superuser](https://dba.stackexchange.com/questions/175319/postgresql-enabling-extensions-without-super-user/175469#175469). +### Run local server and unittests -Then in the `web/` directory call: +In the `web/` directory call: ```shell script # run unittests -./manage.py test +./manage.py test --keepdb # init the main database ./manage.py migrate @@ -170,7 +178,7 @@ By default, the django admin interface is available at [localhost:8000/admin/](http://localhost:8000/admin/) and the swagger api documentation is at [localhost:8000/api/docs/](http://localhost:8000/api/docs/) and -a simple overview page at [localhost:8000/](http://localhost:8000/). +a simple *developmental* overview page at [localhost:8000/](http://localhost:8000/). To get data into the database call: @@ -182,33 +190,3 @@ To get data into the database call: ./manage.py pa_find_locations ``` - -## Docker and CI - -The [Dockerfile](Dockerfile) is an Ubuntu based image. It's probably possible -to switch to Alpine but the postgis libraries are currently not working in -my attempts. - -```shell script -docker build --tag parkapi-dev . -``` - -#### run unittests in docker container - -```shell script -docker run -ti --env PARKAPI_RUN_TESTS=1 --net host parkapi-dev -``` - -Running the container with `--net host` will attach to the postgres at localhost. Please -check the example in the -[postgis docker README](https://github.com/postgis/docker-postgis#readme) -how to connect to a different host. - -#### running the server in docker container - -```shell script -docker run -ti --env DJANGO_DEBUG=True --net host parkapi-dev -``` - -Running in non-DEBUG mode will not deliver static files as this -requires a webserver like nginx or apache. diff --git a/requirements.txt b/requirements.txt index 7a57215..1898808 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ djangorestframework==3.12.4 drf-yasg==1.20.0 Markdown==3.3.6 psycopg2-binary==2.9.2 +python-decouple==3.5 diff --git a/web/.env.example b/web/.env.example new file mode 100644 index 0000000..f69e6eb --- /dev/null +++ b/web/.env.example @@ -0,0 +1,25 @@ +# -- django settings -- + +# This must never be True in production! +https://docs.djangoproject.com/en/4.0/ref/settings/#debug +DJANGO_DEBUG=False + +# https://docs.djangoproject.com/en/4.0/ref/settings/#secret-key +DJANGO_SECRET_KEY= + +# for production this must contain your.host.name +# https://docs.djangoproject.com/en/4.0/ref/settings/#allowed-hosts +DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 + +# -- database settings -- + +POSTGRES_DATABASE=parkapi2 +POSTGRES_TEST_DATABASE=parkapi2-test + +# define database user and password +POSTGRES_USER= +POSTGRES_PASSWORD= + +# define these if the postgres does not run on localhost:5432 +# POSTGRES_HOST= +# POSTGRES_PORT= diff --git a/web/park_api/settings.py b/web/park_api/settings.py index 625c39f..1577c9a 100644 --- a/web/park_api/settings.py +++ b/web/park_api/settings.py @@ -9,10 +9,10 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/3.2/ref/settings/ """ -import os from pathlib import Path -DATETIME_FORMAT = "Y-m-d H:i:s T" +from decouple import config + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -24,30 +24,23 @@ # --- CI variables -- -POSTGRES_DATABASE = os.environ.get('POSTGRES_DATABASE', 'parkapi2') -POSTGRES_TEST_DATABASE = os.environ.get('POSTGRES_DATABASE', 'parkapi2_test') -POSTGRES_HOST = os.environ.get('POSTGRES_HOST', 'localhost') -POSTGRES_PORT = os.environ.get('POSTGRES_PORT', '5432') -POSTGRES_USER = os.environ.get('POSTGRES_USER', 'park_api') -POSTGRES_PASSWORD = os.environ.get('POSTGRES_PASSWORD', 'park_api') +POSTGRES_DATABASE = config('POSTGRES_DATABASE') +POSTGRES_TEST_DATABASE = config('POSTGRES_TEST_DATABASE') +POSTGRES_HOST = config('POSTGRES_HOST', default='localhost') +POSTGRES_PORT = config('POSTGRES_PORT', default=5432, cast=int) +POSTGRES_USER = config('POSTGRES_USER') +POSTGRES_PASSWORD = config('POSTGRES_PASSWORD') -SECRET_KEY = os.environ.get( - 'DJANGO_SECRET_KEY', - 'SECURITY WARNING: keep the secret key used in production secret!' -) +SECRET_KEY = config("DJANGO_SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True if os.environ.get("DJANGO_DEBUG") == "True" else False +DEBUG = config("DJANGO_DEBUG", default=False, cast=bool) -if os.environ.get('DJANGO_ALLOWED_HOSTS'): - ALLOWED_HOSTS = os.environ['DJANGO_ALLOWED_HOSTS'].split() -else: - ALLOWED_HOSTS = ['*'] +ALLOWED_HOSTS = config('DJANGO_ALLOWED_HOSTS').split() -if os.environ.get("DJANGO_CSRF_TRUSTED_ORIGINS"): - CSRF_TRUSTED_ORIGINS = os.environ["DJANGO_CSRF_TRUSTED_ORIGINS"].split() +STATIC_ROOT = config("DJANGO_STATIC_PATH", default=BASE_DIR / "static", cast=Path) -STATIC_ROOT = os.environ.get("DJANGO_STATIC_PATH", BASE_DIR / "static") +# --- end CI variables --- STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage' @@ -173,6 +166,9 @@ USE_TZ = False +# make django admin show times flagged with UTC +DATETIME_FORMAT = "Y-m-d H:i:s T" + # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.2/howto/static-files/ diff --git a/web/start-server.sh b/web/start-server.sh index c6b566f..02a4d94 100755 --- a/web/start-server.sh +++ b/web/start-server.sh @@ -5,10 +5,4 @@ #./manage.py compilemessages || exit 1 ./manage.py collectstatic --no-input || exit 1 -# check for existence of special env variable to run unittest -if [[ -z "${PARKAPI_RUN_TESTS}" ]]; then - # or run server - gunicorn -b 127.0.0.1:8000 park_api.wsgi || exit 1 -else - ./manage.py test || exit 1 -fi +gunicorn -b 127.0.0.1:8000 park_api.wsgi || exit 1