Skip to content

Added django-redis as default cache #1371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
May 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7b5ebe7
added django-redis
Rajgupta36 Apr 13, 2025
85d540c
added redis for staging and production
Rajgupta36 Apr 14, 2025
5dcbe56
update code
Rajgupta36 Apr 14, 2025
10658fa
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 14, 2025
3b8b247
update test-case
Rajgupta36 Apr 14, 2025
17e9bef
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 14, 2025
385910a
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 16, 2025
b8c287b
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 16, 2025
78209e9
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 18, 2025
3bc55d6
update code
Rajgupta36 Apr 21, 2025
6793f43
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 21, 2025
4bfab11
update poetry.lock
Rajgupta36 Apr 21, 2025
85b2e78
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 21, 2025
38e66b8
Update code
arkid15r Apr 22, 2025
a890913
configure Redis with requirepass for secured access
Rajgupta36 Apr 22, 2025
ae0b510
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 22, 2025
95f4868
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 22, 2025
ebefc2c
Update code
arkid15r Apr 23, 2025
f720002
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 23, 2025
f89ef94
update poetry.lock
Rajgupta36 Apr 23, 2025
9ab9f10
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 24, 2025
8061bdb
added env for password security
Rajgupta36 Apr 29, 2025
e17b798
Merge branch 'main' into feat/redis-implementation
Rajgupta36 Apr 29, 2025
94c2b5e
update prod
Rajgupta36 Apr 29, 2025
60287ec
Merge branch 'main' into pr/Rajgupta36/1371
arkid15r May 1, 2025
a96a907
Update code
arkid15r May 1, 2025
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
6 changes: 6 additions & 0 deletions .github/ansible/production/nest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
dest: ~/
mode: '0400'

- name: Copy .env.cache
copy:
src: '{{ github_workspace }}/.env.cache'
dest: ~/
mode: '0400'

- name: Copy .env.db
copy:
src: '{{ github_workspace }}/.env.db'
Expand Down
6 changes: 6 additions & 0 deletions .github/ansible/staging/nest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@
dest: ~/
mode: '0400'

- name: Copy .env.cache
copy:
src: '{{ github_workspace }}/.env.cache'
dest: ~/
mode: '0400'

- name: Copy .env.db
copy:
src: '{{ github_workspace }}/.env.db'
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/run-ci-cd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ jobs:
echo "DJANGO_DB_PORT=${{ secrets.DJANGO_DB_PORT }}" >> .env.backend
echo "DJANGO_DB_USER=${{ secrets.DJANGO_DB_USER }}" >> .env.backend
echo "DJANGO_OPEN_AI_SECRET_KEY=${{ secrets.DJANGO_OPEN_AI_SECRET_KEY }}" >> .env.backend
echo "DJANGO_REDIS_HOST=${{ secrets.DJANGO_REDIS_HOST }}" >> .env.backend
echo "DJANGO_REDIS_PASSWORD=${{ secrets.DJANGO_REDIS_PASSWORD }}" >> .env.backend
echo "DJANGO_RELEASE_VERSION=$(date '+%y.%-m.%-d')-${GITHUB_SHA:0:7}" >> .env.backend
echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env.backend
echo "DJANGO_SENTRY_DSN=${{ secrets.DJANGO_SENTRY_DSN }}" >> .env.backend
Expand All @@ -345,6 +347,10 @@ jobs:
echo "DJANGO_SLACK_SIGNING_SECRET=${{ secrets.DJANGO_SLACK_SIGNING_SECRET }}" >> .env.backend
echo "GITHUB_TOKEN=${{ secrets.DJANGO_GITHUB_TOKEN }}" >> .env.backend

# Cache
touch .env.cache
echo "REDIS_PASSWORD=${{ secrets.DJANGO_REDIS_PASSWORD }}" >> .env.cache

