diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..45eeba05 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +.idea/ +.vscode/ +*.iml +.env +.DS_Store +.venv/ +.pytest_cache/ +**__pycache__/ +README.md +checklist.md +.gitignore +**db.sqlite3 +media \ No newline at end of file diff --git a/.env_example b/.env_example new file mode 100644 index 00000000..d906c661 --- /dev/null +++ b/.env_example @@ -0,0 +1,5 @@ +POSTGRES_DB= +POSTGRES_USER= +POSTGRES_PASSWORD= +DB_HOST= +DB_PORT= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0b1609c6..6eca078d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ *.iml .env .DS_Store -venv/ +.venv/ .pytest_cache/ **__pycache__/ **db.sqlite3 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..e777c51f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM python:3.12-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install -r requirements.txt + +COPY . . + +RUN adduser \ + --disabled-password \ + --no-create-home \ + django-user + +RUN mkdir -p /vol/web/media +RUN mkdir -p /vol/web/static + +RUN chown -R django-user:django-user /vol/ +RUN chown -R django-user:django-user /app + +USER django-user \ No newline at end of file diff --git a/cinema_service/settings.py b/cinema_service/settings.py index 90dde772..09eba630 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -11,6 +11,7 @@ """ from datetime import timedelta from pathlib import Path +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -86,8 +87,12 @@ DATABASES = { "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", + "ENGINE": "django.db.backends.postgresql", + "NAME": os.getenv("POSTGRES_DB"), + "USER": os.getenv("POSTGRES_USER"), + "PASSWORD": os.getenv("POSTGRES_PASSWORD"), + "HOST": os.getenv("DB_HOST", "db"), + "PORT": os.getenv("DB_PORT", "5432"), } } @@ -131,10 +136,11 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.0/howto/static-files/ -STATIC_URL = "static/" +STATIC_URL = "/static/" +STATIC_ROOT = "/vol/web/static" MEDIA_URL = "/media/" -MEDIA_ROOT = BASE_DIR / "media" +MEDIA_ROOT = "/vol/web/media" # Default primary key field type # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..3b3a4621 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +services: + app: + build: + context: . + ports: + - "8000:8000" + command: > + sh -c "python manage.py wait_for_db && + python manage.py migrate && + python manage.py collectstatic --noinput && + python manage.py runserver 0.0.0.0:8000" + env_file: + - .env + depends_on: + - db + volumes: + - .:/app + + db: + image: postgres:14-alpine + ports: + - "5433:5432" + env_file: + - .env + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + postgres_data: diff --git a/requirements.txt b/requirements.txt index 2dc12c67..6f0d9567 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ djangorestframework djangorestframework-simplejwt drf-spectacular Pillow +psycopg2-binary \ No newline at end of file diff --git a/user/management/__init__.py b/user/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/user/management/commands/__init__.py b/user/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/user/management/commands/wait_for_db.py b/user/management/commands/wait_for_db.py new file mode 100644 index 00000000..12a4442f --- /dev/null +++ b/user/management/commands/wait_for_db.py @@ -0,0 +1,21 @@ +import time +from django.db import connections +from django.db.utils import OperationalError +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + def handle(self, *args, **options): + self.stdout.write("Waiting for database...") + + db_conn = None + + while not db_conn: + try: + db_conn = connections["default"] + db_conn.cursor() + except OperationalError: + self.stdout.write("Database unavailable, waiting 1 sec...") + time.sleep(1) + + self.stdout.write(self.style.SUCCESS("Database available!"))