# eSesja Analytics API v2.0 - Instrukcja Instalacji
## Ubuntu 22.04/24.04 + Apache + MySQL + Node.js

---

## 📋 WYMAGANIA SYSTEMOWE

### Oprogramowanie:
- **Ubuntu**: 22.04 LTS lub 24.04 LTS
- **Node.js**: >= 18.0.0
- **MySQL**: >= 8.0
- **Apache**: >= 2.4
- **PM2**: Do zarządzania procesem Node.js
- **Git**: Do pobrania kodu (opcjonalnie)

### Zalecane parametry serwera:
- **RAM**: minimum 2GB (zalecane 4GB+)
- **CPU**: 2 rdzenie+
- **Dysk**: 10GB wolnego miejsca

---

## 🚀 INSTALACJA KROK PO KROKU

### KROK 1: Aktualizacja systemu

```bash
sudo apt update && sudo apt upgrade -y
```

### KROK 2: Instalacja Node.js 20.x (LTS)

```bash
# Dodaj repozytorium NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -

# Zainstaluj Node.js i npm
sudo apt install -y nodejs

# Sprawdź wersje
node --version  # Powinno być >= v18.0.0
npm --version   # Powinno być >= 9.0.0
```

### KROK 3: Instalacja PM2 (Process Manager)

```bash
# Instalacja globalna PM2
sudo npm install -g pm2

# Konfiguracja PM2 do automatycznego startu
sudo pm2 startup systemd
# Wykonaj komendę którą wyświetli PM2
```

### KROK 4: Instalacja Apache i MySQL (jeśli jeszcze nie ma)

```bash
# Apache
sudo apt install -y apache2

# MySQL Server
sudo apt install -y mysql-server

# Zabezpiecz MySQL
sudo mysql_secure_installation
```

### KROK 5: Konfiguracja bazy danych MySQL

```bash
# Zaloguj się do MySQL
sudo mysql -u root -p
```

```sql
-- Utwórz użytkownika dla API
CREATE USER 'statystyki_user'@'localhost' IDENTIFIED BY 'TWOJE_BEZPIECZNE_HASLO';

-- Nadaj uprawnienia do bazy statystyki
GRANT SELECT, INSERT, UPDATE ON statystyki.* TO 'statystyki_user'@'localhost';

-- Zastosuj zmiany
FLUSH PRIVILEGES;

-- Wyjdź
EXIT;
```

**UWAGA:** Zamień `TWOJE_BEZPIECZNE_HASLO` na silne hasło!

### KROK 6: Przygotowanie struktury katalogów

```bash
# Utwórz katalog dla API
sudo mkdir -p /var/www/esesja-api

# Utwórz katalog na logi
sudo mkdir -p /var/log/esesja-api

# Ustaw właściciela
sudo chown -R $USER:$USER /var/www/esesja-api
sudo chown -R $USER:$USER /var/log/esesja-api

# Ustaw uprawnienia
sudo chmod 755 /var/www/esesja-api
sudo chmod 755 /var/log/esesja-api
```

### KROK 7: Skopiowanie plików API

```bash
# Przejdź do katalogu API
cd /var/www/esesja-api

# Skopiuj wszystkie pliki z przygotowanego API do tego katalogu
# Struktura powinna wyglądać tak:
# /var/www/esesja-api/
# ├── config/
# │   ├── database.js
# │   └── logger.js
# ├── controllers/
# │   ├── radniController.js
# │   ├── glosowaniaController.js
# │   ├── statystykiController.js
# │   ├── posiedzeniaController.js
# │   └── utilsController.js
# ├── middleware/
# │   ├── security.js
# │   └── errorHandler.js
# ├── routes/
# │   ├── radni.js
# │   ├── glosowania.js
# │   ├── statystyki.js
# │   ├── posiedzenia.js
# │   └── utils.js
# ├── server.js
# ├── package.json
# ├── ecosystem.config.js
# └── .env.example
```

### KROK 8: Instalacja zależności npm