# Database
touch .env.db
echo "POSTGRES_DB=${{ secrets.DJANGO_DB_NAME }}" >> .env.db
Expand Down Expand Up @@ -511,6 +517,8 @@ jobs:
echo "DJANGO_DB_PORT=${{ secrets.DJANGO_DB_PORT }}" >> .env.backend
echo "DJANGO_DB_USER=${{ secrets.DJANGO_DB_USER }}" >> .env.backend
echo "DJANGO_OPEN_AI_SECRET_KEY=${{ secrets.DJANGO_OPEN_AI_SECRET_KEY }}" >> .env.backend
echo "DJANGO_REDIS_HOST=${{ secrets.DJANGO_REDIS_HOST }}" >> .env.backend
echo "DJANGO_REDIS_PASSWORD=${{ secrets.DJANGO_REDIS_PASSWORD }}" >> .env.backend
echo "DJANGO_RELEASE_VERSION=${{ github.event.release.tag_name }}" >> .env.backend
echo "DJANGO_SECRET_KEY=${{ secrets.DJANGO_SECRET_KEY }}" >> .env.backend
echo "DJANGO_SENTRY_DSN=${{ secrets.DJANGO_SENTRY_DSN }}" >> .env.backend
Expand All @@ -519,6 +527,10 @@ jobs:
echo "DJANGO_SLACK_SIGNING_SECRET=${{ secrets.DJANGO_SLACK_SIGNING_SECRET }}" >> .env.backend
echo "GITHUB_TOKEN=${{ secrets.DJANGO_GITHUB_TOKEN }}" >> .env.backend

# Cache
touch .env.cache
echo "REDIS_PASSWORD=${{ secrets.DJANGO_REDIS_PASSWORD }}" >> .env.cache

# Database
touch .env.db
echo "POSTGRES_DB=${{ secrets.DJANGO_DB_NAME }}" >> .env.db
Expand Down
2 changes: 2 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ DJANGO_DB_PORT=None
DJANGO_DB_USER=None
DJANGO_OPEN_AI_SECRET_KEY=None
DJANGO_PUBLIC_IP_ADDRESS="127.0.0.1"
DJANGO_REDIS_HOST=None
DJANGO_REDIS_PASSWORD=None
DJANGO_RELEASE_VERSION=None
DJANGO_SECRET_KEY=None
DJANGO_SENTRY_DSN=None
Expand Down
2 changes: 1 addition & 1 deletion backend/docker/Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ FROM python:3.13.3-alpine
SHELL ["/bin/sh", "-o", "pipefail", "-c"]

RUN apk update && \
apk add postgresql-client && \
apk add postgresql-client redis && \
addgroup -S owasp && \
adduser -S -h /home/owasp -G owasp owasp && \
python -m pip install --no-cache-dir poetry
Expand Down
39 changes: 37 additions & 2 deletions backend/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ django = "^5.1"
django-configurations = "^2.5.1"
django-cors-headers = "^4.7.0"
django-filter = "^25.1"
django-redis = "^5.4.0"
django-storages = { extras = ["s3"], version = "^1.14.4" }
djangorestframework = "^3.15.2"
geopy = "^2.4.1"
Expand Down
10 changes: 9 additions & 1 deletion backend/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,19 @@ class Base(Configuration):
"INDEX_PREFIX": ENVIRONMENT.lower(),
}

REDIS_HOST = values.SecretValue(environ_name="REDIS_HOST")
REDIS_PASSWORD = values.SecretValue(environ_name="REDIS_PASSWORD")
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": f"redis://:{REDIS_PASSWORD}@{REDIS_HOST}:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
"TIMEOUT": 300,
}
}

# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases
DATABASES = {
Expand Down
56 changes: 39 additions & 17 deletions backend/tests/apps/core/api/algolia_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import pytest
import requests
from django.core.cache import cache

from apps.core.api.algolia import algolia_search

Expand All @@ -18,15 +17,15 @@
CLIENT_IP_ADDRESS = "127.0.0.1"


@pytest.fixture
def _clear_cache():
"""Clear the cache before and after each test."""
cache.clear()
yield
cache.clear()
@pytest.fixture(autouse=True)
def mock_redis_cache():
"""Mock Redis cache used in algolia.py."""
with patch("apps.core.api.algolia.cache") as mock_cache:
mock_cache.get.return_value = None
mock_cache.set.return_value = True
yield mock_cache


@pytest.mark.usefixtures("_clear_cache")
class TestAlgoliaSearch:
@pytest.mark.parametrize(
("index_name", "query", "page", "hits_per_page", "facet_filters", "expected_result"),
Expand Down Expand Up @@ -92,7 +91,6 @@ def test_algolia_search_invalid_method(self):
@pytest.mark.parametrize(
("index_name", "query", "page", "hits_per_page", "facet_filters", "error_message"),
[
# Index name tests
(
5,
"owasp",
Expand All @@ -101,14 +99,38 @@ def test_algolia_search_invalid_method(self):
["idx_is_active:true"],
"indexName is required and must be a string.",
),
# Query tests
("chapters", 5, 2, 20, ["idx_is_active:true"], "query must be a string."),
# Page tests
("committees", "review", "0", 5, [], "page value must be an integer."),
# hitsPerPage tests
("committees", "review", 1, "1001", [], "hitsPerPage must be an integer."),
# Facet filters tests
("issues", "bug", 1, 10, "idx_is_active:true", "facetFilters must be a list."),
(
"chapters",
5,
2,
20,
["idx_is_active:true"],
"query must be a string.",
),
(
"committees",
"review",
"0",
5,
[],
"page value must be an integer.",
),
(
"committees",
"review",
1,
"1001",
[],
"hitsPerPage must be an integer.",
),
(
"issues",
"bug",
1,
10,
"idx_is_active:true",
"facetFilters must be a list.",
),
],
)
def test_algolia_search_invalid_request(
Expand Down
1 change: 1 addition & 0 deletions cspell/custom-dict.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pygoat
pymdownx
pyyaml
repositorycontributor
requirepass
rsc
saft
sakanashi
Expand Down
24 changes: 24 additions & 0 deletions docker/docker-compose-local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ services:
context: ../backend
dockerfile: docker/Dockerfile.local
depends_on:
cache:
condition: service_healthy
db:
condition: service_healthy
env_file: ../backend/.env
Expand All @@ -19,6 +21,8 @@ services:
DJANGO_DB_PASSWORD: ${DJANGO_DB_PASSWORD:-nest_user_dev_password}
DJANGO_DB_PORT: ${DJANGO_DB_PORT:-5432}
DJANGO_DB_USER: ${DJANGO_DB_USER:-nest_user_dev}
DJANGO_REDIS_HOST: ${DJANGO_REDIS_HOST:-nest-cache}
DJANGO_REDIS_PASSWORD: ${DJANGO_REDIS_HOST:-nest-cache-password}
networks:
- nest-network
ports:
Expand All @@ -27,6 +31,25 @@ services:
- ../backend:/home/owasp
- backend-venv:/home/owasp/.venv

cache:
command: >
sh -c '
redis-server --requirepass $$REDIS_PASSWORD --maxmemory 25mb --maxmemory-policy allkeys-lru
'
container_name: nest-cache
image: redis:7.2.7-alpine3.21
environment:
REDIS_PASSWORD: ${DJANGO_REDIS_PASSWORD:-nest-cache-password}
healthcheck:
interval: 5s
retries: 5
test: [CMD, redis-cli, -a, $REDIS_PASSWORD, ping]
timeout: 5s
networks:
- nest-network
volumes:
- cache-data:/data

db:
container_name: nest-db
image: postgres:16.4
Expand Down Expand Up @@ -91,6 +114,7 @@ networks:

volumes:
backend-venv:
cache-data:
db-data:
docs-venv:
frontend-next:
Expand Down
35 changes: 29 additions & 6 deletions docker/docker-compose-production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,60 @@ services:
image: arkid15r/owasp-nest-backend:production
env_file: .env.backend
depends_on:
production-nest-cache:
condition: service_healthy
production-nest-db:
condition: service_healthy
restart: unless-stopped
networks:
- nest-app-network
- nest-cache-network
- nest-db-network
volumes:
- ./data:/home/owasp/data

production-nest-frontend:
container_name: production-nest-frontend
image: arkid15r/owasp-nest-frontend:production
production-nest-cache:
container_name: production-nest-cache
image: redis:7.2.7-alpine3.21
command: >
sh -c '
redis-server --requirepass $$REDIS_PASSWORD --maxmemory 100mb --maxmemory-policy allkeys-lru
'
env_file: .env.cache
healthcheck:
interval: 5s
retries: 5
test: [CMD, redis-cli, -a, $REDIS_PASSWORD, ping]
timeout: 5s
restart: unless-stopped
volumes:
- ./volumes/cache:/data
networks:
- nest-app-network
- nest-cache-network

production-nest-db:
container_name: production-nest-db
image: postgres:16.4
env_file: .env.db
healthcheck:
test: [CMD, pg_isready, -U, nest_user_production, -d, nest_db_production]
interval: 5s
timeout: 5s
retries: 5
test: [CMD, pg_isready, -U, nest_user_production, -d, nest_db_production]
timeout: 5s
restart: unless-stopped
volumes:
- ./volumes/db:/var/lib/postgresql/data
networks:
- nest-db-network

production-nest-frontend:
container_name: production-nest-frontend
image: arkid15r/owasp-nest-frontend:production
restart: unless-stopped
networks:
- nest-app-network

networks:
nest-app-network:
nest-cache-network:
nest-db-network:
Loading