Skip to content

Commit 4bc1c65

Browse files
authored
[#61] Add Redis/Celery service in Render (#64)
* feat: add celery/redis render service [#61] * fix: add condition for redis [#61] * chore: lint [#61] * chore: moar lint [#61] * meh * chore: more new line [#61]
1 parent ab26711 commit 4bc1c65

File tree

6 files changed

+51
-3
lines changed

6 files changed

+51
-3
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Nick Kelly
3+
Copyright (c) 2025 Nick Kelly
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "cookiecutter-fastapi-backend"
3-
version = "1.1.0"
3+
version = "1.2.0"
44
description = "Cookiecutter template to build and deploy fastapi backends..batteries included"
55
authors = ["nickatnight <nialexanderke@proton.me>"]
66
readme = "README.md"

{{ cookiecutter.project_slug }}/.env_example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ POSTGRES_URL=
1616
# Redis
1717
REDIS_HOST=redis
1818
REDIS_PORT=6379
19+
REDIS_URL=
1920
{%- endif %}

{{ cookiecutter.project_slug }}/render.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,43 @@ services:
2626
fromDatabase:
2727
name: {{ cookiecutter.project_slug_db }}db
2828
property: connectionString
29+
{%- if cookiecutter.use_celery == "yes" %}
30+
- key: REDIS_URL
31+
fromService:
32+
name: celery-redis
33+
type: redis
34+
property: connectionString
35+
36+
- type: worker
37+
name: celery-worker
38+
runtime: docker
39+
plan: free
40+
autoDeployTrigger: checksPass
41+
dockerCommand: celery --app=src worker --loglevel=info --concurrency=4
42+
dockerfilePath: ./{{ cookiecutter.backend_container_name }}/Dockerfile
43+
dockerContext: ./{{ cookiecutter.backend_container_name }}
44+
45+
envVars:
46+
- key: PORT
47+
value: '10000'
48+
- key: POETRY_VERSION
49+
value: '1.8.5'
50+
- key: POSTGRES_URL
51+
fromDatabase:
52+
name: {{ cookiecutter.project_slug_db }}db
53+
property: connectionString
54+
- key: REDIS_URL
55+
fromService:
56+
name: celery-redis
57+
type: redis
58+
property: connectionString
2959

60+
- type: redis
61+
name: celery-redis
62+
plan: free # free plans will not persist data
63+
maxmemoryPolicy: noeviction # recommended policy for queues
64+
ipAllowList: [] # only allow internal connections
65+
{%- endif %}
3066
databases:
3167
- name: {{ cookiecutter.project_slug_db }}db
3268
plan: free

{{ cookiecutter.project_slug }}/{{ cookiecutter.backend_container_name }}/src/api/deps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55

66
def get_redis_url() -> str:
7-
return f"redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}"
7+
return settings.REDIS_URL or ""
88

99

1010
def get_redis_client() -> Redis:

{{ cookiecutter.project_slug }}/{{ cookiecutter.backend_container_name }}/src/core/config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Settings(BaseSettings):
2525
{%- if cookiecutter.use_celery == "yes" %}
2626
REDIS_HOST: str = Field(default="")
2727
REDIS_PORT: str = Field(default="")
28+
REDIS_URL: Optional[str] = None
2829
{%- endif %}
2930
DB_POOL_SIZE: int = Field(default=83)
3031
WEB_CONCURRENCY: int = Field(default=9)
@@ -52,6 +53,16 @@ def build_db_connection(cls, v: Optional[str], values: ValidationInfo) -> Any:
5253
host=values.data.get("POSTGRES_HOST"),
5354
path=f"{values.data.get('POSTGRES_DB') or ''}",
5455
).unicode_string()
56+
{%- if cookiecutter.use_celery == "yes" %}
57+
58+
@field_validator("REDIS_URL", mode="before")
59+
@classmethod
60+
def build_redis_connection(cls, v: Optional[str], values: ValidationInfo) -> Any:
61+
if isinstance(v, str) and len(v) > 0:
62+
return v
63+
64+
return f"redis://{values.data.get('REDIS_HOST')}:{values.data.get('REDIS_PORT')}"
65+
{%- endif %}
5566

5667

5768
settings = Settings()

0 commit comments

Comments
 (0)