```bash
cd /var/www/esesja-api
npm install
```

### KROK 9: Konfiguracja pliku .env

```bash
# Skopiuj przykładowy plik
cp .env.example .env

# Edytuj plik
nano .env
```

**Zawartość pliku .env:**

```env
# Konfiguracja bazy danych MySQL
DB_HOST=localhost
DB_PORT=3306
DB_USER=statystyki_user
DB_PASSWORD=TWOJE_BEZPIECZNE_HASLO
DB_NAME=statystyki

# Konfiguracja serwera API
API_PORT=3001
NODE_ENV=production

# Zabezpieczenia CORS - dozwolone domeny
ALLOWED_ORIGINS=https://twoja-domena.pl,https://www.twoja-domena.pl

# Klucz API (opcjonalny - wygeneruj losowy)
API_SECRET_KEY=

# Rate limiting
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100

# Logowanie
LOG_LEVEL=info
LOG_DIR=/var/log/esesja-api
```

**WAŻNE:**
1. Zamień `TWOJE_BEZPIECZNE_HASLO` na hasło z KROKU 5
2. Zamień `https://twoja-domena.pl` na rzeczywisty adres Twojej strony
3. Jeśli chcesz dodatkowe zabezpieczenie API Key:
   ```bash
   openssl rand -hex 32
   ```
   Wygenerowany ciąg wklej jako `API_SECRET_KEY`

### KROK 10: Testowe uruchomienie API

```bash
# Sprawdź czy API się uruchamia
cd /var/www/esesja-api
node server.js
```

Jeśli wszystko działa poprawnie, zobaczysz:
```
==================================================
eSesja Analytics API v2.0
Environment: production
Server running on port 3001
Health check: http://localhost:3001/health
API endpoint: http://localhost:3001/api
==================================================
✓ Połączenie z bazą danych MySQL nawiązane pomyślnie
```

Zatrzymaj serwer (Ctrl+C) i przejdź do następnego kroku.

### KROK 11: Uruchomienie API przez PM2

```bash
cd /var/www/esesja-api

# Uruchom API przez PM2
pm2 start ecosystem.config.js

# Zapisz konfigurację PM2
pm2 save

# Sprawdź status
pm2 status

# Sprawdź logi
pm2 logs esesja-api

# Monitoruj zasoby
pm2 monit
```

**Przydatne komendy PM2:**
```bash
pm2 restart esesja-api    # Restart API
pm2 stop esesja-api        # Zatrzymaj API
pm2 delete esesja-api      # Usuń z PM2
pm2 logs esesja-api --lines 100  # Pokaż ostatnie 100 linii logów
```

### KROK 12: Konfiguracja Apache jako Reverse Proxy

#### Włącz potrzebne moduły Apache:

```bash
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod headers
sudo a2enmod rewrite
sudo systemctl restart apache2
```

#### Utwórz plik konfiguracji VirtualHost:

```bash
sudo nano /etc/apache2/sites-available/esesja-api.conf
```

**Zawartość pliku (dla subdomena api.twoja-domena.pl):**

```apache
<VirtualHost *:80>
    ServerName api.twoja-domena.pl
    ServerAdmin admin@twoja-domena.pl

    # Logi
    ErrorLog ${APACHE_LOG_DIR}/esesja-api-error.log
    CustomLog ${APACHE_LOG_DIR}/esesja-api-access.log combined

    # Reverse Proxy do Node.js API
    ProxyPreserveHost On
    ProxyPass / http://localhost:3001/
    ProxyPassReverse / http://localhost:3001/

    # Nagłówki bezpieczeństwa
    Header always set X-Frame-Options "DENY"
    Header always set X-Content-Type-Options "nosniff"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"

    # CORS (jeśli potrzebujesz)
    Header always set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
    Header always set Access-Control-Allow-Headers "Content-Type, Authorization, X-API-Key"

    <Location />
        Require all granted
    </Location>
</VirtualHost>
```

**Alternatywa: API w podkatalogu głównej domeny (np. twoja-domena.pl/api):**

