Files
fotohost/README.md
T

384 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PhotoHost — Фото-хостинг
Современный фото-хостинг на **Python (Flask)**, **PostgreSQL** и **Docker Compose**.
- Красивая главная страница с drag-and-drop загрузкой
- Галерея загруженных фото
- Копирование прямых ссылок на изображения
- Хранение метаданных в PostgreSQL, файлов — в Docker volume
---
## Структура проекта
```
fotohost/
├── app/
│ ├── __init__.py # Flask-приложение и модель Photo
│ ├── routes.py # Маршруты (загрузка, галерея, API)
│ ├── templates/ # HTML-шаблоны
│ └── static/ # CSS и JavaScript
├── uploads/ # Локальная папка (в Docker — volume)
├── docker-compose.yml # Оркестрация web + PostgreSQL
├── Dockerfile
├── wsgi.py # Точка входа для Gunicorn
├── requirements.txt
├── .env.example
└── README.md
```
---
## Развёртывание на Ubuntu 24.04
Подробная пошаговая инструкция для чистого сервера Ubuntu 24.04 LTS.
### 1. Подключение к серверу
```bash
ssh user@YOUR_SERVER_IP
```
Замените `user` на имя пользователя и `YOUR_SERVER_IP` на IP-адрес сервера.
### 2. Обновление системы
```bash
sudo apt update && sudo apt upgrade -y
```
### 3. Установка необходимых пакетов
```bash
sudo apt install -y ca-certificates curl gnupg git
```
### 4. Установка Docker
Docker официально поддерживается на Ubuntu 24.04.
```bash
# Добавить GPG-ключ Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Добавить репозиторий Docker
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Установить Docker Engine и Compose plugin
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
Проверка установки:
```bash
sudo docker run hello-world
docker compose version
```
### 5. Добавить пользователя в группу docker (опционально)
Чтобы не использовать `sudo` перед каждой командой docker:
```bash
sudo usermod -aG docker $USER
newgrp docker
```
### 6. Копирование проекта на сервер
**Вариант A — через Git:**
```bash
cd ~
git clone https://git.evilfox.cc/test2/fotohost.git fotohost
cd fotohost
```
**Вариант B — через SCP с локального компьютера:**
```bash
# Выполнить на локальной машине (Windows PowerShell / Linux)
scp -r ./fotohost user@YOUR_SERVER_IP:~/
```
```bash
# На сервере
cd ~/fotohost
```
**Вариант C — создать файлы вручную** — скопируйте содержимое проекта в каталог `~/fotohost`.
### 7. Настройка переменных окружения
```bash
cp .env.example .env
nano .env
```
Измените значения в `.env`:
```env
POSTGRES_USER=photohost
POSTGRES_PASSWORD=YOUR_STRONG_DB_PASSWORD
POSTGRES_DB=photohost
DATABASE_URL=postgresql://photohost:YOUR_STRONG_DB_PASSWORD@db:5432/photohost
SECRET_KEY=random_string_min_32_chars
MAX_UPLOAD_MB=10
APP_PORT=8080
```
Сгенерировать случайный `SECRET_KEY`:
```bash
python3 -c "import secrets; print(secrets.token_hex(32))"
```
### 8. Запуск приложения
```bash
docker compose up -d --build
```
Проверка статуса контейнеров:
```bash
docker compose ps
```
Ожидаемый результат — оба сервиса `running`:
| Сервис | Контейнер | Порт |
|--------|----------------|-------------|
| web | photohost-web | 8080 → 8000 |
| db | photohost-db | 5432 (внутр.) |
Просмотр логов:
```bash
docker compose logs -f web
```
### 9. Проверка работы
Откройте в браузере:
```
http://YOUR_SERVER_IP:8080
```
Загрузите тестовое изображение — оно должно появиться в галерее.
### 10. Открытие порта в файрволе (UFW)
Если включён UFW:
```bash
sudo ufw allow 8080/tcp
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status
```
### 11. Автозапуск при перезагрузке сервера
Docker Compose с `restart: unless-stopped` уже перезапускает контейнеры. Убедитесь, что Docker включён:
```bash
sudo systemctl enable docker
sudo systemctl start docker
```
---
## Полезные команды
| Действие | Команда |
|-----------------------|----------------------------------|
| Остановить | `docker compose down` |
| Перезапустить | `docker compose restart` |
| Пересобрать | `docker compose up -d --build` |
| Логи web | `docker compose logs -f web` |
| Логи БД | `docker compose logs -f db` |
| Зайти в контейнер web | `docker compose exec web bash` |
| Зайти в PostgreSQL | `docker compose exec db psql -U photohost -d photohost` |
---
## Резервное копирование
### База данных
```bash
docker compose exec db pg_dump -U photohost photohost > backup_$(date +%Y%m%d).sql
```
Восстановление:
```bash
cat backup_20250606.sql | docker compose exec -T db psql -U photohost -d photohost
```
### Загруженные фото
Фото хранятся в Docker volume `uploads_data`. Список volumes:
```bash
docker volume ls
```
Бэкап volume:
```bash
docker run --rm -v photohost_uploads_data:/data -v $(pwd):/backup alpine tar czf /backup/uploads_backup.tar.gz -C /data .
```
---
## Настройка домена и HTTPS (Nginx + Let's Encrypt)
### Установка Nginx и Certbot
```bash
sudo apt install -y nginx certbot python3-certbot-nginx
```
### Конфиг Nginx
```bash
sudo nano /etc/nginx/sites-available/photohost
```
```nginx
server {
listen 80;
server_name photos.example.com;
client_max_body_size 15M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
```bash
sudo ln -s /etc/nginx/sites-available/photohost /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```
### SSL-сертификат
```bash
sudo certbot --nginx -d photos.example.com
```
Откройте порты 80 и 443:
```bash
sudo ufw allow 'Nginx Full'
```
---
## Локальная разработка (без Docker)
```bash
# Установить PostgreSQL локально или запустить только БД:
docker compose up -d db
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Измените DATABASE_URL на localhost:
# DATABASE_URL=postgresql://photohost:photohost_secret@localhost:5432/photohost
export FLASK_APP=wsgi.py
python wsgi.py
```
Приложение будет доступно на `http://localhost:8000`.
> Для локального запуска только БД добавьте в `docker-compose.yml` для сервиса `db` строку `ports: - "5432:5432"`.
---
## API
| Метод | URL | Описание |
|-------|---------------|-----------------------------|
| GET | `/` | Главная страница |
| POST | `/upload` | Загрузка фото (form-data) |
| GET | `/uploads/<filename>` | Прямая ссылка на файл |
| GET | `/api/photos` | JSON-список всех фото |
| POST | `/delete/<id>` | Удаление фото |
Пример ответа `/api/photos`:
```json
[
{
"id": 1,
"url": "/uploads/abc123.jpg",
"original_name": "photo.jpg",
"file_size": 245760,
"size_human": "240.0 КБ",
"created_at": "2025-06-06T12:00:00+00:00"
}
]
```
---
## Устранение неполадок
**Контейнер web не запускается**
```bash
docker compose logs web
```
Частая причина — БД ещё не готова. Healthcheck в `docker-compose.yml` решает это; подождите 30 секунд и перезапустите:
```bash
docker compose restart web
```
**Ошибка подключения к PostgreSQL**
Проверьте, что пароли в `.env` совпадают в `POSTGRES_PASSWORD` и `DATABASE_URL`.
**Фото не загружаются (413 Request Entity Too Large)**
Увеличьте `MAX_UPLOAD_MB` в `.env` и `client_max_body_size` в Nginx.
**Порт 8080 занят**
Измените `APP_PORT=9090` в `.env` и перезапустите:
```bash
docker compose down && docker compose up -d
```
---
## Технологии
- Python 3.12, Flask 3, Gunicorn
- PostgreSQL 16
- SQLAlchemy, Pillow
- Docker & Docker Compose