-
Notifications
You must be signed in to change notification settings - Fork 945
solution #1010
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
solution #1010
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| .venv | ||
| __pycache__ | ||
| .git | ||
| .pyc | ||
| .env | ||
| media/ | ||
| staticfiles/* |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,19 @@ | ||
| .idea/ | ||
| .vscode/ | ||
| *.iml | ||
| # Python envs and caches | ||
| .venv | ||
| __pycache__/ | ||
| *.pyc | ||
| # Git | ||
| .git | ||
| .gitignore | ||
| # Env and secrets | ||
| .env | ||
| .DS_Store | ||
| venv/ | ||
| .pytest_cache/ | ||
| **__pycache__/ | ||
| **db.sqlite3 | ||
| media | ||
| # Media and static (не включати в образ) | ||
| media/ | ||
| staticfiles/ | ||
| # IDE / editor | ||
| .vscode/ | ||
|
Comment on lines
+7
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Dockerfile installs build dependencies ( |
||
| .idea/ | ||
| # Test / build artifacts | ||
|
Comment on lines
+12
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: you |
||
| dist/ | ||
| build/ | ||
| *.egg-info/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| FROM python:3.11-slim | ||
|
|
||
| ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| COPY requirements.txt . | ||
|
|
||
| RUN pip install --no-cache-dir -r requirements.txt | ||
|
|
||
| COPY . /app | ||
|
|
||
| RUN mkdir -p /app/media/uploads/movies /app/staticfiles \ | ||
| && adduser --disabled-password --no-create-home my_user \ | ||
| && chown -R my_user:my_user /app \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The success message is printed inside the except branch. That means you log "Database available!" when an OperationalError occurs (DB unavailable). Move this message into the successful branch (e.g., use an |
||
| && chmod +x /app/entrypoint.sh | ||
|
|
||
|
|
||
| USER my_user | ||
|
|
||
|
Comment on lines
+13
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The success message is printed on every loop iteration because |
||
| ENTRYPOINT ["/app/entrypoint.sh"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import time | ||
| from django.db.utils import OperationalError | ||
| from django.db import connections | ||
| from django.core.management.base import BaseCommand | ||
|
|
||
|
|
||
| class Command(BaseCommand): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In |
||
| help = "Waits for DB to be available" # noqa: VNE003 | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
| 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() | ||
|
Comment on lines
+13
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You create |
||
| except OperationalError: | ||
| self.stdout.write("Database unavailable, waiting 1 second") | ||
| time.sleep(1) | ||
| self.stdout.write(self.style.SUCCESS("Database available!")) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The success message is printed regardless of whether the DB connection attempt succeeded because this line is outside the try/except. Move this success write so it only runs when |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # Generated by Django 5.2.13 on 2026-04-20 12:46 | ||
|
|
||
| import django.db.models.deletion | ||
|
Comment on lines
+1
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The entrypoint script should fail fast if any command fails to avoid continuing with a partially initialized container. Add |
||
| from django.conf import settings | ||
| from django.db import migrations, models | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Installing Python packages ( |
||
| dependencies = [ | ||
| ('cinema', '0001_initial'), | ||
| migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
|
Comment on lines
+11
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mounting the host project directory into |
||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AlterField( | ||
| model_name='movie', | ||
| name='actors', | ||
| field=models.ManyToManyField(blank=True, related_name='movies', to='cinema.actor'), | ||
| ), | ||
|
Comment on lines
+13
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the wait_for_db command the success message is printed regardless of whether the DB connection succeeded because the success write is outside the try/except and the loop never breaks on success. Move the success message to run only after |
||
| migrations.AlterField( | ||
| model_name='movie', | ||
| name='genres', | ||
| field=models.ManyToManyField(blank=True, related_name='movies', to='cinema.genre'), | ||
| ), | ||
|
Comment on lines
+24
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The db service volume uses |
||
| 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), | ||
| ), | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
| For the full list of settings and their values, see | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The image installs Python packages with |
||
| https://docs.djangoproject.com/en/4.0/ref/settings/ | ||
| """ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This bind mount |
||
| import os | ||
| from datetime import timedelta | ||
| from pathlib import Path | ||
|
|
||
|
|
@@ -86,8 +87,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"], | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -131,7 +136,8 @@ | |
| # Static files (CSS, JavaScript, Images) | ||
| # https://docs.djangoproject.com/en/4.0/howto/static-files/ | ||
|
|
||
| STATIC_URL = "static/" | ||
| STATIC_URL = "/static/" | ||
| STATIC_ROOT = BASE_DIR / "staticfiles" | ||
|
|
||
| MEDIA_URL = "/media/" | ||
| MEDIA_ROOT = BASE_DIR / "media" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| services: | ||
| cinema: | ||
| build: | ||
| context: . | ||
| env_file: | ||
| - .env | ||
| ports: | ||
| - "8000:8000" | ||
| command: python manage.py runserver 0.0.0.0:8000 | ||
| volumes: | ||
| - .:/app | ||
| - my_media:/app/media/uploads/movies | ||
| depends_on: | ||
| - db | ||
|
|
||
|
|
||
| db: | ||
| image: postgres:16.0-alpine3.17 | ||
| restart: always | ||
| env_file: | ||
| - .env | ||
| ports: | ||
| - "5432:5432" | ||
| volumes: | ||
| - my_db:$PGDATA | ||
|
|
||
| volumes: | ||
| my_db: | ||
| my_media: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| #!/bin/sh | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The docker-compose service is named |
||
| python manage.py wait_for_db | ||
|
Comment on lines
+1
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a fail-fast option so the script stops on any error (for example, |
||
| python manage.py migrate | ||
| python manage.py collectstatic --noinput | ||
|
Comment on lines
+5
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be aware that bind-mounting the project directory over There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In |
||
|
|
||
| exec "$@" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Installing Python packages may require OS-level build dependencies (for example if
psycopg2is in requirements). Consider either usingpsycopg2-binaryin requirements or installing necessary system packages (e.g.libpq-dev,gcc) beforepip installso the image build doesn't fail. Alternatively, add a multi-stage build or use--no-install-recommendsandapt-getto keep the image thin.