```apache
<VirtualHost *:80>
    ServerName twoja-domena.pl
    DocumentRoot /var/www/html

    # ...inne konfiguracje...

    # Reverse Proxy dla /api
    ProxyPass /api http://localhost:3001/api
    ProxyPassReverse /api http://localhost:3001/api

    <Location /api>
        Require all granted
    </Location>
</VirtualHost>
```

#### Włącz konfigurację i restart Apache:

```bash
# Włącz nową konfigurację
sudo a2ensite esesja-api.conf

# Sprawdź konfigurację
sudo apache2ctl configtest

# Restart Apache
sudo systemctl restart apache2
```

### KROK 13: Konfiguracja SSL/HTTPS z Let's Encrypt (ZALECANE!)

```bash
# Zainstaluj certbot
sudo apt install -y certbot python3-certbot-apache

# Uzyskaj certyfikat SSL (zamień na swoją domenę)
sudo certbot --apache -d api.twoja-domena.pl

# Certbot automatycznie skonfiguruje HTTPS
# Wybierz opcję przekierowania HTTP -> HTTPS (zalecane)

# Test automatycznego odnawiania
sudo certbot renew --dry-run
```

Po tym kroku Apache automatycznie utworzy plik:
`/etc/apache2/sites-available/esesja-api-le-ssl.conf` z konfiguracją HTTPS.

### KROK 14: Konfiguracja firewalla (opcjonalnie)

```bash
# Sprawdź status
sudo ufw status

# Pozwól na SSH (jeśli nie jest)
sudo ufw allow OpenSSH

# Pozwól na HTTP i HTTPS
sudo ufw allow 'Apache Full'

# Włącz firewall
sudo ufw enable

# Sprawdź reguły
sudo ufw status verbose
```

### KROK 15: Testowanie API

#### Test lokalny (z serwera):

```bash
# Health check
curl http://localhost:3001/health

# API root
curl http://localhost:3001/api

# Test endpointu radnych
curl http://localhost:3001/api/radni
```

#### Test przez Apache (z zewnątrz):

```bash
# Health check (zamień na swoją domenę)
curl https://api.twoja-domena.pl/health

# API root
curl https://api.twoja-domena.pl/api

# Test endpointu radnych
curl https://api.twoja-domena.pl/api/radni
```

---

## 🔧 KONFIGURACJA ZAAWANSOWANA

### Zwiększenie limitów dla produkcji

#### 1. Limity systemowe Linux:

```bash
# Edytuj limits.conf
sudo nano /etc/security/limits.conf

# Dodaj na końcu:
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536

# Wyloguj się i zaloguj ponownie
```

#### 2. Zwiększenie limitów MySQL:

```bash
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

# Dodaj/zmodyfikuj:
[mysqld]
max_connections = 200
innodb_buffer_pool_size = 1G
```

```bash
sudo systemctl restart mysql
```

#### 3. Optymalizacja Apache:

```bash
sudo nano /etc/apache2/mods-available/mpm_event.conf

# Dostosuj wartości:
<IfModule mpm_event_module>
    StartServers             2
    MinSpareThreads         25
    MaxSpareThreads         75
    ThreadLimit             64
    ThreadsPerChild         25
    MaxRequestWorkers      150
    MaxConnectionsPerChild   0
</IfModule>
```

```bash
sudo systemctl restart apache2
```

### Rotacja logów

PM2 automatycznie zarządza swoimi logami, ale możesz skonfigurować logrotate dla logów aplikacji:

```bash
sudo nano /etc/logrotate.d/esesja-api
```

```
/var/log/esesja-api/*.log {
    daily
    rotate 14
    compress
    delaycompress
    notifempty
    missingok
    copytruncate
}
```

---

## 📊 MONITOROWANIE

### Sprawdzanie statusu usług:

```bash
# Status PM2
pm2 status

# Status Apache
sudo systemctl status apache2

# Status MySQL
sudo systemctl status mysql

# Użycie zasobów przez Node.js
pm2 monit
```

