production with django admin template
This commit is contained in:
@@ -11,6 +11,7 @@ SECRET_KEY = os.environ.get('SECRET_KEY', 'django-insecure-fk#ywtdyi8=t6^vdbo!=b
|
|||||||
DEBUG = os.environ.get('DEBUG', 'True') == 'True'
|
DEBUG = os.environ.get('DEBUG', 'True') == 'True'
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
'unfold',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
@@ -27,6 +28,14 @@ INSTALLED_APPS = [
|
|||||||
'modules.crm',
|
'modules.crm',
|
||||||
'modules.fleet'
|
'modules.fleet'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
UNFOLD = {
|
||||||
|
'SITE_TITLE': 'ERP Admin',
|
||||||
|
'SITE_HEADER': 'ERP Administration',
|
||||||
|
'SITE_SYMBOL': 'dashboard',
|
||||||
|
'SHOW_HISTORY': True,
|
||||||
|
}
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'corsheaders.middleware.CorsMiddleware', # Mora biti prvi
|
'corsheaders.middleware.CorsMiddleware', # Mora biti prvi
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
|||||||
@@ -1,101 +1,22 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export PATH="/usr/local/bin:$PATH"
|
|
||||||
|
|
||||||
APP_DIR="/app"
|
|
||||||
APP_USER="appuser"
|
|
||||||
APP_UID=1000
|
|
||||||
STATIC_ROOT="${STATIC_ROOT:-/app/staticfiles}"
|
|
||||||
MEDIA_ROOT="${MEDIA_ROOT:-/app/media}"
|
|
||||||
|
|
||||||
# Kreiraj korisnika 'appuser' s UID 1000 ako ne postoji
|
|
||||||
if ! getent passwd "${APP_USER}" > /dev/null; then
|
|
||||||
echo "--> Kreiram ${APP_USER}..."
|
|
||||||
addgroup --system --gid ${APP_UID} ${APP_USER} || true
|
|
||||||
adduser --system --uid ${APP_UID} --ingroup ${APP_USER} --no-create-home --disabled-login ${APP_USER} || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ako smo root, pokušaj osigurati ownership. Ako nismo root, samo logiramo i nastavljamo.
|
|
||||||
if [ "$(id -u)" -eq 0 ]; then
|
|
||||||
echo "--> (root) Kreiram/ajustiram direktorije i dozvole..."
|
|
||||||
mkdir -p "${STATIC_ROOT}" "${MEDIA_ROOT}" "${APP_DIR}"
|
|
||||||
# pokušaj chown, ali ne izlazi na grešku ako neuspije (možda host FS to ne dozvoljava)
|
|
||||||
if chown -R ${APP_USER}:${APP_USER} "${STATIC_ROOT}" "${MEDIA_ROOT}" "${APP_DIR}"; then
|
|
||||||
echo "--> Chown uspješan."
|
|
||||||
else
|
|
||||||
echo "--> Upozorenje: chown nije uspio (moguće root_squash ili mount bez chown dopuštenja)."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "--> Nismo root (uid=$(id -u)), preskačem chown. Provjeri vlasništvo na hostu ako su problemi s permisijama."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Helper: run command as appuser but return to the script (do not replace shell)
|
|
||||||
run_as_appuser_now() {
|
|
||||||
if command -v gosu >/dev/null 2>&1; then
|
|
||||||
gosu ${APP_USER} "$@"
|
|
||||||
elif command -v su-exec >/dev/null 2>&1; then
|
|
||||||
su-exec ${APP_USER} "$@"
|
|
||||||
elif command -v runuser >/dev/null 2>&1; then
|
|
||||||
runuser -u ${APP_USER} -- "$@"
|
|
||||||
else
|
|
||||||
# If we're already non-root (appuser), run directly; if root and no helpers, run directly anyway (with warning)
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
|
||||||
"$@"
|
|
||||||
else
|
|
||||||
echo "--> Upozorenje: nema gosu/su-exec/runuser; izvršavam kao root (nepoželjno)."
|
|
||||||
"$@"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Helper: exec the given command as appuser (replace current shell / PID 1)
|
|
||||||
exec_as_appuser() {
|
|
||||||
# Ako smo već appuser, samo izvrši naredbu direktno
|
|
||||||
if [ "$(id -u -n)" = "${APP_USER}" ]; then
|
|
||||||
exec "$@"
|
|
||||||
# Inače, pokušaj koristiti alate za switch
|
|
||||||
elif command -v gosu >/dev/null 2>&1; then
|
|
||||||
exec gosu ${APP_USER} "$@"
|
|
||||||
elif command -v su-exec >/dev/null 2>&1; then
|
|
||||||
exec su-exec ${APP_USER} "$@"
|
|
||||||
else
|
|
||||||
# Fallback
|
|
||||||
exec "$@"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$1" = "gunicorn" ]; then
|
if [ "$1" = "gunicorn" ]; then
|
||||||
echo "--> Pokrećem migracije..."
|
echo "--> Pokrećem migracije..."
|
||||||
# Ako smo root, pokrenimo migrate kao appuser; ako smo non-root (već appuser), pokreni direktno
|
python manage.py migrate --noinput
|
||||||
if [ "$(id -u)" -eq 0 ]; then
|
|
||||||
run_as_appuser_now python manage.py migrate --noinput
|
|
||||||
else
|
|
||||||
python manage.py migrate --noinput
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "--> Osiguravam prava nad statikom prije collectstatic..."
|
echo "--> Skupljam statiku..."
|
||||||
mkdir -p "${STATIC_ROOT}"
|
python manage.py collectstatic --noinput
|
||||||
if [ "$(id -u)" -eq 0 ]; then
|
|
||||||
chown -R ${APP_USER}:${APP_USER} "${STATIC_ROOT}" || echo "--> chown statika nije uspio"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "--> Skupljam statiku..."
|
echo "--> Pokrećem Gunicorn..."
|
||||||
if command -v gosu >/dev/null 2>&1 || command -v su-exec >/dev/null 2>&1 || command -v runuser >/dev/null 2>&1; then
|
exec gunicorn --bind 0.0.0.0:8000 --workers 3 core.wsgi:application
|
||||||
run_as_appuser_now python manage.py collectstatic --noinput
|
|
||||||
else
|
|
||||||
python manage.py collectstatic --noinput
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "--> Pokrećem Gunicorn kao appuser..."
|
|
||||||
exec_as_appuser gunicorn --bind 0.0.0.0:8000 --workers 3 core.wsgi:application
|
|
||||||
|
|
||||||
elif [ "$1" = "celery" ]; then
|
elif [ "$1" = "celery" ]; then
|
||||||
echo "--> Pokrećem Celery kao appuser..."
|
echo "--> Pokrećem Celery..."
|
||||||
shift
|
shift
|
||||||
# Replace PID1 with celery running as appuser
|
exec celery "$@"
|
||||||
exec_as_appuser celery "$@"
|
|
||||||
|
|
||||||
else
|
else
|
||||||
exec "$@"
|
exec "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
101
docker-compose.prod.yml
Normal file
101
docker-compose.prod.yml
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
redis:
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: 004erpbackend
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
DJANGO_SETTINGS_MODULE: core.settings.production
|
||||||
|
command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers 3 --timeout 120
|
||||||
|
volumes:
|
||||||
|
- media_volume:/app/media
|
||||||
|
ports:
|
||||||
|
- "8001:8000"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_started
|
||||||
|
|
||||||
|
worker:
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: 004erpworker
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
DEBUG: "False"
|
||||||
|
DJANGO_SETTINGS_MODULE: core.settings.production
|
||||||
|
command: celery -A core worker --loglevel=info
|
||||||
|
volumes:
|
||||||
|
- media_volume:/app/media
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_started
|
||||||
|
|
||||||
|
flower:
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: 004erpflower
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
DEBUG: "False"
|
||||||
|
DJANGO_SETTINGS_MODULE: core.settings.production
|
||||||
|
command: celery -A core flower --port=5555
|
||||||
|
ports:
|
||||||
|
- "5555:5555"
|
||||||
|
depends_on:
|
||||||
|
redis:
|
||||||
|
condition: service_started
|
||||||
|
worker:
|
||||||
|
condition: service_started
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ./frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: 004erpfrontend
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PUBLIC_API_URL: ${PUBLIC_API_URL}
|
||||||
|
command: sh -c "npm run build && node ./dist/server/entry.mjs"
|
||||||
|
ports:
|
||||||
|
- "4321:4321"
|
||||||
|
depends_on:
|
||||||
|
backend:
|
||||||
|
condition: service_started
|
||||||
|
|
||||||
|
webhook:
|
||||||
|
build: /opt/erp/deploy-webhook
|
||||||
|
container_name: 004erpwebhook
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
WEBHOOK_SECRET: ${GITEA_WEBHOOK_SECRET}
|
||||||
|
ports:
|
||||||
|
- "9001:9001"
|
||||||
|
volumes:
|
||||||
|
- /opt/erp/app:/opt/erp/app
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
redis_data:
|
||||||
|
media_volume:
|
||||||
|
external: true
|
||||||
@@ -27,7 +27,7 @@ services:
|
|||||||
context: ./backend
|
context: ./backend
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
command: celery -A core worker --loglevel=info
|
command: celery -A core worker --loglevel=info
|
||||||
user: "1000:1000"
|
user: "1001:1001"
|
||||||
volumes:
|
volumes:
|
||||||
- ./backend:/app
|
- ./backend:/app
|
||||||
- media_volume:/app/media
|
- media_volume:/app/media
|
||||||
@@ -44,4 +44,4 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
postgres_data:
|
postgres_data:
|
||||||
redis_data:
|
redis_data:
|
||||||
media_volume: # Ovo je ključno za tvoj ERP
|
media_volume: # Ovo je ključno za tvoj ERP
|
||||||
|
|||||||
Reference in New Issue
Block a user