diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..d0bfe055 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +__pycache__/ +*.pyc +.env +venv/ +.git/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..81f8ba88 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM python:3.12-slim + +ENV PYTHONUNBUFFERED=1 +ENV PYTHONPATH=/app + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +RUN adduser \ + --disabled-password \ + --no-create-home \ + django-user + +RUN mkdir -p /vol/web/media /vol/web/static + +RUN chown -R django-user:django-user /vol/ +RUN chmod -R 755 /vol/web/ + +COPY --chown=django-user:django-user . . + +USER django-user + +CMD manage.py runserver 0.0.0.0:8000 \ No newline at end of file diff --git a/cinema/management/commands/wait_for_db.py b/cinema/management/commands/wait_for_db.py new file mode 100644 index 00000000..15ee679f --- /dev/null +++ b/cinema/management/commands/wait_for_db.py @@ -0,0 +1,19 @@ +from django.db.utils import OperationalError +from django.core.management.base import BaseCommand +import time + + +class Command(BaseCommand): + def handle(self, *args, **options): + self.stdout.write("Waiting for database...") + db_up = False + + while db_up is False: + try: + self.check(databases=["default"]) + db_up = True + except OperationalError: + self.stdout.write("Database unavailable, waiting 1 second...") + time.sleep(1) + + self.stdout.write(self.style.SUCCESS("Database available!")) diff --git a/cinema_service/settings.py b/cinema_service/settings.py index 90dde772..7b68369c 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,14 @@ DATABASES = { "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ.get("POSTGRES_DB", "cinema_db"), + "USER": os.environ.get("POSTGRES_USER", "cinema_user"), + "PASSWORD": os.environ.get( + "POSTGRES_PASSWORD", "supersecretpassword123" + ), + "HOST": os.environ.get("POSTGRES_HOST", "db"), + "PORT": os.environ.get("POSTGRES_PORT", "5432"), } } @@ -131,10 +138,12 @@ # 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 files (Uploaded by users) 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..2f9b9f24 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +services: + app: + build: + context: . + ports: + - "8000:8000" + command: > + sh -c "python manage.py wait_for_db && + python manage.py migrate && + python manage.py runserver 0.0.0.0:8000" + env_file: + - .env + depends_on: + - db + volumes: + - static_data:/vol/web/static + - media_data:/vol/web/media + + db: + image: postgres:14-alpine + ports: + - "5433:5432" + env_file: + - .env + volumes: + - my_db:/var/lib/postgresql/data + +volumes: + my_db: + static_data: + media_data: \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 2dc12c67..5f52ec6c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ djangorestframework djangorestframework-simplejwt drf-spectacular Pillow +psycopg2-binary>=2.9.0