### Sprawdzanie logów:

```bash
# Logi PM2
pm2 logs esesja-api

# Logi aplikacji (Winston)
tail -f /var/log/esesja-api/api-$(date +%Y-%m-%d).log

# Logi błędów
tail -f /var/log/esesja-api/error-$(date +%Y-%m-%d).log

# Logi Apache
sudo tail -f /var/log/apache2/esesja-api-access.log
sudo tail -f /var/log/apache2/esesja-api-error.log
```

---

## 🛡️ BEZPIECZEŃSTWO - CHECKLIST

- [ ] Zmieniono domyślne hasło MySQL
- [ ] Utworzono dedykowanego użytkownika MySQL z ograniczonymi uprawnieniami
- [ ] Skonfigurowano `.env` z właściwymi domenami w `ALLOWED_ORIGINS`
- [ ] Włączono HTTPS z certyfikatem SSL
- [ ] Ustawiono restrykcyjne uprawnienia do plików (755 katalogi, 644 pliki)
- [ ] Skonfigurowano firewall (ufw)
- [ ] Włączono rate limiting w API
- [ ] Regularnie aktualizowano system i zależności npm
- [ ] Zabezpieczono plik `.env` (chmod 600)
- [ ] Wyłączono niepotrzebne usługi systemowe

---

## 🔄 AKTUALIZACJA API

```bash
# Zatrzymaj API
pm2 stop esesja-api

# Przejdź do katalogu
cd /var/www/esesja-api

# Backup bazy (opcjonalnie)
mysqldump -u root -p statystyki > backup_$(date +%Y%m%d).sql

# Pobierz nowe pliki (git pull lub skopiuj ręcznie)

# Zainstaluj nowe zależności
npm install

# Uruchom ponownie API
pm2 restart esesja-api

# Sprawdź logi
pm2 logs esesja-api --lines 50
```

---

## ❓ ROZWIĄZYWANIE PROBLEMÓW

### Problem: API nie startuje

```bash
# Sprawdź logi PM2
pm2 logs esesja-api --err

# Sprawdź połączenie z MySQL
mysql -u statystyki_user -p statystyki -e "SELECT 1"

# Sprawdź czy port 3001 jest wolny
sudo netstat -tulpn | grep 3001
```

### Problem: 502 Bad Gateway w Apache

```bash
# Sprawdź czy API działa
pm2 status

# Sprawdź logi Apache
sudo tail -100 /var/log/apache2/esesja-api-error.log

# Restart Apache
sudo systemctl restart apache2
```

### Problem: CORS errors

1. Sprawdź plik `.env` -> `ALLOWED_ORIGINS`
2. Dodaj domenę frontendu do listy dozwolonych
3. Restart API: `pm2 restart esesja-api`

### Problem: Powolne zapytania

```bash
# Sprawdź logi wolnych zapytań
grep "Wolne zapytanie" /var/log/esesja-api/api-$(date +%Y-%m-%d).log

# Dodaj indeksy w MySQL (jeśli brakuje)
# Sprawdź sekcję "Optymalizacja bazy danych" poniżej
```

---

## 🎯 NASTĘPNE KROKI

Po udanej instalacji API:

1. **Przetestuj wszystkie endpointy** - użyj Postmana lub curl
2. **Skonfiguruj frontend** - podepnij React do API
3. **Zintegruj Solr** - dla wyszukiwania pełnotekstowego
4. **Ustaw monitoring** - np. Grafana + Prometheus
5. **Skonfiguruj backup** - automatyczne backupy bazy danych

---

## 📞 WSPARCIE

W razie problemów:
1. Sprawdź logi: PM2, Apache, MySQL
2. Zweryfikuj konfigurację `.env`
3. Upewnij się że wszystkie usługi działają
4. Sprawdź czy porty nie są blokowane przez firewall

---

**Autor:** Leszek  
**Wersja:** 2.0.0  
**Data:** 2025-12-25
