Initial refactor

This commit is contained in:
Sonny Bakker 2023-03-05 15:21:04 +01:00
parent 12b4aa0b91
commit 89f23fe668
11 changed files with 230 additions and 65 deletions

View file

@ -3,7 +3,6 @@ stages:
- test - test
- lint - lint
- release - release
- deploy
variables: variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
@ -17,9 +16,8 @@ variables:
cache: cache:
key: "$CI_COMMIT_REF_SLUG" key: "$CI_COMMIT_REF_SLUG"
paths: paths:
- .venv/ - env/
- .cache/pip - .cache/pip
- .cache/poetry
- node_modules/ - node_modules/
include: include:
@ -27,4 +25,3 @@ include:
- local: '/gitlab-ci/test.yml' - local: '/gitlab-ci/test.yml'
- local: '/gitlab-ci/lint.yml' - local: '/gitlab-ci/lint.yml'
- local: '/gitlab-ci/release.yml' - local: '/gitlab-ci/release.yml'
- local: '/gitlab-ci/deploy.yml'

5
bin/docker-entrypoint.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/bash
python /app/src/manage.py migrate
exec "$@"

View file

@ -0,0 +1,18 @@
upstream gunicorn {
server django:8000;
}
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/access_log;
error_log /var/log/nginx/error_log;
location / {
proxy_pass http://gunicorn;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}

View file

@ -0,0 +1,36 @@
version: '3.6'
volumes:
static-files:
node-modules:
services:
celery:
environment:
- DJANGO_SETTINGS_MODULE=newsreader.conf.docker
volumes:
- ./src/:/app/src
django:
build:
context: .
dockerfile: ./docker/django
target: development
command: python /app/src/manage.py runserver 0.0.0.0:8000
environment:
- DJANGO_SETTINGS_MODULE=newsreader.conf.docker
volumes:
- ./src:/app/src
- static-files:/app/src/newsreader/static
stdin_open: true
tty: true
webpack:
build:
context: .
dockerfile: ./docker/webpack
command: npm run build:watch
volumes:
- ./src/:/app/src
- static-files:/app/src/newsreader/static
- node-modules:/app/node_modules

View file

@ -0,0 +1,14 @@
version: '3.6'
volumes:
logs:
services:
nginx:
image: nginx:1.23
depends_on:
django:
condition: service_healthy
volumes:
- ./config/nginx/conf.d:/etc/nginx/conf.d
- logs:/var/log/nginx

View file

@ -1,62 +1,84 @@
version: "3" version: '3.6'
volumes: volumes:
logs:
media:
postgres-data: postgres-data:
static-files:
node-modules:
services: services:
db: db:
image: postgres image: postgres:15
healthcheck:
test: /usr/bin/pg_isready
interval: 5s
timeout: 10s
retries: 10
environment: environment:
POSTGRES_DB: "newsreader" POSTGRES_DB: 'newsreader'
POSTGRES_USER: "newsreader" POSTGRES_USER: 'newsreader'
POSTGRES_PASSWORD: "newsreader" POSTGRES_PASSWORD: 'newsreader'
volumes: volumes:
- postgres-data:/var/lib/postgresql/data - postgres-data:/var/lib/postgresql/data
rabbitmq: rabbitmq:
image: rabbitmq:3.7 image: rabbitmq:3.7
memcached: memcached:
image: memcached:1.6 image: memcached:1.6
ports: ports:
- "11211:11211" - '11211:11211'
entrypoint: entrypoint:
- memcached - memcached
- -m 64 - -m 64
celery: celery:
build: build:
context: . context: .
dockerfile: ./docker/django dockerfile: ./docker/django
command: celery worker -n worker1@%h -n worker2@%h --app newsreader --loglevel INFO --concurrency 2 --workdir /app/src/ --beat --scheduler django command: |
celery worker -n worker1@%h
-n worker2@%h
--app newsreader
--loglevel INFO
--concurrency 2
--workdir /app/src/
--beat
--scheduler django
environment: environment:
- DJANGO_SETTINGS_MODULE=newsreader.conf.docker - DJANGO_SETTINGS_MODULE=newsreader.conf.production
depends_on: depends_on:
- rabbitmq rabbitmq:
- memcached condition: service_started
memcached:
condition: service_started
db:
condition: service_healthy
django:
condition: service_healthy
volumes: volumes:
- ./src/:/app/src - logs:/app/logs
django: django:
build: build:
context: . context: .
dockerfile: ./docker/django dockerfile: ./docker/django
command: python /app/src/manage.py runserver 0.0.0.0:8000 target: production
entrypoint: /app/bin/docker-entrypoint.sh
command: gunicorn --bind 0.0.0.0:8000 --workers 3 newsreader.wsgi:application
healthcheck:
test: /usr/bin/curl --fail http://django:8000 || exit 1
interval: 5s
timeout: 10s
retries: 10
environment: environment:
- DJANGO_SETTINGS_MODULE=newsreader.conf.docker - DJANGO_SETTINGS_MODULE=newsreader.conf.production
ports: ports:
- "8000:8000" - '8000:8000'
depends_on: depends_on:
- db memcached:
- memcached condition: service_started
db:
condition: service_healthy
volumes: volumes:
- ./src:/app/src - logs:/app/logs
- static-files:/app/src/newsreader/static - media:/app/media
stdin_open: true
tty: true
webpack:
build:
context: .
dockerfile: ./docker/webpack
command: npm run build:watch
volumes:
- ./src/:/app/src
- static-files:/app/src/newsreader/static
- node-modules:/app/node_modules

View file

@ -1,10 +1,105 @@
FROM python:3.9-bullseye # stage 1
FROM python:3.9-bullseye as backend
RUN apt-get update && apt-get install -y --no-install-recommends \
vim \
curl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app WORKDIR /app
RUN mkdir /app/src RUN mkdir /app/src
RUN mkdir /app/logs
RUN mkdir /app/media
COPY ./requirements /app/requirements COPY ./requirements /app/requirements
RUN pip install -r requirements/production.txt -r requirements/development.txt RUN pip install -r requirements/production.txt
# stage 2
FROM node:current-bullseye AS frontend-build
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY ./build /app/build/
COPY ./*.json ./*.js ./.babelrc /app/
RUN npm ci
COPY ./src /app/src COPY ./src /app/src
RUN npm run build
# stage 3
FROM python:3.9-bullseye as production
RUN apt-get update && apt-get install -y --no-install-recommends \
postgresql-client \
vim \
curl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN mkdir /app/logs
RUN mkdir /app/media
RUN mkdir /app/bin
COPY --from=backend /usr/local/lib/python3.9 /usr/local/lib/python3.9
COPY --from=backend /usr/local/bin/gunicorn /usr/local/bin/gunicorn
COPY --from=backend /usr/local/bin/celery /usr/local/bin/celery
COPY --from=backend /app/src/ /app/src/
COPY ./bin/docker-entrypoint.sh /app/bin/docker-entrypoint.sh
COPY --from=frontend-build /app/src/newsreader/static /app/src/newsreader/static
COPY ./src /app/src
RUN useradd -M -u 1000 newsreader
RUN chown -R newsreader:newsreader /app
USER newsreader
ARG COMMIT_HASH
ARG RELEASE=latest
ENV RELEASE=${RELEASE} \
GIT_SHA=${COMMIT_HASH} \
PYTHONUNBUFFERED=1 \
DJANGO_SETTINGS_MODULE=newsreader.conf.production
ARG SECRET_KEY=dummy
RUN python src/manage.py collectstatic --noinput \
&& python src/manage.py compilemessages
# (optional) stage 4
FROM python:3.9-bullseye as development
RUN apt-get update && apt-get install -y --no-install-recommends \
vim \
curl \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN mkdir /app/bin
COPY ./requirements /app/requirements
COPY ./bin/docker-entrypoint.sh /app/bin/docker-entrypoint.sh
COPY --from=backend /usr/local/lib/python3.9 /usr/local/lib/python3.9
COPY --from=backend /usr/local/bin/celery /usr/local/bin/celery
COPY --from=backend /app/src/ /app/src/
RUN pip install -r requirements/production.txt -r requirements/development.txt
RUN useradd -M -u 1000 newsreader
RUN chown -R newsreader:newsreader /app
USER newsreader

View file

@ -1,22 +0,0 @@
deploy:
stage: deploy
image: python:3.7
environment:
name: production
url: rss.fudiggity.nl
rules:
- if: $CI_COMMIT_TAG
before_script:
- pip install ansible --quiet
- git clone https://git.fudiggity.nl/ansible/newsreader.git deployment --branch master
- cd deployment
- ansible-galaxy install -r requirements.yml
- mkdir /root/.ssh && echo "$DEPLOY_HOST_KEY" > /root/.ssh/known_hosts
- echo "$DEPLOY_KEY" > deploy_key && chmod 0600 deploy_key
- echo "$VAULT_PASSWORD" > vault
script:
- >
ansible-playbook playbook.yml
--private-key deploy_key
--vault-password-file vault
--extra-vars "app_branch=$CI_COMMIT_TAG"

View file

@ -2,7 +2,7 @@ python-tests:
stage: test stage: test
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/' coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
services: services:
- postgres:11 - postgres:15
- memcached:1.5.22 - memcached:1.5.22
image: python:3.9-bullseye image: python:3.9-bullseye
before_script: before_script:

View file

@ -21,7 +21,7 @@ DJANGO_PROJECT_DIR = os.path.join(BASE_DIR, "src", "newsreader")
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: don"t run with debug turned on in production! # SECURITY WARNING: don"t run with debug turned on in production!
DEBUG = True DEBUG = False
ALLOWED_HOSTS = ["127.0.0.1", "localhost"] ALLOWED_HOSTS = ["127.0.0.1", "localhost"]
INTERNAL_IPS = ["127.0.0.1", "localhost"] INTERNAL_IPS = ["127.0.0.1", "localhost"]
@ -208,9 +208,6 @@ STATICFILES_FINDERS = [
# Email # Email
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
# Project settings
ENVIRONMENT = "development"
# Reddit integration # Reddit integration
REDDIT_CLIENT_ID = "CLIENT_ID" REDDIT_CLIENT_ID = "CLIENT_ID"
REDDIT_CLIENT_SECRET = "CLIENT_SECRET" REDDIT_CLIENT_SECRET = "CLIENT_SECRET"
@ -261,7 +258,6 @@ ACCOUNT_ACTIVATION_DAYS = 7
SENTRY_CONFIG = { SENTRY_CONFIG = {
"dsn": os.environ.get("SENTRY_DSN"), "dsn": os.environ.get("SENTRY_DSN"),
"send_default_pii": False, "send_default_pii": False,
"environment": ENVIRONMENT,
"integrations": [DjangoIntegration(), CeleryIntegration()] "integrations": [DjangoIntegration(), CeleryIntegration()]
if DjangoIntegration and CeleryIntegration if DjangoIntegration and CeleryIntegration
else [], else [],

View file

@ -2,6 +2,8 @@ from .base import * # isort:skip
from .version import get_current_version from .version import get_current_version
ALLOWED_HOSTS = ["django", "127.0.0.1"]
SECRET_KEY = "=q(ztyo)b6noom#a164g&s9vcj1aawa^g#ing_ir99=_zl4g&$" SECRET_KEY = "=q(ztyo)b6noom#a164g&s9vcj1aawa^g#ing_ir99=_zl4g&$"
INSTALLED_APPS += ["debug_toolbar", "django_extensions"] INSTALLED_APPS += ["debug_toolbar", "django_extensions"]
@ -31,6 +33,8 @@ CACHES = {
}, },
} }
DEBUG = True
# Project settings # Project settings
VERSION = get_current_version() VERSION = get_current_version()
ENVIRONMENT = "docker" ENVIRONMENT = "docker"