From c9fb11a9bb9a1396a67cb537374a84cabb1f737a Mon Sep 17 00:00:00 2001 From: Mateusz Date: Mon, 27 Apr 2026 16:25:13 +0200 Subject: [PATCH 01/17] feat: create .dockerignore --- .dockerignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..9e7dc17a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +__pycache__/ +.venv +.github +.env From 1e8bc52fab0f10ec29995252b9fcf7d9677a4815 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Mon, 27 Apr 2026 16:35:58 +0200 Subject: [PATCH 02/17] feat: create dockerfile --- dockerfile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 dockerfile diff --git a/dockerfile b/dockerfile new file mode 100644 index 00000000..45ed43a5 --- /dev/null +++ b/dockerfile @@ -0,0 +1,11 @@ +FROM python:3.11-alpine + +WORKDIR app/ + +COPY requirements.txt + +RUN pip install -r requirements.txt + +COPY . . + + From 8c1d897b8b03a7ac4ecce2c19ea96080963fc9a0 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Mon, 27 Apr 2026 16:48:03 +0200 Subject: [PATCH 03/17] feat: change database settings in settings.py --- cinema_service/settings.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cinema_service/settings.py b/cinema_service/settings.py index 90dde772..52633037 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -85,9 +85,13 @@ # https://docs.djangoproject.com/en/4.0/ref/settings/#databases DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'cinema', + 'USER': 'admin', + 'PASSWORD': 'secret', + 'HOST': 'db', + 'PORT': '5432', } } From 8002e2ea980db555466ea3a404f49c8f8888f78c Mon Sep 17 00:00:00 2001 From: Mateusz Date: Mon, 27 Apr 2026 17:09:08 +0200 Subject: [PATCH 04/17] feat: create wait_for_db.py --- cinema/managment/commands/wait_for_db.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 cinema/managment/commands/wait_for_db.py diff --git a/cinema/managment/commands/wait_for_db.py b/cinema/managment/commands/wait_for_db.py new file mode 100644 index 00000000..601616a3 --- /dev/null +++ b/cinema/managment/commands/wait_for_db.py @@ -0,0 +1,17 @@ +import time +from django.db.utils import OperationalError +from django.core.management.base import BaseCommand + +class Command(BaseCommand): + def handle(self, *args, **options): + db_up = False + while db_up is False: + try: + # This check command tries to see if the DB is ready + 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!')) From ea58769a80f9a172fb77b123be9dc883bbc40c15 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 13:44:32 +0200 Subject: [PATCH 05/17] feat: implement wait_for_db.py --- cinema/{managment => management}/commands/wait_for_db.py | 1 - 1 file changed, 1 deletion(-) rename cinema/{managment => management}/commands/wait_for_db.py (88%) diff --git a/cinema/managment/commands/wait_for_db.py b/cinema/management/commands/wait_for_db.py similarity index 88% rename from cinema/managment/commands/wait_for_db.py rename to cinema/management/commands/wait_for_db.py index 601616a3..931e6106 100644 --- a/cinema/managment/commands/wait_for_db.py +++ b/cinema/management/commands/wait_for_db.py @@ -7,7 +7,6 @@ def handle(self, *args, **options): db_up = False while db_up is False: try: - # This check command tries to see if the DB is ready self.check(databases=['default']) db_up = True except OperationalError: From 9c4470a841c399a509c5ef2eaa25211670633720 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 13:47:12 +0200 Subject: [PATCH 06/17] feat: refactor code --- cinema/management/commands/wait_for_db.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/cinema/management/commands/wait_for_db.py b/cinema/management/commands/wait_for_db.py index 931e6106..6321ed17 100644 --- a/cinema/management/commands/wait_for_db.py +++ b/cinema/management/commands/wait_for_db.py @@ -1,16 +1,18 @@ 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): - db_up = False - while db_up is False: + self.stdout.write("Waiting for database...") + db_conn = None + while not db_conn: try: - self.check(databases=['default']) - db_up = True + db_conn = connections["default"] + db_conn.ensure_connection() except OperationalError: - self.stdout.write('Database unavailable, waiting 1 second...') + self.stdout.write("Database unavailable, waiting 1 second...") time.sleep(1) - - self.stdout.write(self.style.SUCCESS('Database available!')) + self.stdout.write(self.style.SUCCESS("Database available!")) From b547464578bacb6e72a6757cd9dc77398441964e Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 13:52:14 +0200 Subject: [PATCH 07/17] feat: add media_root, static_root --- cinema_service/settings.py | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/cinema_service/settings.py b/cinema_service/settings.py index 52633037..c63b41b2 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -9,8 +9,10 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/4.0/ref/settings/ """ + 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 @@ -20,9 +22,7 @@ # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = ( - "django-insecure-6vubhk2$++agnctay_4pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" -) +SECRET_KEY = "django-insecure-6vubhk2$++agnctay_4pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -85,17 +85,16 @@ # https://docs.djangoproject.com/en/4.0/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'cinema', - 'USER': 'admin', - 'PASSWORD': 'secret', - 'HOST': 'db', - 'PORT': '5432', + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ.get("POSTGRES_DB"), + "USER": os.environ.get("POSTGRES_USER"), + "PASSWORD": os.environ.get("POSTGRES_PASSWORD"), + "HOST": os.environ.get("POSTGRES_HOST"), + "PORT": os.environ.get("POSTGRES_PORT", "5432"), } } - # Password validation # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators @@ -105,16 +104,13 @@ "UserAttributeSimilarityValidator", }, { - "NAME": "django.contrib.auth.password_validation." - "MinimumLengthValidator", + "NAME": "django.contrib.auth.password_validation." "MinimumLengthValidator", }, { - "NAME": "django.contrib.auth.password_validation." - "CommonPasswordValidator", + "NAME": "django.contrib.auth.password_validation." "CommonPasswordValidator", }, { - "NAME": "django.contrib.auth.password_validation." - "NumericPasswordValidator", + "NAME": "django.contrib.auth.password_validation." "NumericPasswordValidator", }, ] @@ -135,10 +131,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_URL = '/media/' +MEDIA_ROOT = '/vol/web/media' # Default primary key field type # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field From c680e3e4788aa8a9e0ad4c9cf7170298ba603cee Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 13:55:15 +0200 Subject: [PATCH 08/17] feat: add RUN and EXPOSE --- dockerfile | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/dockerfile b/dockerfile index 45ed43a5..98becade 100644 --- a/dockerfile +++ b/dockerfile @@ -1,11 +1,21 @@ FROM python:3.11-alpine -WORKDIR app/ +WORKDIR /app -COPY requirements.txt +COPY requirements.txt . -RUN pip install -r requirements.txt +RUN apk add --update --no-cache postgresql-client jpeg libjpeg \ + && apk add --update --no-cache --virtual .tmp-build-deps \ + gcc libc-dev postgresql-dev musl-dev zlib-dev jpeg-dev \ + && pip install --no-cache-dir -r requirements.txt \ + && apk del .tmp-build-deps -COPY . . +RUN mkdir -p /vol/web/media /vol/web/static \ + && adduser -D appuser \ + && chown -R appuser:appuser /vol + +USER appuser +COPY . . +EXPOSE 8000 From eb7cf949d575bae181152f924305c9797670ec6e Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 14:05:54 +0200 Subject: [PATCH 09/17] feat: add psycopg2-binary --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 2dc12c67..622155ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ djangorestframework djangorestframework-simplejwt drf-spectacular Pillow +psycopg2-binary From 1ac7a796cbadfd8ee0f22155f9fb7a25f9c13b07 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 14:07:02 +0200 Subject: [PATCH 10/17] feat: create docker-compose.yml --- ...ovie_actors_alter_movie_genres_and_more.py | 41 +++++++++++++++++++ docker-compose.yml | 38 +++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 cinema/migrations/0002_alter_movie_actors_alter_movie_genres_and_more.py create mode 100644 docker-compose.yml 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..94530f55 --- /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-27 17:09 + +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/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..b5178ee5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,38 @@ +services: + db: + image: postgres:15-alpine + restart: unless-stopped + volumes: + - postgres_data:/var/lib/postgresql/data + env_file: + - .env + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER"] + interval: 10s + timeout: 5s + retries: 5 + + app: + build: . + restart: unless-stopped + volumes: + - .:/app + - media_files:/vol/web/media + - static_files:/vol/web/static + ports: + - "8000:8000" + env_file: + - .env + 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" + depends_on: + db: + condition: service_healthy + +volumes: + postgres_data: + media_files: + static_files: From b3e8a98765929a0b214a2c74579d557254b6388c Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 14:22:57 +0200 Subject: [PATCH 11/17] feat: fix flaek8 issues --- cinema_service/settings.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/cinema_service/settings.py b/cinema_service/settings.py index c63b41b2..a40a3699 100644 --- a/cinema_service/settings.py +++ b/cinema_service/settings.py @@ -22,7 +22,9 @@ # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "django-insecure-6vubhk2$++agnctay_4pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" +SECRET_KEY = ( + "django-insecure-6vubhk2$++agnctay_4pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" +) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -104,13 +106,16 @@ "UserAttributeSimilarityValidator", }, { - "NAME": "django.contrib.auth.password_validation." "MinimumLengthValidator", + "NAME": "django.contrib.auth.password_validation." + "MinimumLengthValidator", }, { - "NAME": "django.contrib.auth.password_validation." "CommonPasswordValidator", + "NAME": "django.contrib.auth.password_validation." + "CommonPasswordValidator", }, { - "NAME": "django.contrib.auth.password_validation." "NumericPasswordValidator", + "NAME": "django.contrib.auth.password_validation." + "NumericPasswordValidator", }, ] @@ -131,11 +136,11 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.0/howto/static-files/ -STATIC_URL = '/static/' -STATIC_ROOT = '/vol/web/static' +STATIC_URL = "/static/" +STATIC_ROOT = "/vol/web/static" -MEDIA_URL = '/media/' -MEDIA_ROOT = '/vol/web/media' +MEDIA_URL = "/media/" +MEDIA_ROOT = "/vol/web/media" # Default primary key field type # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field From 50f11b977bdf07fe501f7736508e58d56afda84a Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 15:15:09 +0200 Subject: [PATCH 12/17] feat: fix problem with database connection --- docker-compose.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b5178ee5..e815531f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,11 +6,6 @@ services: - postgres_data:/var/lib/postgresql/data env_file: - .env - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER"] - interval: 10s - timeout: 5s - retries: 5 app: build: . @@ -29,8 +24,7 @@ services: python manage.py collectstatic --noinput && python manage.py runserver 0.0.0.0:8000" depends_on: - db: - condition: service_healthy + - db volumes: postgres_data: From 0c4262d1c91030bc023ff39ec3d04624a3fd8581 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 15:23:23 +0200 Subject: [PATCH 13/17] feat: remove appuser --- dockerfile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dockerfile b/dockerfile index 98becade..210c3d7e 100644 --- a/dockerfile +++ b/dockerfile @@ -11,10 +11,6 @@ RUN apk add --update --no-cache postgresql-client jpeg libjpeg \ && apk del .tmp-build-deps RUN mkdir -p /vol/web/media /vol/web/static \ - && adduser -D appuser \ - && chown -R appuser:appuser /vol - -USER appuser COPY . . From 2d039d6471ea4bc1328e4e901f0768f97099759f Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 15:25:17 +0200 Subject: [PATCH 14/17] feat: remove \ --- dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerfile b/dockerfile index 210c3d7e..85c0c162 100644 --- a/dockerfile +++ b/dockerfile @@ -10,7 +10,7 @@ RUN apk add --update --no-cache postgresql-client jpeg libjpeg \ && pip install --no-cache-dir -r requirements.txt \ && apk del .tmp-build-deps -RUN mkdir -p /vol/web/media /vol/web/static \ +RUN mkdir -p /vol/web/media /vol/web/static COPY . . From 8cd4f6bda295afd2b789d58fa823d2b6016246ef Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 15:48:44 +0200 Subject: [PATCH 15/17] feat: add create user --- dockerfile | 11 +++++++++++ requirements.txt | 21 +++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/dockerfile b/dockerfile index 85c0c162..bcfeb407 100644 --- a/dockerfile +++ b/dockerfile @@ -12,6 +12,17 @@ RUN apk add --update --no-cache postgresql-client jpeg libjpeg \ RUN mkdir -p /vol/web/media /vol/web/static +RUN adduser \ + --disabled-password \ + --no-create-home \ + django-user + +RUN chown -R django-user:django-user /vol/ + +RUN chmod -R 755 /vol/web/ + +USER django-user + COPY . . EXPOSE 8000 diff --git a/requirements.txt b/requirements.txt index 622155ff..123d668e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,12 @@ -django -flake8 -flake8-quotes -flake8-variables-names -pep8-naming -django-debug-toolbar -djangorestframework -djangorestframework-simplejwt -drf-spectacular -Pillow +Django==6.0.4 +django-debug-toolbar==6.3.0 +djangorestframework==3.17.1 +djangorestframework_simplejwt==5.5.1 +drf-spectacular==0.29.0 +flake8==7.3.0 +flake8-quotes==3.4.0 +flake8-variables-names==0.0.6 +pep8-naming==0.15.1 +pillow==12.2.0 +pyflakes==3.4.0 psycopg2-binary From 89996bb71fa948738af3a0a7e8135862127a3474 Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 15:51:18 +0200 Subject: [PATCH 16/17] feat: update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 123d668e..27dbbe10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==6.0.4 +Django==5.2.13 django-debug-toolbar==6.3.0 djangorestframework==3.17.1 djangorestframework_simplejwt==5.5.1 From 69008476e16c5306ad14897055462d1eb07444ee Mon Sep 17 00:00:00 2001 From: Mateusz Date: Tue, 28 Apr 2026 15:53:04 +0200 Subject: [PATCH 17/17] feat: update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 27dbbe10..b749994e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,4 @@ flake8-variables-names==0.0.6 pep8-naming==0.15.1 pillow==12.2.0 pyflakes==3.4.0 -psycopg2-binary +psycopg2-binary==2.9.12