Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/.venv/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty ALLOWED_HOSTS list will cause Django to reject requests to 127.0.0.1:8000. In Django 4.0+, even with DEBUG=True, you must explicitly list allowed hosts. Add '127.0.0.1' to the ALLOWED_HOSTS list in settings.py to allow access at http://127.0.0.1:8000/api/.

/.idea/
/Dockerfile
Comment on lines +1 to +3
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .dockerignore entries have incorrect path syntax. Paths like /.venv/ and /Dockerfile with leading slashes refer to filesystem root, not the build context. Since .dockerignore operates relative to the build context (.), paths should not have leading slashes. Change to .venv/, .idea/, Dockerfile, docker-compose.yaml without the leading slash.

/docker-compose.yaml
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[flake8]
inline-quotes = "
ignore = E203, E266, W503, N807, N818, F401
ignore = E203, E266, W503, N807, N818, F401, VNE003
max-line-length = 79
max-complexity = 18
select = B,C,E,F,W,T4,B9,Q0,N8,VNE
Expand Down
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM python:3.12.1-alpine3.18
LABEL maintainer="knyrikkolesnichenko2004@gmail.com"

WORKDIR app/

ENV PYTHONBUFFERED 1

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

RUN mkdir -p /files/media/

RUN adduser \
--disabled-password \
--no-create-home \
django_user

RUN chown -R django_user /files/media
RUN chmod -R 755 /files/media

USER django_user
Empty file added cinema/management/__init__.py
Empty file.
Empty file.
27 changes: 27 additions & 0 deletions cinema/management/commands/wait_for_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import time

from django.core.management.base import BaseCommand
Comment on lines +1 to +3
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .dockerignore file excludes Dockerfile and docker-compose.yaml from the build context. This will cause Docker to fail because the build process needs the Dockerfile to build the image.

from django.db.utils import OperationalError
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excluding docker-compose.yaml from the build context is acceptable, but excluding Dockerfile is critical - it's required to build the app image.

from psycopg import OperationalError as PsycopgOperationalError


class Command(BaseCommand):
help = "Force the app to wait while the database is unavailable"

def handle(self, *args, **options) -> None:
self.stdout.write("Waiting for the database...")
db_up = False

while not db_up:
try:
self.check(databases=("default",))
db_up = True
except (PsycopgOperationalError, OperationalError):
self.stdout.write(
"Database is unavailable, wait for a second..."
)
time.sleep(1)

self.stdout.write(
self.style.SUCCESS("The database is available!")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The depends_on directive only waits for the container to start, not for PostgreSQL to be fully ready to accept connections. The wait_for_db command handles this, but consider using condition: service_healthy with a healthcheck for more robust orchestration.

)
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 6.0.4 on 2026-04-25 06:03

import django.db.models.deletion
from django.conf import settings
Comment on lines +1 to +4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dockerfile and docker-compose.yaml are incorrectly listed in .dockerignore. These files are needed for the Docker build context and should not be excluded. Remove these lines.

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'),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using fixed PostgreSQL version '16.0-alpine3.17' prevents automatic security updates. Use a floating tag like '16-alpine' or 'latest' instead.

),
migrations.AlterField(
model_name='movie',
name='genres',
field=models.ManyToManyField(blank=True, related_name='movies', to='cinema.genre'),
),
migrations.AlterField(
model_name='moviesession',
Comment on lines +18 to +27
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The db service is missing a volumes mount for the database data directory. Add volumes: - my_db:/var/lib/postgresql/data to ensure database data persists between container restarts.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ALLOWED_HOSTS is empty, which will cause Django to reject requests when running in Docker. Add '0.0.0.0' and 'localhost' to ALLOWED_HOSTS in settings.py, or use an environment variable.

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),
),
]
13 changes: 9 additions & 4 deletions cinema_service/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The depends_on directive only waits for the db container to start, not for PostgreSQL to be fully initialized and ready to accept connections. The wait_for_db command mitigates this, but adding a healthcheck to the db service with condition: service_healthy would provide more robust service orchestration.

Expand Down Expand Up @@ -86,9 +87,13 @@

DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
"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"),
},
}


Expand Down Expand Up @@ -134,7 +139,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
Expand Down
31 changes: 31 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
services:
cinema:
build:
context: .
env_file:
- .env
ports:
- "8000:8000"
volumes:
- my_media:/files/media
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"
depends_on:
- db

db:
image: postgres:16.0-alpine3.17
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PostgreSQL image tag '16.0-alpine3.17' has an unusual format. For the postgres image, the tag typically follows the pattern '16-alpine' (version-os). The '16.0' and '3.17' format is non-standard and may not exist or could cause unexpected behavior. Use '16-alpine' or 'latest-alpine' instead.

restart: always
ports:
- "5432:5432"
env_file:
- .env
volumes:
- my_db:$PGDATA
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The db service mounts a volume using $PGDATA environment variable (my_db:$PGDATA), but PGDATA is never set as an environment variable in the docker-compose file. This means the volume will be mounted to an empty/null path. Either set environment: PGDATA: /var/lib/postgresql/data or use a direct path like my_db:/var/lib/postgresql/data.


volumes:
my_db:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty ALLOWED_HOSTS will cause Django to reject all HTTP requests. According to the task requirements, you need to access the project at 127.0.0.1:8000/api/. In Django 4.0+, you must explicitly list allowed hosts. Add 'localhost' and '127.0.0.1' to ALLOWED_HOSTS, or use an environment variable like: ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', 'localhost 127.0.0.1').split()

my_media:
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ djangorestframework
djangorestframework-simplejwt
drf-spectacular
Pillow
psycopg
psycopg_binary
Loading