Jak hostuję statyczną stronę MkDocs na AWS¶
I czego uczę się przy okazji o architekturze, bezpieczeństwie i odpowiedzialności za koszty¶
Probowałem z Amazon Lightsail i Wordpress - koszty były zbyt wysokie.
Chciałem prostej przestrzeni — lekkiej, statycznej strony, którą zbuduję sam.
Inspiracja przyszła z dokumentacji FastAPI oparta o MKDocs i hostowana w pełni w AWS.
Ale to nie tylko publikacja.
To sposób na naukę.
Na zrozumienie chmury od środka - przez praktykę, decyzje, błędy i poprawki.
Co wybrałem i dlaczego?¶
Komponent | Opis |
---|---|
MkDocs | Generator statycznych stron — szybki, lekki, idealny do bloga |
AWS S3 | Przechowuje wygenerowane pliki HTML, CSS, JS |
Amazon CloudFront | Dostarcza stronę globalnie, obsługuje HTTPS + cache |
AWS Route 53 | DNS dla mojej domeny andrzejoblong.pl |
ACM (SSL) | Certyfikat SSL dla bezpieczeństwa HTTPS |
AWS WAF | Zabezpieczenie przed nadużyciami i botami |
AWS Budgets | Alerty kosztowe — by nie zaskoczył mnie rachunek |
Jak to zabezpieczyłem?¶
S3 bucket¶
- Publiczny dostęp do S3: ZABLOKOWANY !
- Bucket policy z warunkiem
AWS:SourceArn == CloudFront
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<BUCKET_ID>/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "<CLOUDFRONT_DISTRIBUTION_ARN>"
}
}
}
]
}
CloudFront¶
- OAC (Origin Access Control): tylko CloudFront może czytać pliki
- Kompresja objektów
- Redirect HTTP to HTTPS
- Dla mojej strony dopuszczam tylko GET, HEAD
- Cache Key and origin request a) CachingOptimized b) CORS-S3Origin
- TTL 24h w cache policy
- Certyfikat SSL (ACM) + domena w Route 53
- Uproszczona nawigacja dzięki CloudFront Function, która automatycznie dopisuje "index.html" do adresów bez roszerzenia.
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
Dzięki niemu mogę pisać linki /about, /docs, /blog/, a CloudFront sam znajdzie odpowiednie pliki w S3 - bez błędów.
- WAF +
Rate-based rule
Szacunkowe miesięczne koszty¶
Usługa | Koszt (USD) | Uwagi |
---|---|---|
S3 (storage) | 0.01–0.10 | Pliki statyczne |
S3 (GET requests) | 0.01–0.50 | W zależności od liczby odwiedzin |
CloudFront | 1–3 | Transfer + cache |
Route 53 | 0.50 | DNS + domena |
ACM SSL | 0.00 | Darmowy |
WAF | 5 + 1 USD/reguła/ miesięcznie | |
RAZEM | ~8 USD | Przy lekkiej stronie |
Czego się uczę dzięki temu projektowi?¶
- Projektowanie CDN + cache + dostępów
- Świadome zarządzanie kosztami
- Rozdzielenie infrastruktury i treści
- Świadomość architektury chmurowej
Moja osobista checklista¶
- S3: brak publicznego dostępu
- CloudFront: aktywne cache, SSL
- OAC: tylko CloudFront do S3
- Route 53: domena
- WAF: rate limit, bot protection
- Budgets: alert kosztowy przy 5 USD
Obsary do usprawnień¶
Wdrożenie automatyzacji¶
mkdocs build
Wygenerowane pliki trafiają do site/
Wrzucenie strony na S3:
aws s3 sync site/ s3://<BUCKET_ID>/ --delete
Inwalidacja cache w CloudFront:
aws cloudfront create-invalidation \
--distribution-id <MY_ID> \
--paths "/index.html" "/"
- skrypt do automatyzacji
- automatyzacja deploy z GitHub Actions
- Terraform do zarządzania infrastrukturą
Podsumowanie¶
Nie buduję najtaniej. Buduję świadomie. Dla siebie.
Aby się uczyć, testować, rozwijać.
To projekt, w którym dane i decyzje spotykają się z odpowiedzialnością.