Typowy deploy wygląda tak: otwierasz FileZillę, logujesz się, nawigujesz do katalogu, przeciągasz pliki, czekasz, sprawdzasz czy strona działa. 10 minut za każdym razem — i łatwo o pomyłkę (wgranie .env na produkcję, nadpisanie configa).
Ze skryptem deploy — jedno polecenie w terminalu. Backup z produkcji, walidacja plików, upload przez szyfrowane FTP, sprawdzenie czy strona odpowiada. 30 sekund zamiast 10 minut.
Pipeline deploy — 6 faz
FAZA 1: Lista paczek TMP → Które pliki wgrywamy? FAZA 2: Walidacja pre-deploy ├── Pliki zakazane (AuthHelper, .env, config prod) ├── CSP nonce check └── PHP/JSON syntax FAZA 3: Potwierdzenie usera [TAK/NIE] → NIGDY nie wgrywaj bez explicit "TAK" FAZA 4: Backup z produkcji → FTP get aktualnych plików do back/ FAZA 5: Upload (LFTP + TLS) → Szyfrowane połączenie, 3 retry, timeout 30s FAZA 6: Post-deploy verify → curl -I na każdą podstronę
| Ręczny deploy (FileZilla) | Automatyczny deploy (skrypt) |
|---|---|
| ~10 minut | ~30 sekund |
| Łatwo wgrać .env na produkcję | Walidacja blokuje zakazane pliki |
| Brak backupu | Automatyczny backup przed wgraniem |
| Nie wiadomo czy strona działa | HTTP check po deployu |
| Nieszyfrowane FTP | FTP + TLS (szyfrowane) |
Konfiguracja — plik credentials
Otwórz terminal i stwórz plik z danymi dostępowymi do FTP:
# Zainstaluj LFTP (jeśli nie masz) brew install lftp # macOS sudo apt install lftp # Linux # Utwórz plik credentials touch config/ftp-servers.env
# Serwer #1 — główna strona FTP_STRONA_HOST="ftp.twoja-firma.pl" FTP_STRONA_USER="uzytkownik" FTP_STRONA_PASS="haslo" FTP_STRONA_PATH="/public_html/" # Serwer #2 — panel admin FTP_ADMIN_HOST="ftp.twoja-firma.pl" FTP_ADMIN_USER="admin_user" FTP_ADMIN_PASS="admin_haslo" FTP_ADMIN_PATH="/public_html/"
Dodaj config/ftp-servers.env do .gitignore od razu! Hasła FTP w repozytorium = katastrofa. Stwórz też ftp-servers.env.example (bez haseł) jako szablon.
Skrypt deploy.sh
#!/bin/bash # Deploy przez LFTP + TLS # Użycie: ./scripts/deploy.sh strona /ścieżka/do/paczki set -e # Załaduj credentials source config/ftp-servers.env SERVER="$1"; PACKAGE="$2" # Wybierz serwer na podstawie nazwy case "$SERVER" in strona) HOST=$FTP_STRONA_HOST USER=$FTP_STRONA_USER PASS=$FTP_STRONA_PASS REMOTE=$FTP_STRONA_PATH ;; *) echo "Nieznany serwer: $SERVER"; exit 1 ;; esac echo "Wgrywam paczkę $PACKAGE na $SERVER..." # Upload przez LFTP z TLS lftp -c " set ssl:verify-certificate no; set net:timeout 30; set net:max-retries 3; open -u $USER,$PASS $HOST; lcd $PACKAGE; cd $REMOTE; mirror --reverse --verbose --only-newer; bye; " echo "Upload zakończony."
# Nadaj uprawnienia chmod +x scripts/deploy.sh # Uruchom ./scripts/deploy.sh strona /ścieżka/do/paczki-TMP
Backup przed deploy
Przed KAŻDYM wgraniem — pobierz aktualną wersję z produkcji. Jeśli coś pójdzie nie tak, masz do czego wrócić.
# Utwórz katalog na backup mkdir -p back/sesja-73/ # Pobierz pliki z serwera lftp -c " open -u $USER,$PASS $HOST; cd $REMOTE; lcd back/sesja-73/; mget plik1.php plik2.php; bye; "
Dodaj back/ do .gitignore. Backupy z produkcji mogą zawierać configi z hasłami — nie powinny trafić do repozytorium. Trzymaj max 5 ostatnich sesji.
Post-deploy verify
Po wgraniu — sprawdź czy strona odpowiada:
# Sprawdź nagłówki HTTP curl -I https://twoja-strona.pl/ curl -I https://twoja-strona.pl/cennik curl -I https://twoja-strona.pl/kontakt # Oczekiwany wynik: HTTP/2 200 na każdej
Wszystkie podstrony zwracają HTTP 200? Strona wygląda poprawnie w przeglądarce? Deploy zakończony sukcesem!
Pułapki
Jeśli Twoja klasa autoryzacji ma bypass dla localhost (auto-login bez hasła w trybie dev) — NIGDY nie wgrywaj jej na produkcję! Dodaj do listy zakazanych plików w walidacji pre-deploy.
LFTP domyślnie ma krótki timeout. Ustaw set net:timeout 30 i set net:max-retries 3 — agent ponowi próbę jeśli połączenie się zerwie.