-
Notifications
You must be signed in to change notification settings - Fork 6
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
Fix docker image build #26
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,11 @@ | |
.dockerignore | ||
.gitignore | ||
.git | ||
.github | ||
.env | ||
.pylintrc | ||
__pycache__ | ||
*.pyc | ||
*.egg-info | ||
.idea/ | ||
|
||
.vscode |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# Test project outside docker | ||
PYTHONPATH=/app/ | ||
DEBUG=0 | ||
DJANGO_SETTINGS_MODULE=config.settings.test | ||
DJANGO_SETTINGS_MODULE=config.settings.production | ||
DJANGO_SECRET_KEY=t3st-s3cr3t#-!k3y | ||
ETHEREUM_NODES_URLS=https://ethereum.publicnode.com,https://polygon-rpc.com | ||
ETH_HASH_BACKEND=pysha3 | ||
PRICES_CACHE_TTL_MINUTES=60 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
# Test project outside docker | ||
PYTHONPATH=/app/ | ||
DEBUG=0 | ||
DJANGO_SETTINGS_MODULE=config.settings.test | ||
DJANGO_SECRET_KEY=t3st-s3cr3t#-!k3y | ||
ETHEREUM_MAINNET_NODE=https://ethereum.publicnode.com | ||
ETHEREUM_NODES_URLS=http://localhost:8545 | ||
ETH_HASH_BACKEND=pysha3 | ||
PRICES_CACHE_TTL_MINUTES=60 | ||
|
||
# Only required for testing | ||
ETHEREUM_MAINNET_NODE=https://ethereum.publicnode.com |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,4 +38,4 @@ COPY --chown=python:python . . | |
# Use numeric ids so kubernetes identifies the user correctly | ||
USER 999:999 | ||
|
||
RUN DJANGO_SETTINGS_MODULE=config.settings.production DJANGO_DOT_ENV_FILE=.env.tracing.sample python manage.py collectstatic --noinput | ||
RUN DJANGO_SETTINGS_MODULE=config.settings.production DJANGO_DOT_ENV_FILE=.env.sample python manage.py collectstatic --noinput | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose that here should be .env instead .env.sample. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, as this is only a placeholder as it needs a file to exist, so it doesn't matter which one, but good catch |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
from config.gunicorn import ( | ||
gunicorn_request_timeout, | ||
gunicorn_worker_connections, | ||
gunicorn_workers, | ||
) | ||
|
||
access_logfile = "-" | ||
error_logfile = "-" | ||
max_requests = 20_000 # Restart a worker after it has processed a given number of requests (for memory leaks) | ||
max_requests_jitter = ( | ||
10_000 # Randomize max_requests to prevent all workers restarting at the same time | ||
) | ||
# graceful_timeout = 90 # https://stackoverflow.com/a/24305939 | ||
keep_alive = 2 | ||
log_file = "-" | ||
log_level = "info" | ||
logger_class = "safe_price_service.utils.loggers.CustomGunicornLogger" | ||
preload_app = False # Load application code before the worker processes are forked (problems with gevent patching) | ||
# For timeout to work with gevent, a custom GeventWorker needs to be used | ||
timeout = gunicorn_request_timeout | ||
|
||
worker_class = "gunicorn_custom_workers.MyGeventWorker" # "gevent" | ||
worker_connections = gunicorn_worker_connections | ||
workers = gunicorn_workers |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import gevent | ||
from gunicorn.workers.ggevent import GeventWorker | ||
|
||
|
||
class MyGeventWorker(GeventWorker): | ||
def patch_psycopg2(self) -> bool: | ||
try: | ||
from psycogreen.gevent import patch_psycopg | ||
|
||
patch_psycopg() | ||
self.log.info("Patched Psycopg2 for gevent") | ||
return True | ||
except ImportError: | ||
self.log.info("Cannot patch psycopg2 for gevent, install psycogreen") | ||
return False | ||
|
||
def patch(self): | ||
super().patch() | ||
self.log.info("Patched all for gevent") | ||
self.patch_psycopg2() | ||
|
||
def handle_request(self, listener_name, req, sock, addr): | ||
try: | ||
with gevent.Timeout(self.cfg.timeout): | ||
super().handle_request(listener_name, req, sock, addr) | ||
except gevent.Timeout: | ||
self.log.error("TimeoutError on %s", req.path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking that we are mixing configuration and execution here, could we separate them in different sections?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right