From 9576202fa1cc2dc24087c9733986777517e04901 Mon Sep 17 00:00:00 2001 From: jmsgrogan Date: Sun, 18 Feb 2024 14:09:12 +0000 Subject: [PATCH] Start adding deployment infra. --- .gitignore | 2 ++ README.md | 33 ++++++++++++++++++++++++--- compose.prod.yaml | 25 ++++++++++++++++++++ compose.yaml | 12 ++++++++++ infra/install_arch_deps.sh | 1 + nginx/Dockerfile | 4 ++++ nginx/nginx.conf | 20 ++++++++++++++++ requirements.txt | 5 +--- wedding_site/Dockerfile | 16 +++++++++++++ wedding_site/requirements.txt | 5 ++++ wedding_site/wedding_site/settings.py | 10 ++++---- 11 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 compose.prod.yaml create mode 100644 compose.yaml create mode 100644 infra/install_arch_deps.sh create mode 100644 nginx/Dockerfile create mode 100644 nginx/nginx.conf create mode 100644 wedding_site/Dockerfile create mode 100644 wedding_site/requirements.txt diff --git a/.gitignore b/.gitignore index e1dba2e..041559f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ /build */uploads +*/staticfiles __pycache__ *.pyc .venv +.env* *.sqlite3 diff --git a/README.md b/README.md index d7112f5..8ead6d7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Web backend for hosting a wedding website. -## Run development server: +# Run Local server: ```sh source .venv/bin/activate @@ -10,10 +10,37 @@ cd wedding_site python manage.py runserver ``` -## Do Migrations +# Do Migrations ```sh cd wedding_site python manage.py makemigrations primary python manage.py migrate -``` \ No newline at end of file +``` + +# Run Dev Server in container + +```sh +podman-compose -f compose.yaml up -d --build +``` + +Bring it down with: + +```sh +podman-compose down -v +``` + +# Run Prod Server + +```sh +podman-compose -f compose.prod.yaml up -d --build +``` + +Sync static files: + +```sh +podman-compose -f compose.prod.yaml exec web python manage.py collectstatic --no-input --clear +``` + + + diff --git a/compose.prod.yaml b/compose.prod.yaml new file mode 100644 index 0000000..f406dfd --- /dev/null +++ b/compose.prod.yaml @@ -0,0 +1,25 @@ +version: '3.8' + +services: + web: + build: ./wedding_site + command: gunicorn wedding_site.wsgi:application --bind 0.0.0.0:8000 + volumes: + - ./wedding_site/:/usr/src/app/ + - static_volume:/staticfiles + expose: + - 8000 + env_file: + - ./.env.prod + + nginx: + build: ./nginx + ports: + - 8080:80 + volumes: + - static_volume:/staticfiles + depends_on: + - web + +volumes: + static_volume: \ No newline at end of file diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..ddaa801 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,12 @@ +version: '3.8' + +services: + web: + build: ./wedding_site + command: python manage.py runserver 0.0.0.0:8000 + volumes: + - ./wedding_site/:/usr/src/app/ + ports: + - 8000:8000 + env_file: + - ./.env.dev \ No newline at end of file diff --git a/infra/install_arch_deps.sh b/infra/install_arch_deps.sh new file mode 100644 index 0000000..8937870 --- /dev/null +++ b/infra/install_arch_deps.sh @@ -0,0 +1 @@ +pacman -Sy podman aardvark-dns \ No newline at end of file diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000..bdde282 --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,4 @@ +FROM docker.io/nginx + +RUN rm /etc/nginx/conf.d/default.conf +COPY nginx.conf /etc/nginx/conf.d \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..10a320d --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,20 @@ +upstream wedding_site { + server web:8000; +} + +server { + + listen 80; + + location / { + proxy_pass http://wedding_site; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + } + + location /static/ { + alias /staticfiles/; + } + +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 2e2e3ab..e7584bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1 @@ -django -markdown -pillow -beautifulsoup4 +podman-compose \ No newline at end of file diff --git a/wedding_site/Dockerfile b/wedding_site/Dockerfile new file mode 100644 index 0000000..7817462 --- /dev/null +++ b/wedding_site/Dockerfile @@ -0,0 +1,16 @@ +# pull official base image +FROM python:3.11.4-slim-buster + +# set environment variables +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 + +# install dependencies +RUN pip install --upgrade pip +COPY ./requirements.txt . +RUN pip install -r requirements.txt + +RUN mkdir staticfiles + +# copy project +COPY . . \ No newline at end of file diff --git a/wedding_site/requirements.txt b/wedding_site/requirements.txt new file mode 100644 index 0000000..2666a26 --- /dev/null +++ b/wedding_site/requirements.txt @@ -0,0 +1,5 @@ +django +markdown +pillow +beautifulsoup4 +gunicorn \ No newline at end of file diff --git a/wedding_site/wedding_site/settings.py b/wedding_site/wedding_site/settings.py index d97a4d7..aaf44cc 100644 --- a/wedding_site/wedding_site/settings.py +++ b/wedding_site/wedding_site/settings.py @@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/5.0/ref/settings/ """ from pathlib import Path +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -19,13 +20,11 @@ BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-bj9fez3qztt5e2lrzpgh%%nat@w^kn!k@l92l=+#%wm)4)p^5m' +SECRET_KEY = os.environ.get("SECRET_KEY") -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = bool(os.environ.get("DEBUG", default=0)) -ALLOWED_HOSTS = ["localhost"] +ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ") # Application definition @@ -117,6 +116,7 @@ USE_TZ = True # https://docs.djangoproject.com/en/5.0/howto/static-files/ STATIC_URL = 'static/' +STATIC_ROOT = BASE_DIR / "staticfiles" # Default primary key field type # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field