fin
All checks were successful
Build and Push PetClones-site / build-and-push (push) Successful in 42s
All checks were successful
Build and Push PetClones-site / build-and-push (push) Successful in 42s
This commit is contained in:
@@ -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
235
DOCKER.md
@@ -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
|
|
||||||
- [ ] Настроить автоматическое резервное копирование БД
|
|
||||||
|
|
||||||
## Контакты и вопросы
|
|
||||||
|
|
||||||
Если возникнут вопросы или проблемы, проверь логи контейнера.
|
|
||||||
|
|
||||||
11
README.md
11
README.md
@@ -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. Просто жалко выбрасывать.
|
||||||
@@ -1,46 +1,57 @@
|
|||||||
|
% 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
|
||||||
web:
|
web:
|
||||||
# Используем образ из Gitea реестра (собран в CI/CD)
|
# Используем образ из Gitea реестра (собран в CI/CD)
|
||||||
image: git.cube2.ru/erjemin/2024-test-rosmorport:latest
|
image: git.cube2.ru/erjemin/2024-test-rosmorport:latest
|
||||||
|
|
||||||
# Имя контейнера
|
# Имя контейнера
|
||||||
container_name: petclones-site--backend
|
container_name: petclones-site--backend
|
||||||
|
|
||||||
|
# Переменные окружения
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
# Переменные окружения для production
|
# Переменные окружения для production
|
||||||
environment:
|
environment:
|
||||||
- DOCKER_ENV=1
|
- DOCKER_ENV=1
|
||||||
- DEBUG=False
|
- DEBUG=False
|
||||||
- PYTHONUNBUFFERED=1
|
- 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: >
|
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
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<h5>О проекте</h5>
|
<h5>О проекте</h5>
|
||||||
<p>
|
<p>
|
||||||
<strong>2024 год:</strong> Веб-приложение для управления и анализа данных, тестовое задание в процессе соискатения на должность Python разработчика в компанию <a href="https://www.rosmorport.ru/" target="_blank">РосМорПорт</a>.
|
<strong>2024 год:</strong> Веб-приложение для управления и анализа данных, тестовое задание в процессе соискатения на должность <i>Frontend-разработчи</i> в компанию <a href="https://www.rosmorport.ru/" target="_blank">РосМорПорт</a>.
|
||||||
Изготовлено за два дня. Потенци­альный работодатель не предоставил обратной сявзи, в соискании должности отказано.
|
Изготовлено за два дня. В соискании должности отказано.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>Условия задания, подробности и исходный код:</strong><br/>
|
<strong>Условия задания, подробности и исходный код:</strong><br/>
|
||||||
|
|||||||
Reference in New Issue
Block a user