fin
All checks were successful
Build and Push PetClones-site / build-and-push (push) Successful in 42s

This commit is contained in:
2026-04-01 17:42:21 +03:00
parent 2a37e24242
commit 6093dc2021
6 changed files with 49 additions and 289 deletions

View File

@@ -13,7 +13,7 @@ ADMIN_URL=hidden-admin-panel/
# ======================================== # ========================================
# База данных # База данных
# ======================================== # ========================================
DB_NAME=database/db.sqlite3 DB_NAME=db.sqlite3
# Настройки достпа к пакетам в репозитории, чтобы wathtower мог проверять их свежесть и скачивать # Настройки достпа к пакетам в репозитории, чтобы wathtower мог проверять их свежесть и скачивать
REPO_USER=xxxxx REPO_USER=xxxxx

235
DOCKER.md
View File

@@ -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
- [ ] Настроить автоматическое резервное копирование БД
## Контакты и вопросы
Если возникнут вопросы или проблемы, проверь логи контейнера.

View File

@@ -1,15 +1,20 @@
## Тестовое задание rosmorport ## Тестовое задание rosmorport
**2024 год**: _14 апреля (воскресенье)_
Тестовое задание на соискание вакансии `Frontend-разработчик` в ФГУП РосМорФлот. Тестовое задание на соискание вакансии `Frontend-разработчик` в ФГУП РосМорФлот.
* [Тестовое задание](target.md) (таким, как оно было выдано, авторская орфография и пунктуация). * [Тестовое задание](target.md) (таким, как оно было выдано, авторская орфография и пунктуация).
* [Мой ответ](my_anwer.txt) (спустя два дня) * [Мой ответ](my_anwer.txt) (спустя два дня)
* Развёрнуто на [pet-clones.cocorico.ru](https://pet-clones.cocorico.ru/) (login: admin / pwd: 1234) * Развёрнуто на [pet-clones.cube2.ru](https://pet-clones.cube2.ru/) (login: admin / pwd: 1234)
* [Ответ РосМорФлот](feedback.txt) (спустя четыре дня, в ответ на просьбу обратной связи... судя по логам * [Ответ РосМорФлот](feedback.txt) спустя четыре дня, после нескольких обращений об обратной связи... судя по логам
заходил один раз сразу по получения решения). заходил один раз, никих действий (новых записей) произведено не было.
Мое мнение о тестовом задании: в задании нет никаких рекомендаций, ограничений и запретов на Мое мнение о тестовом задании: в задании нет никаких рекомендаций, ограничений и запретов на
какие-либо _выбранные технологии_... Зачем задании столько требований по Backend, если вакансия какие-либо _выбранные технологии_... Зачем задании столько требований по Backend, если вакансия
`Frontend-разработчик` -- загадка. И, похоже, дополнительно нужен навык чтения мыслей на расстоянии. `Frontend-разработчик` -- загадка. И, похоже, дополнительно нужен навык чтения мыслей на расстоянии.
---
**2026 год**: _1 апреля (среда)_
Проект, при переносе на новый хостинг, переделан для разве­ртывания в Docker. Просто жалко выбрасывать.

View File

@@ -1,7 +1,15 @@
% cat docker-compose.yml
# docker-compose.prod.yml для production развертывания проекта rosmorport_tsts # 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: services:
# Django приложение в production # Django приложение в production
@@ -12,6 +20,9 @@ services:
# Имя контейнера # Имя контейнера
container_name: petclones-site--backend container_name: petclones-site--backend
# Переменные окружения
env_file:
- .env
# Переменные окружения для production # Переменные окружения для production
environment: environment:
- DOCKER_ENV=1 - DOCKER_ENV=1
@@ -19,28 +30,28 @@ services:
- PYTHONUNBUFFERED=1 - PYTHONUNBUFFERED=1
# Тома для медиа, статики и БД # Тома для медиа, статики и БД
# ВАЖНО: Используем локальные монтирования, а не именованные тома!
# Данные должны быть доступны на хосте для nginx и резервного копирования
volumes: volumes:
# Volume для media (загруженные пользователями файлы) # Локальная папка для media (загруженные пользователями файлы)
- media:/app/public/media:rw # Контейнер: /app/public/media → Хост: ./media
# Volume для базы данных (SQLite файл) - ./media:/app/public/media:rw
- database:/app/database:rw # Локальная папка для базы данных (SQLite файл)
# Контейнер: /app/database → Хост: ./database
- ./database:/app/database:rw
# Volume для экспорта конфигов из контейнера на хост # Volume для экспорта конфигов из контейнера на хост
# Контейнер копирует nginx конфиг при запуске для настройки reverse-proxy на хосте # Контейнер: /tmp/nginx_configs → Хост: ./config/nginx
- ./config/nginx:/tmp/nginx_configs:rw # контейнер пишет сюда конфиги - ./config/nginx:/tmp/nginx_configs:rw
# Command: скрипт для копирования конфигов из контейнера на хост при запуске # Command: запуск Django приложения с миграциями
# Встроенный entrypoint nginx:alpine (/docker-entrypoint.sh) запустит это как команду
command: > command: >
sh -c " sh -c "
echo '📋 Копирование внешнего nginx конфига на хост...' && cd /app/rosmorport_tsts &&
cp /tmp/pet-clones--external-nginx.conf.source /tmp/nginx_configs/pet-clones--external-nginx.conf.sample && echo 'Применение миграций БД...' &&
echo '✅ Пример nginx-конфига создан в ./config/nginx/pet-clones--external-nginx.conf.sample (свежий из контейнера)' && python manage.py migrate --noinput &&
if [ ! -f /tmp/nginx_configs/pet-clones--external-nginx.conf ]; then echo 'Сбор статических файлов...' &&
cp /tmp/pet-clones--external-nginx.conf.source /tmp/nginx_configs/pet-clones--external-nginx.conf && python manage.py collectstatic --noinput &&
echo '✅ Боевой nginx-конфиг создан в ./config/nginx/pet-clones--external-nginx.conf (свежий из контейнера)' echo '🚀 Запуск gunicorn...' &&
else
echo '⏭️ Боевой nginx-конфиг оставлен без изменений.'
fi
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 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: resources:
limits: limits:
cpus: '0.25' cpus: '0.25'
memory: 512M memory: 256M
# Логирование в JSON-файлы (для сбора логов через docker logs) # Логирование в JSON-файлы (для сбора логов через docker logs)
logging: logging:
@@ -69,9 +80,6 @@ services:
max-size: "5m" # больше лимит в продакшене для логирования max-size: "5m" # больше лимит в продакшене для логирования
max-file: "1" # храним 1 файл лога max-file: "1" # храним 1 файл лога
networks:
- petclones-site--network
# WATCHTOWER ДЛЯ АВТОМАТИЧЕСКОГО ОБНОВЛЕНИЯ ОБРАЗОВ ИЗ РЕЕСТРА # WATCHTOWER ДЛЯ АВТОМАТИЧЕСКОГО ОБНОВЛЕНИЯ ОБРАЗОВ ИЗ РЕЕСТРА
watchtower: watchtower:
image: containrrr/watchtower image: containrrr/watchtower
@@ -97,12 +105,3 @@ services:
options: options:
max-size: "1m" max-size: "1m"
max-file: "1" max-file: "1"
networks:
- petclones-site--network
# Сеть для сервисов
networks:
default:
name: petclones-site--network
driver: bridge

View File

@@ -33,16 +33,7 @@ services:
ports: ports:
- "127.0.0.1:8040:8000" - "127.0.0.1:8040:8000"
# Именованные тома для хранения данных # Сетевая конфигурация
volumes:
django_staticfiles:
driver: local
django_mediafiles:
driver: local
# postgres_data:
# driver: local
# Опционально: сеть для сервисов
networks: networks:
default: default:
name: rosmorport_network name: rosmorport_network

View File

@@ -8,8 +8,8 @@
<div class="modal-body"> <div class="modal-body">
<h5>О&nbsp;проекте</h5> <h5>О&nbsp;проекте</h5>
<p> <p>
<strong>2024 год:</strong> Веб-приложение для&nbsp;управления и&nbsp;анализа данных, тестовое задание в&nbsp;процессе соискатения на&nbsp;должность Python разработчика в&nbsp;компанию <a href="https://www.rosmorport.ru/" target="_blank">РосМорПорт</a>. <strong>2024 год:</strong> Веб-приложение для&nbsp;управления и&nbsp;анализа данных, тестовое задание в&nbsp;процессе соискатения на&nbsp;должность <i>Frontend-разработчи</i> в&nbsp;компанию <a href="https://www.rosmorport.ru/" target="_blank">РосМорПорт</a>.
Изготовлено за&nbsp;два дня. Потенци&shy;альный работодатель не&nbsp;предоставил обратной сявзи, в&nbsp;соискании&nbsp;должности отказано. Изготовлено за&nbsp;два дня. В&nbsp;соискании&nbsp;должности отказано.
</p> </p>
<p> <p>
<strong>Условия задания, подробности и&nbsp;исходный код:</strong><br/> <strong>Условия задания, подробности и&nbsp;исходный код:</strong><br/>