diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..692b3014 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.github/ +.venv/ +.gitignore +README.md +.env +.pytest_cache/ +*.pyc +__pycache__/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..526d237e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.11-alpine +LABEL maintainer="ys33ys33ys55@gmail.com" + +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app/ + + +COPY . . + +RUN pip install --no-cache-dir -r requirements.txt + +RUN mkdir -p /files/media/ + +RUN adduser --disabled-password --no-create-home my_user + +RUN chown -R my_user /files/media/ +RUN chmod -R 755 /files/media/ + +USER my_user diff --git a/cinema/management/commands/__init__.py b/cinema/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cinema/management/commands/wait_for_db.py b/cinema/management/commands/wait_for_db.py new file mode 100644 index 00000000..d478b138 --- /dev/null +++ b/cinema/management/commands/wait_for_db.py @@ -0,0 +1,19 @@ +import time + +from django.core.management.base import BaseCommand +from django.db import OperationalError, connection + + +class Command(BaseCommand): + def handle(self, *args, **options): + self.stdout.write("Waiting for database...") + db_conn = None + while not db_conn: + try: + connection.ensure_connection() + db_conn = True + except OperationalError: + self.stdout.write("Database unavailable...") + time.sleep(1) + + self.stdout.write(self.style.SUCCESS("Database available!")) diff --git a/cinema/migrations/0002_alter_movie_actors_alter_movie_genres_and_more.py b/cinema/migrations/0002_alter_movie_actors_alter_movie_genres_and_more.py new file mode 100644 index 00000000..9dbb3914 --- /dev/null +++ b/cinema/migrations/0002_alter_movie_actors_alter_movie_genres_and_more.py @@ -0,0 +1,41 @@ +# Generated by Django 5.2.13 on 2026-04-16 13:35 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cinema', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AlterField( + model_name='movie', + name='actors', + field=models.ManyToManyField(blank=True, related_name='movies', to='cinema.actor'), + ), + migrations.AlterField( + model_name='movie', + name='genres', + field=models.ManyToManyField(blank=True, related_name='movies', to='cinema.genre'), + ), + migrations.AlterField( + model_name='moviesession', + name='cinema_hall', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_sessions', to='cinema.cinemahall'), + ), + migrations.AlterField( + model_name='moviesession', + name='movie', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_sessions', to='cinema.movie'), + ), + migrations.AlterField( + model_name='order', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/cinema_service/settings.py b/cinema_service/settings.py index 90dde772..05140083 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -9,6 +9,8 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/4.0/ref/settings/ """ +import os + from datetime import timedelta from pathlib import Path @@ -27,7 +29,9 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = [ + "0.0.0.0", +] INTERNAL_IPS = [ "127.0.0.1", @@ -86,8 +90,12 @@ DATABASES = { "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ["POSTGRES_DB"], + "USER": os.environ["POSTGRES_USER"], + "PASSWORD": os.environ["POSTGRES_PASSWORD"], + "HOST": os.environ["POSTGRES_HOST"], + "PORT": os.environ["POSTGRES_PORT"], } } @@ -134,7 +142,7 @@ STATIC_URL = "static/" MEDIA_URL = "/media/" -MEDIA_ROOT = BASE_DIR / "media" +MEDIA_ROOT = "/files/media/" # Default primary key field type # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 00000000..f2f50d42 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,31 @@ +services: + app: + build: + context: . + env_file: + - .env + ports: + - "8000:8000" + command: > + sh -c "python manage.py wait_for_db && + python manage.py makemigrations && + python manage.py migrate && + python manage.py runserver 0.0.0.0:8000" + volumes: + - my_media:/files/media + depends_on: + - db + + db: + image: postgres:16.0-alpine3.17 + restart: always + env_file: + - .env + ports: + - "5432:5432" + volumes: + - my_db:/var/lib/postgresql/data/ + +volumes: + my_db: + my_media: diff --git a/example.env b/example.env new file mode 100644 index 00000000..2d3cd46b --- /dev/null +++ b/example.env @@ -0,0 +1,6 @@ +POSTGRES_DB=cinema +POSTGRES_USER=cinema +POSTGRES_PASSWORD=cinema +POSTGRES_HOST=db +POSTGRES_PORT=5432 +PGDATA=/var/lib/postgresql/data/ diff --git a/requirements.txt b/requirements.txt index 2dc12c67..c1caf3ed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,6 @@ django +psycopg +psycopg-binary flake8 flake8-quotes flake8-variables-names