You've already forked hotpocket
This commit is contained in:
3
services/backend/ops/bin/check-virtualenv.sh
Executable file
3
services/backend/ops/bin/check-virtualenv.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
${VIRTUAL_ENV}/bin/django-admin check
|
||||
53
services/backend/ops/bin/entrypoint-deployment.sh
Executable file
53
services/backend/ops/bin/entrypoint-deployment.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cat <<EOF
|
||||
|
||||
A
|
||||
_ _ _ _ _ _
|
||||
| |__ | |_| |__ | | __ _| |__ ___ _ __ | |
|
||||
| '_ \| __| '_ \| |/ _\` | '_ \/ __| | '_ \| |
|
||||
| |_) | |_| | | | | (_| | |_) \__ \_| |_) | |
|
||||
|_.__/ \__|_| |_|_|\__,_|_.__/|___(_) .__/|_|
|
||||
|_|
|
||||
production
|
||||
|
||||
HotPocket v1.0.0 [${HOTPOCKET_BACKEND_IMAGE_ID}] (https://hotpocket.app/)
|
||||
Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
|
||||
Licensed under Apache-2.0
|
||||
EOF
|
||||
|
||||
export PYTHONPATH="/srv/app:$PYTHONPATH"
|
||||
|
||||
if [ -n "${HOTPOCKET_BACKEND_RUN_MIGRATIONS}" ];then
|
||||
echo; echo "--- Running migrations..."
|
||||
${VIRTUAL_ENV}/bin/python /srv/app/manage.py migrate
|
||||
fi
|
||||
|
||||
if [[ -n "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME}" && -n "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD}" ]]; then
|
||||
echo; echo "--- Creating initial Account..."
|
||||
${VIRTUAL_ENV}/bin/python /srv/app/manage.py create_initial_account "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_USERNAME}" "${HOTPOCKET_BACKEND_INITIAL_ACCOUNT_PASSWORD}"
|
||||
fi
|
||||
|
||||
if [ "${HOTPOCKET_BACKEND_ENV}" = "aio" ];then
|
||||
mkdir -p "${HOTPOCKET_BACKEND_UPLOADS_PATH:-/srv/run/uploads}"
|
||||
fi
|
||||
|
||||
echo; echo "--- Running entrypoint.d parts..."
|
||||
find "/srv/etc/entrypoint.d/" -follow -type f -print | sort -V | while read -r ENTRYPOINT_PART; do
|
||||
case "$ENTRYPOINT_PART" in
|
||||
*.sh)
|
||||
echo "$0: Executing ${ENTRYPOINT_PART}...";
|
||||
"$ENTRYPOINT_PART"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "$0: Ignoring ${ENTRYPOINT_PART}..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo; echo "--- Setup done, booting the app..."; echo
|
||||
|
||||
exec /usr/bin/dumb-init "$@"
|
||||
15
services/backend/ops/deployment/gunicorn.conf.py
Normal file
15
services/backend/ops/deployment/gunicorn.conf.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
import gunicorn_worker_healthcheck
|
||||
|
||||
bind = '0.0.0.0:8000'
|
||||
workers = int(os.environ.get('HOTPOCKET_BACKEND_GUNICORN_WORKERS', 4))
|
||||
logconfig = '/srv/lib/gunicorn.logging.conf'
|
||||
worker_tmp_dir = '/dev/shm'
|
||||
proc_name = 'hotpocket_backend'
|
||||
|
||||
healthcheck_bind = '0.0.0.0:8001'
|
||||
gunicorn_worker_healthcheck.start(globals())
|
||||
48
services/backend/ops/deployment/gunicorn.logging.conf
Normal file
48
services/backend/ops/deployment/gunicorn.logging.conf
Normal file
@@ -0,0 +1,48 @@
|
||||
[loggers]
|
||||
keys=root,gunicorn.error,gunicorn.access
|
||||
|
||||
[handlers]
|
||||
keys=console,error,access
|
||||
|
||||
[formatters]
|
||||
keys=generic,access
|
||||
|
||||
[logger_root]
|
||||
level=INFO
|
||||
handlers=console
|
||||
|
||||
[logger_gunicorn.error]
|
||||
level=INFO
|
||||
handlers=error
|
||||
propagate=0
|
||||
qualname=gunicorn.error
|
||||
|
||||
[logger_gunicorn.access]
|
||||
level=INFO
|
||||
handlers=access
|
||||
propagate=0
|
||||
qualname=gunicorn.access
|
||||
|
||||
[handler_console]
|
||||
class=StreamHandler
|
||||
formatter=generic
|
||||
args=(sys.stdout,)
|
||||
|
||||
[handler_error]
|
||||
class=StreamHandler
|
||||
formatter=generic
|
||||
args=(sys.stdout,)
|
||||
|
||||
[handler_access]
|
||||
class=StreamHandler
|
||||
formatter=access
|
||||
args=(sys.stdout,)
|
||||
|
||||
[formatter_generic]
|
||||
format=%(asctime)s [%(process)d] [%(levelname)s] %(message)s
|
||||
datefmt=%Y-%m-%d %H:%M:%S
|
||||
class=logging.Formatter
|
||||
|
||||
[formatter_access]
|
||||
format=%(message)s
|
||||
class=logging.Formatter
|
||||
1
services/backend/ops/docker/secrets/__init__.py
Normal file
1
services/backend/ops/docker/secrets/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# type: ignore
|
||||
27
services/backend/ops/docker/secrets/admin.py
Normal file
27
services/backend/ops/docker/secrets/admin.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
from keep_it_secret import LiteralField, SecretsField
|
||||
|
||||
from hotpocket_backend.secrets.admin import AdminSecrets
|
||||
|
||||
# isort: off
|
||||
from .common import (
|
||||
DockerCelerySecrets,
|
||||
DockerDatabaseSecrets,
|
||||
DockerOIDCSecrets,
|
||||
)
|
||||
# isort: on
|
||||
|
||||
|
||||
class DockerAdminSecrets(AdminSecrets):
|
||||
SECRET_KEY: str = LiteralField.new('thisisntright')
|
||||
|
||||
DATABASE: DockerDatabaseSecrets = SecretsField.new(DockerDatabaseSecrets)
|
||||
CELERY: DockerCelerySecrets = SecretsField.new(DockerCelerySecrets)
|
||||
|
||||
OIDC: DockerOIDCSecrets = SecretsField.new(DockerOIDCSecrets)
|
||||
|
||||
|
||||
__secrets__ = DockerAdminSecrets()
|
||||
54
services/backend/ops/docker/secrets/common.py
Normal file
54
services/backend/ops/docker/secrets/common.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
from keep_it_secret import EnvField, LiteralField
|
||||
|
||||
from hotpocket_backend.secrets.base import (
|
||||
CelerySecrets,
|
||||
DatabaseSecrets,
|
||||
OIDCSecrets,
|
||||
)
|
||||
|
||||
|
||||
class DockerDatabaseSecrets(DatabaseSecrets):
|
||||
payload: str = LiteralField.new(
|
||||
json.dumps({
|
||||
'engine': os.getenv('HOTPOCKET_BACKEND_DATABASE_ENGINE', 'django.db.backends.postgresql'),
|
||||
'name': os.getenv('HOTPOCKET_BACKEND_DATABASE_NAME', 'hotpocket'),
|
||||
'user': os.getenv('HOTPOCKET_BACKEND_DATABASE_USER', 'hotpocket'),
|
||||
'password': os.getenv('HOTPOCKET_BACKEND_DATABASE_PASSWORD', 'hotpocketm4st3r'),
|
||||
'host': os.getenv('HOTPOCKET_BACKEND_DATABASE_HOST', 'postgres.hotpocket.work.bthlabs.net'),
|
||||
'port': os.getenv('HOTPOCKET_BACKEND_DATABASE_PORT', '5432'),
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
class DockerOIDCSecrets(OIDCSecrets):
|
||||
payload: str = LiteralField.new(
|
||||
json.dumps({
|
||||
'endpoint': os.getenv(
|
||||
'HOTPOCKET_OIDC_ENDPOINT',
|
||||
'https://auth.hotpocket.work.bthlabs.net:8443/realms/hotpocket-development',
|
||||
),
|
||||
'key': os.getenv('HOTPOCKET_OID_KEY', 'hotpocket-backend'),
|
||||
'secret': os.getenv('HOTPOCKET_OIDC_SECRET', 'eAIhyioDjtlbUJnehIEzKt6ONQtMNs1P'),
|
||||
'display_name': 'auth.hotpocket.work',
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
class DockerCelerySecrets(CelerySecrets):
|
||||
broker_url: str = EnvField.new(
|
||||
'HOTPOCKET_BACKEND_CELERY_BROKER_URL',
|
||||
default='amqp://hotpocket:hotpocketm4st3r@rabbitmq.hotpocket.work.bthlabs.net/hotpocket',
|
||||
required=False,
|
||||
)
|
||||
result_backend: str = EnvField.new(
|
||||
'HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND',
|
||||
default='db+postgresql+psycopg://hotpocket:hotpocketm4st3r@postgres.hotpocket.work.bthlabs.net/hotpocket',
|
||||
required=False,
|
||||
)
|
||||
27
services/backend/ops/docker/secrets/webapp.py
Normal file
27
services/backend/ops/docker/secrets/webapp.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
from keep_it_secret import LiteralField, SecretsField
|
||||
|
||||
from hotpocket_backend.secrets.webapp import WebAppSecrets
|
||||
|
||||
# isort: off
|
||||
from .common import (
|
||||
DockerCelerySecrets,
|
||||
DockerDatabaseSecrets,
|
||||
DockerOIDCSecrets,
|
||||
)
|
||||
# isort: on
|
||||
|
||||
|
||||
class DockerWebAppSecrets(WebAppSecrets):
|
||||
SECRET_KEY: str = LiteralField.new('thisisntright')
|
||||
|
||||
DATABASE: DockerDatabaseSecrets = SecretsField.new(DockerDatabaseSecrets)
|
||||
CELERY: DockerCelerySecrets = SecretsField.new(DockerCelerySecrets)
|
||||
|
||||
OIDC: DockerOIDCSecrets = SecretsField.new(DockerOIDCSecrets)
|
||||
|
||||
|
||||
__secrets__ = DockerWebAppSecrets()
|
||||
1
services/backend/ops/docker/settings/__init__.py
Normal file
1
services/backend/ops/docker/settings/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# type: ignore
|
||||
17
services/backend/ops/docker/settings/admin.py
Normal file
17
services/backend/ops/docker/settings/admin.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
# flake8: noqa
|
||||
from __future__ import annotations
|
||||
|
||||
from hotpocket_backend.settings.admin import *
|
||||
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
INSTALLED_APPS += [
|
||||
'django_extensions',
|
||||
]
|
||||
|
||||
LOGGING['loggers']['hotpocket_backend']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_common']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_soa']['level'] = 'DEBUG'
|
||||
14
services/backend/ops/docker/settings/testing.py
Normal file
14
services/backend/ops/docker/settings/testing.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
# flake8: noqa
|
||||
from __future__ import annotations
|
||||
|
||||
from hotpocket_backend.settings.webapp import *
|
||||
|
||||
DEBUG = False
|
||||
TESTING = True
|
||||
|
||||
ROOT_URLCONF = 'hotpocket_backend.urls.testing'
|
||||
|
||||
CELERY_BROKER_URL = 'amqp://guest@rabbitmq.testing.hotpocket/'
|
||||
CELERY_RESULT_BACKEND = 'disabled://'
|
||||
28
services/backend/ops/docker/settings/webapp.py
Normal file
28
services/backend/ops/docker/settings/webapp.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
# flake8: noqa
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from hotpocket_backend.settings.webapp import *
|
||||
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
INSTALLED_APPS += [
|
||||
'django_extensions',
|
||||
]
|
||||
|
||||
LOGGING['loggers']['hotpocket_backend']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_common']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_soa']['level'] = 'DEBUG'
|
||||
|
||||
CELERY_BEAT_SCHEDULE_FILENAME = 'run/celerybeat-schedule-docker'
|
||||
|
||||
UPLOADS_PATH = Path(
|
||||
os.environ.get(
|
||||
'HOTPOCKET_BACKEND_UPLOADS_PATH',
|
||||
'/srv/app/run/uploads',
|
||||
),
|
||||
)
|
||||
1
services/backend/ops/metal/secrets/__init__.py
Normal file
1
services/backend/ops/metal/secrets/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# type: ignore
|
||||
27
services/backend/ops/metal/secrets/admin.py
Normal file
27
services/backend/ops/metal/secrets/admin.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
from keep_it_secret import LiteralField, SecretsField
|
||||
|
||||
from hotpocket_backend.secrets.admin import AdminSecrets
|
||||
|
||||
# isort: off
|
||||
from .common import (
|
||||
MetalCelerySecrets,
|
||||
MetalDatabaseSecrets,
|
||||
MetalOIDCSecrets,
|
||||
)
|
||||
# isort: on
|
||||
|
||||
|
||||
class MetalAdminSecrets(AdminSecrets):
|
||||
SECRET_KEY: str = LiteralField.new('thisisntright')
|
||||
|
||||
DATABASE: MetalDatabaseSecrets = SecretsField.new(MetalDatabaseSecrets)
|
||||
CELERY: MetalCelerySecrets = SecretsField.new(MetalCelerySecrets)
|
||||
|
||||
OIDC: MetalOIDCSecrets = SecretsField.new(MetalOIDCSecrets)
|
||||
|
||||
|
||||
__secrets__ = MetalAdminSecrets()
|
||||
54
services/backend/ops/metal/secrets/common.py
Normal file
54
services/backend/ops/metal/secrets/common.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
from keep_it_secret import EnvField, LiteralField
|
||||
|
||||
from hotpocket_backend.secrets.base import (
|
||||
CelerySecrets,
|
||||
DatabaseSecrets,
|
||||
OIDCSecrets,
|
||||
)
|
||||
|
||||
|
||||
class MetalDatabaseSecrets(DatabaseSecrets):
|
||||
payload: str = LiteralField.new(
|
||||
json.dumps({
|
||||
'engine': os.getenv('HOTPOCKET_BACKEND_DATABASE_ENGINE', 'django.db.backends.postgresql'),
|
||||
'name': os.getenv('HOTPOCKET_BACKEND_DATABASE_NAME', 'hotpocket'),
|
||||
'user': os.getenv('HOTPOCKET_BACKEND_DATABASE_USER', 'hotpocket'),
|
||||
'password': os.getenv('HOTPOCKET_BACKEND_DATABASE_PASSWORD', 'hotpocketm4st3r'),
|
||||
'host': os.getenv('HOTPOCKET_BACKEND_DATABASE_HOST', 'postgres.hotpocket.work.bthlabs.net'),
|
||||
'port': os.getenv('HOTPOCKET_BACKEND_DATABASE_PORT', '5432'),
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
class MetalOIDCSecrets(OIDCSecrets):
|
||||
payload: str = LiteralField.new(
|
||||
json.dumps({
|
||||
'endpoint': os.getenv(
|
||||
'HOTPOCKET_OIDC_ENDPOINT',
|
||||
'https://auth.hotpocket.work.bthlabs.net:8443/realms/hotpocket-development',
|
||||
),
|
||||
'key': os.getenv('HOTPOCKET_OID_KEY', 'hotpocket-backend'),
|
||||
'secret': os.getenv('HOTPOCKET_OIDC_SECRET', 'eAIhyioDjtlbUJnehIEzKt6ONQtMNs1P'),
|
||||
'display_name': 'auth.hotpocket.work',
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
class MetalCelerySecrets(CelerySecrets):
|
||||
broker_url: str = EnvField.new(
|
||||
'HOTPOCKET_BACKEND_CELERY_BROKER_URL',
|
||||
default='amqp://hotpocket:hotpocketm4st3r@rabbitmq.hotpocket.work.bthlabs.net/hotpocket',
|
||||
required=False,
|
||||
)
|
||||
result_backend: str = EnvField.new(
|
||||
'HOTPOCKET_BACKEND_CELERY_RESULT_BACKEND',
|
||||
default='db+postgresql+psycopg://hotpocket:hotpocketm4st3r@postgres.hotpocket.work.bthlabs.net/hotpocket',
|
||||
required=False,
|
||||
)
|
||||
27
services/backend/ops/metal/secrets/webapp.py
Normal file
27
services/backend/ops/metal/secrets/webapp.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
from __future__ import annotations
|
||||
|
||||
from keep_it_secret import LiteralField, SecretsField
|
||||
|
||||
from hotpocket_backend.secrets.webapp import WebAppSecrets
|
||||
|
||||
# isort: off
|
||||
from .common import (
|
||||
MetalCelerySecrets,
|
||||
MetalDatabaseSecrets,
|
||||
MetalOIDCSecrets,
|
||||
)
|
||||
# isort: on
|
||||
|
||||
|
||||
class MetalWebAppSecrets(WebAppSecrets):
|
||||
SECRET_KEY: str = LiteralField.new('thisisntright')
|
||||
|
||||
DATABASE: MetalDatabaseSecrets = SecretsField.new(MetalDatabaseSecrets)
|
||||
CELERY: MetalCelerySecrets = SecretsField.new(MetalCelerySecrets)
|
||||
|
||||
OIDC: MetalOIDCSecrets = SecretsField.new(MetalOIDCSecrets)
|
||||
|
||||
|
||||
__secrets__ = MetalWebAppSecrets()
|
||||
1
services/backend/ops/metal/settings/__init__.py
Normal file
1
services/backend/ops/metal/settings/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# type: ignore
|
||||
17
services/backend/ops/metal/settings/admin.py
Normal file
17
services/backend/ops/metal/settings/admin.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
# flake8: noqa
|
||||
from __future__ import annotations
|
||||
|
||||
from hotpocket_backend.settings.admin import *
|
||||
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
INSTALLED_APPS += [
|
||||
'django_extensions',
|
||||
]
|
||||
|
||||
LOGGING['loggers']['hotpocket_backend']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_common']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_soa']['level'] = 'DEBUG'
|
||||
14
services/backend/ops/metal/settings/testing.py
Normal file
14
services/backend/ops/metal/settings/testing.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
# flake8: noqa
|
||||
from __future__ import annotations
|
||||
|
||||
from hotpocket_backend.settings.webapp import *
|
||||
|
||||
DEBUG = False
|
||||
TESTING = True
|
||||
|
||||
ROOT_URLCONF = 'hotpocket_backend.urls.testing'
|
||||
|
||||
CELERY_BROKER_URL = 'amqp://guest@rabbitmq.testing.hotpocket/'
|
||||
CELERY_RESULT_BACKEND = 'disabled://'
|
||||
28
services/backend/ops/metal/settings/webapp.py
Normal file
28
services/backend/ops/metal/settings/webapp.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# type: ignore
|
||||
# flake8: noqa
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from hotpocket_backend.settings.webapp import *
|
||||
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
INSTALLED_APPS += [
|
||||
'django_extensions',
|
||||
]
|
||||
|
||||
LOGGING['loggers']['hotpocket_backend']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_common']['level'] = 'DEBUG'
|
||||
LOGGING['loggers']['hotpocket_soa']['level'] = 'DEBUG'
|
||||
|
||||
CELERY_BEAT_SCHEDULE_FILENAME = 'run/celerybeat-schedule'
|
||||
|
||||
UPLOADS_PATH = Path(
|
||||
os.environ.get(
|
||||
'HOTPOCKET_BACKEND_UPLOADS_PATH',
|
||||
os.path.join(os.getcwd(), 'run/uploads'),
|
||||
),
|
||||
)
|
||||
Reference in New Issue
Block a user