diff --git a/.env.example b/.env.example index 5928542..ac80035 100644 --- a/.env.example +++ b/.env.example @@ -13,7 +13,7 @@ ADMIN_URL=hidden-admin-panel/ # ======================================== # База данных # ======================================== -DB_NAME=database/db.sqlite3 +DB_NAME=db.sqlite3 # Настройки достпа к пакетам в репозитории, чтобы wathtower мог проверять их свежесть и скачивать REPO_USER=xxxxx diff --git a/DOCKER.md b/DOCKER.md deleted file mode 100644 index e49e819..0000000 --- a/DOCKER.md +++ /dev/null @@ -1,235 +0,0 @@ -# Подготовка проекта к контейнеризации - -## Описание - -Этот документ описывает процесс подготовки проекта Django `rosmorport_tsts` к развертыванию в Docker контейнерах. - -## Подготовка окружения - -### Предварительные требования - -- **Python** 3.12 или выше -- **Poetry** 1.7 или выше (для управления зависимостями) -- **Docker** и **Docker Compose** (для контейнеризации) - -### Установка Poetry - -Если Poetry еще не установлена: - -```bash -curl -sSL https://install.python-poetry.org | python3 - -export PATH="$HOME/.local/bin:$PATH" -poetry --version -``` - -### Установка зависимостей локально - -```bash -# Перейди в директорию проекта -cd /Users/e-serg/PRJ/2024-test-rosmorport - -# Установи зависимости через poetry -poetry install - -# Активируй виртуальное окружение -poetry shell -``` - -## Локальная разработка - -### С использованием poetry (рекомендуется для разработки) - -```bash -# Установи зависимости -poetry install - -# Активируй окружение -poetry shell - -# Выполни миграции -cd rosmorport_tsts -python manage.py migrate - -# Собери статические файлы -python manage.py collectstatic - -# Запусти development сервер -python manage.py runserver 0.0.0.0:8000 - -# Откройся в браузере: http://localhost:8000 -``` - -### С использованием Docker Compose (для тестирования контейнера) - -```bash -# Убедись, что Docker и Docker Compose установлены -docker --version -docker-compose --version - -# Запусти контейнер в режиме разработки -docker-compose up -d - -# Проверь логи -docker-compose logs -f web - -#停止контейнер -docker-compose down -``` - -**Docker Compose автоматически:** -- Установит зависимости -- Выполнит миграции БД -- Соберет статические файлы -- Запустит Django dev сервер на порту 8000 - -## Развертывание на Production - -### Подготовка переменных окружения - -1. Скопируй `.env.example` в `.env.prod`: - ```bash - cp .env.example .env.prod - ``` - -2. Отредактируй `.env.prod` с production значениями: - ```env - DEBUG=False - ALLOWED_HOSTS=your-domain.com - SECRET_KEY=your-super-secret-key - DB_HOST=db - DB_NAME=rosmorport_db - DB_USER=postgres - DB_PASSWORD=your-secure-password - ``` - -### Запуск на production - -```bash -# Запусти Docker Compose с production конфигурацией -docker-compose -f docker-compose.prod.yml up -d - -# Проверь статус -docker-compose -f docker-compose.prod.yml ps - -# Просмотри логи -docker-compose -f docker-compose.prod.yml logs -f web -``` - -## Структура файлов - -``` -. -├── Dockerfile # Конфигурация Docker образа -├── docker-compose.yml # Конфигурация для разработки -├── docker-compose.prod.yml # Конфигурация для production -├── .dockerignore # Файлы, игнорируемые при сборке образа -├── pyproject.toml # Конфигурация Poetry -├── poetry.lock # Заблокированные версии зависимостей -├── .env.example # Шаблон переменных окружения -└── rosmorport_tsts/ # Django проект - ├── manage.py - ├── rosmorport_tsts/ - │ ├── settings.py - │ ├── wsgi.py - │ └── ... - └── ... -``` - -## Команды для управления контейнерами - -### Development (docker-compose.yml) - -```bash -# Запуск -docker-compose up -d - -# Остановка -docker-compose down - -# Просмотр логов -docker-compose logs -f web - -# Выполнение команд в контейнере -docker-compose exec web python manage.py createsuperuser -docker-compose exec web python manage.py migrate -docker-compose exec web python manage.py shell - -# Пересборка образа -docker-compose up --build -``` - -### Production (docker-compose.prod.yml) - -```bash -# Запуск -docker-compose -f docker-compose.prod.yml up -d - -# Остановка -docker-compose -f docker-compose.prod.yml down - -# Просмотр логов -docker-compose -f docker-compose.prod.yml logs -f web - -# Создание superuser в production -docker-compose -f docker-compose.prod.yml exec web python manage.py createsuperuser - -# Выполнение миграций -docker-compose -f docker-compose.prod.yml exec web python manage.py migrate -``` - -## Проверка после развертывания - -1. **Проверь доступность приложения:** - ```bash - curl http://localhost:8000 - ``` - -2. **Проверь статус admin панели:** - - Development: http://localhost:8000/admin - - Логин: admin / Пароль: 1234 (если пользователь существует) - -3. **Проверь статические файлы:** - - http://localhost:8000/static/css/rosmorport.css - -4. **Проверь логи на ошибки:** - ```bash - docker-compose logs web | grep -i error - ``` - -## Troubleshooting - -### Проблема: Порт 8000 уже занят - -**Решение:** Измени порт в docker-compose.yml: -```yaml -ports: - - "8080:8000" # Используй 8080 вместо 8000 -``` - -### Проблема: Ошибка при выполнении миграций - -**Решение:** Проверь БД и выполни миграции вручную: -```bash -docker-compose exec web python manage.py migrate -``` - -### Проблема: Статические файлы не загружаются - -**Решение:** Пересобери статические файлы: -```bash -docker-compose exec web python manage.py collectstatic --noinput -``` - -## Дальнейшие улучшения - -- [ ] Добавить Nginx для reverse proxy в production -- [ ] Настроить HTTPS/SSL -- [ ] Добавить PostgreSQL вместо SQLite для production -- [ ] Настроить логирование (ELK, Sentry) -- [ ] Добавить health checks -- [ ] Настроить автоматическое резервное копирование БД - -## Контакты и вопросы - -Если возникнут вопросы или проблемы, проверь логи контейнера. - diff --git a/README.md b/README.md index 0a99db5..063ee6e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,20 @@ ## Тестовое задание rosmorport +**2024 год**: _14 апреля (воскресенье)_ + Тестовое задание на соискание вакансии `Frontend-разработчик` в ФГУП РосМорФлот. * [Тестовое задание](target.md) (таким, как оно было выдано, авторская орфография и пунктуация). * [Мой ответ](my_anwer.txt) (спустя два дня) -* Развёрнуто на [pet-clones.cocorico.ru](https://pet-clones.cocorico.ru/) (login: admin / pwd: 1234) -* [Ответ РосМорФлот](feedback.txt) (спустя четыре дня, в ответ на просьбу обратной связи... судя по логам - заходил один раз сразу по получения решения). +* Развёрнуто на [pet-clones.cube2.ru](https://pet-clones.cube2.ru/) (login: admin / pwd: 1234) +* [Ответ РосМорФлот](feedback.txt) спустя четыре дня, после нескольких обращений об обратной связи... судя по логам + заходил один раз, никих действий (новых записей) произведено не было. Мое мнение о тестовом задании: в задании нет никаких рекомендаций, ограничений и запретов на какие-либо _выбранные технологии_... Зачем задании столько требований по Backend, если вакансия `Frontend-разработчик` -- загадка. И, похоже, дополнительно нужен навык чтения мыслей на расстоянии. +--- +**2026 год**: _1 апреля (среда)_ +Проект, при переносе на новый хостинг, переделан для развертывания в Docker. Просто жалко выбрасывать. \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 65ebef0..0e6d123 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,46 +1,57 @@ + % cat docker-compose.yml # docker-compose.prod.yml для production развертывания проекта rosmorport_tsts -# Использование: docker-compose -f docker-compose.prod.yml up -d +# Для использование на хосте провайдера, перейдите в папку с приложением, размемтите +# его там под именем `docker-compose.yml` +# +# Запуск на продакшене: +# cd <папка-с-приложением> +# mkdir -p config/nginx media database +# sudo chmod -R 777 media database config/nginx +# sodo docker compose up -d -version: '3.9' +# version: '3.9' services: # Django приложение в production web: # Используем образ из Gitea реестра (собран в CI/CD) image: git.cube2.ru/erjemin/2024-test-rosmorport:latest - + # Имя контейнера container_name: petclones-site--backend - + + # Переменные окружения + env_file: + - .env # Переменные окружения для production environment: - DOCKER_ENV=1 - DEBUG=False - PYTHONUNBUFFERED=1 - - # Тома для медиа, статики и БД - volumes: - # Volume для media (загруженные пользователями файлы) - - media:/app/public/media:rw - # Volume для базы данных (SQLite файл) - - database:/app/database:rw - # Volume для экспорта конфигов из контейнера на хост - # Контейнер копирует nginx конфиг при запуске для настройки reverse-proxy на хосте - - ./config/nginx:/tmp/nginx_configs:rw # контейнер пишет сюда конфиги - # Command: скрипт для копирования конфигов из контейнера на хост при запуске - # Встроенный entrypoint nginx:alpine (/docker-entrypoint.sh) запустит это как команду + # Тома для медиа, статики и БД + # ВАЖНО: Используем локальные монтирования, а не именованные тома! + # Данные должны быть доступны на хосте для nginx и резервного копирования + volumes: + # Локальная папка для media (загруженные пользователями файлы) + # Контейнер: /app/public/media → Хост: ./media + - ./media:/app/public/media:rw + # Локальная папка для базы данных (SQLite файл) + # Контейнер: /app/database → Хост: ./database + - ./database:/app/database:rw + # Volume для экспорта конфигов из контейнера на хост + # Контейнер: /tmp/nginx_configs → Хост: ./config/nginx + - ./config/nginx:/tmp/nginx_configs:rw + + # Command: запуск Django приложения с миграциями command: > sh -c " - echo '📋 Копирование внешнего nginx конфига на хост...' && - cp /tmp/pet-clones--external-nginx.conf.source /tmp/nginx_configs/pet-clones--external-nginx.conf.sample && - echo '✅ Пример nginx-конфига создан в ./config/nginx/pet-clones--external-nginx.conf.sample (свежий из контейнера)' && - if [ ! -f /tmp/nginx_configs/pet-clones--external-nginx.conf ]; then - cp /tmp/pet-clones--external-nginx.conf.source /tmp/nginx_configs/pet-clones--external-nginx.conf && - echo '✅ Боевой nginx-конфиг создан в ./config/nginx/pet-clones--external-nginx.conf (свежий из контейнера)' - else - echo '⏭️ Боевой nginx-конфиг оставлен без изменений.' - fi + cd /app/rosmorport_tsts && + echo 'Применение миграций БД...' && + python manage.py migrate --noinput && + echo 'Сбор статических файлов...' && + python manage.py collectstatic --noinput && + echo '🚀 Запуск gunicorn...' && gunicorn --bind 0.0.0.0:8000 --workers 1 --worker-class sync --worker-tmp-dir /dev/shm --max-requests 200 --timeout 120 --access-logfile - --error-logfile - rosmorport_tsts.wsgi:application " @@ -60,7 +71,7 @@ services: resources: limits: cpus: '0.25' - memory: 512M + memory: 256M # Логирование в JSON-файлы (для сбора логов через docker logs) logging: @@ -69,9 +80,6 @@ services: max-size: "5m" # больше лимит в продакшене для логирования max-file: "1" # храним 1 файл лога - networks: - - petclones-site--network - # WATCHTOWER ДЛЯ АВТОМАТИЧЕСКОГО ОБНОВЛЕНИЯ ОБРАЗОВ ИЗ РЕЕСТРА watchtower: image: containrrr/watchtower @@ -97,12 +105,3 @@ services: options: max-size: "1m" max-file: "1" - networks: - - petclones-site--network - -# Сеть для сервисов -networks: - default: - name: petclones-site--network - driver: bridge - diff --git a/docker-compose.yml b/docker-compose.yml index ec51234..0913c77 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,16 +33,7 @@ services: ports: - "127.0.0.1:8040:8000" -# Именованные тома для хранения данных -volumes: - django_staticfiles: - driver: local - django_mediafiles: - driver: local - # postgres_data: - # driver: local - -# Опционально: сеть для сервисов +# Сетевая конфигурация networks: default: name: rosmorport_network diff --git a/rosmorport_tsts/templates-django/popup/about.jinja b/rosmorport_tsts/templates-django/popup/about.jinja index 1f49305..acad4b0 100644 --- a/rosmorport_tsts/templates-django/popup/about.jinja +++ b/rosmorport_tsts/templates-django/popup/about.jinja @@ -8,8 +8,8 @@
- 2024 год: Веб-приложение для управления и анализа данных, тестовое задание в процессе соискатения на должность Python разработчика в компанию РосМорПорт. - Изготовлено за два дня. Потенциальный работодатель не предоставил обратной сявзи, в соискании должности отказано. + 2024 год: Веб-приложение для управления и анализа данных, тестовое задание в процессе соискатения на должность Frontend-разработчи в компанию РосМорПорт. + Изготовлено за два дня. В соискании должности отказано.
Условия задания, подробности и исходный код: