Spis treści 15 sekcji
- Kiedy migrować WordPress na AWS?
- Architektura docelowa
- Krok 1: Przygotowanie po stronie starego hostingu
- Krok 2: Przygotowanie infrastruktury AWS
- Krok 3: Import bazy danych
- Krok 4: Konfiguracja wp-config.php
- Krok 5: S3 dla mediów (obrazków)
- Krok 6: CloudFront CDN + SSL
- Krok 7: DNS migracja (Route 53)
- Krok 8: Elastic IP + finalizacja
- Checklist po migracji
- Koszty - ile zapłacisz miesięcznie?
- Optymalizacja wydajności WordPress na AWS
- FAQ - najczęstsze pytania o WordPress na AWS
- Co dalej?
Kiedy migrować WordPress na AWS?
WordPress na współdzielonym hostingu (np. nazwa.pl, OVH, Cyberfolks) ma swoje limity. Rozważ migrację na AWS gdy:
- Strona jest wolna - współdzielony hosting = współdzielone zasoby z setkami innych stron
- Potrzebujesz SSL, HTTP/2, CDN - na hostingu to często dodatek płatny lub niedostępny
- Masz spikes w ruchu - artykuł na HackerNews = hosting pada
- Chcesz pełnej kontroli - własny serwer, własna konfiguracja PHP/MySQL/Nginx
- Zależy Ci na bezpieczeństwie - izolacja, firewalle, szyfrowanie, backupy
Architektura docelowa
| Warstwa | Serwis | Rola |
|---|---|---|
| Compute | EC2 (t3.small) | Serwer PHP + Nginx |
| Baza danych | RDS MySQL (db.t3.micro) | WordPress database |
| Media / pliki | S3 | Obrazki, PDFy, uploads |
| CDN | CloudFront | Cache globalny, SSL, HTTP/2 |
| DNS | Route 53 | Zarządzanie domeną |
| SSL | ACM | Darmowy certyfikat SSL |
| Sieć | VPC | Izolacja sieciowa |
Krok 1: Przygotowanie po stronie starego hostingu
Zanim cokolwiek zrobisz na AWS, wyeksportuj dane z obecnego hostingu:
- Backup bazy danych:
# Przez phpMyAdmin: Export → Quick → Format SQL → Go # Lub przez SSH/terminal na starym hostingu: mysqldump -u wp_user -p wp_database > wordpress_backup.sql - Backup plików WordPress:
# Spakuj cały katalog WordPress cd /home/user/public_html tar -czf wordpress_files.tar.gz . - Zanotuj: wersję PHP, wersję MySQL, listę pluginów, konfigurację permalink
Krok 2: Przygotowanie infrastruktury AWS
2.1 Utwórz VPC i subnety
Dla bezpieczeństwa, RDS powinien być w prywatnym subnecie (niedostępny z internetu):
- Wejdź w VPC → Create VPC
- Wybierz VPC and more (kreator automatyczny)
- Name:
wordpress-vpc - CIDR:
10.0.0.0/16 - AZs: 2
- Public subnets: 2, Private subnets: 2
- NAT Gateway: None (oszczędność $32/mc)
- Kliknij Create VPC
# Użyj gotowego VPC z artykułu o VPC
# lub utwórz ręcznie:
aws ec2 create-vpc --cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=wordpress-vpc}]'
# Publiczne subnety (dla EC2)
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.1.0/24 --availability-zone eu-central-1a
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.2.0/24 --availability-zone eu-central-1b
# Prywatne subnety (dla RDS)
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.3.0/24 --availability-zone eu-central-1a
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.4.0/24 --availability-zone eu-central-1b
Szczegółową konfigurację VPC opisałem w poradniku VPC od podstaw.
2.2 Utwórz RDS MySQL
- Wejdź w RDS → Create database
- Engine: MySQL 8.4 (LTS - dla 8.0 od sierpnia 2026 AWS nalicza płatny Extended Support)
- Template: Free tier (db.t3.micro) lub Dev/Test
- DB identifier:
wordpress-db - Credentials: admin / silne hasło (zapisz!)
- Connectivity: Twoje VPC, prywatne subnety
- Security Group: utwórz nową, port 3306, źródło = SG instancji EC2
- Database name:
wordpress - Backup: 7 dni (domyślne, free)
# Security Group dla RDS
aws ec2 create-security-group \
--group-name wordpress-rds-sg \
--description "WordPress RDS access" \
--vpc-id vpc-xxx
# Pozwól na dostęp z EC2 SG (dodaj po utworzeniu EC2 SG)
aws ec2 authorize-security-group-ingress \
--group-id sg-rds \
--protocol tcp --port 3306 \
--source-group sg-ec2
# RDS subnet group
aws rds create-db-subnet-group \
--db-subnet-group-name wordpress-subnets \
--db-subnet-group-description "WordPress private subnets" \
--subnet-ids subnet-private-1a subnet-private-1b
# Utwórz instancję RDS
aws rds create-db-instance \
--db-instance-identifier wordpress-db \
--db-instance-class db.t3.micro \
--engine mysql --engine-version 8.4 \
--master-username admin \
--master-user-password "TwojeSilneHaslo123!" \
--allocated-storage 20 --storage-type gp3 \
--db-name wordpress \
--db-subnet-group-name wordpress-subnets \
--vpc-security-group-ids sg-rds \
--backup-retention-period 7 \
--no-publicly-accessible \
--storage-encrypted
2.3 Uruchom instancję EC2
- Wejdź w EC2 → Launch instance
- Name:
wordpress-server - AMI: Amazon Linux 2023
- Instance type: t3.small (2 vCPU, 2 GB RAM)
- Key pair: utwórz nową lub wybierz istniejącą
- Network: Twoje VPC, publiczny subnet
- Security Group: HTTP (80), HTTPS (443) z 0.0.0.0/0 + SSH (22) z Twojego IP
- Storage: 20 GB gp3
- Advanced → User data (poniżej)
# Security Group dla EC2
aws ec2 create-security-group \
--group-name wordpress-ec2-sg \
--description "WordPress EC2" \
--vpc-id vpc-xxx
aws ec2 authorize-security-group-ingress --group-id sg-ec2 \
--ip-permissions \
IpProtocol=tcp,FromPort=80,ToPort=80,IpRanges=[{CidrIp=0.0.0.0/0}] \
IpProtocol=tcp,FromPort=443,ToPort=443,IpRanges=[{CidrIp=0.0.0.0/0}] \
IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp=TWOJ.IP/32}]
# Uruchom EC2
aws ec2 run-instances \
--image-id ami-0faab6bdbac9486fb \
--instance-type t3.small \
--key-name wordpress-key \
--subnet-id subnet-public-1a \
--security-group-ids sg-ec2 \
--block-device-mappings DeviceName=/dev/xvda,Ebs={VolumeSize=20,VolumeType=gp3} \
--associate-public-ip-address \
--user-data file://wordpress-setup.sh \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=wordpress-server}]'
User Data - automatyczna instalacja LEMP + WordPress
#!/bin/bash
# wordpress-setup.sh - User Data script
# Aktualizacja systemu
dnf update -y
# Instalacja Nginx, PHP 8.2, MySQL client
dnf install -y nginx php8.2-fpm php8.2-mysqlnd php8.2-gd \
php8.2-xml php8.2-mbstring php8.2-curl php8.2-zip \
php8.2-intl php8.2-opcache mariadb105
# Konfiguracja PHP-FPM
sed -i 's/user = apache/user = nginx/' /etc/php-fpm.d/www.conf
sed -i 's/group = apache/group = nginx/' /etc/php-fpm.d/www.conf
# Konfiguracja Nginx
cat > /etc/nginx/conf.d/wordpress.conf <<'NGINX'
server {
listen 80;
server_name _;
root /var/www/wordpress;
index index.php;
client_max_body_size 64M;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
NGINX
# Pobierz WordPress
cd /tmp
curl -O https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
mv wordpress /var/www/wordpress
chown -R nginx:nginx /var/www/wordpress
# Uruchom serwisy
systemctl enable --now nginx php-fpm
echo "WordPress setup complete!"
Krok 3: Import bazy danych
# Połącz się z EC2
ssh -i wordpress-key.pem ec2-user@EC2_PUBLIC_IP
# Prześlij backup bazy
scp -i wordpress-key.pem wordpress_backup.sql ec2-user@EC2_PUBLIC_IP:/tmp/
# Zaimportuj do RDS
mysql -h wordpress-db.xxxxxxx.eu-central-1.rds.amazonaws.com \
-u admin -p wordpress < /tmp/wordpress_backup.sql
Krok 4: Konfiguracja wp-config.php
# Na instancji EC2
cd /var/www/wordpress
cp wp-config-sample.php wp-config.php
# Edytuj wp-config.php
cat > wp-config.php <<'WPCONFIG'
<?php
define('DB_NAME', 'wordpress');
define('DB_USER', 'admin');
define('DB_PASSWORD', 'TwojeSilneHaslo123!');
define('DB_HOST', 'wordpress-db.xxxxxxx.eu-central-1.rds.amazonaws.com');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
// Wygeneruj unikalne klucze: https://api.wordpress.org/secret-key/1.1/salt/
define('AUTH_KEY', 'unikalna-wartosc-1');
define('SECURE_AUTH_KEY', 'unikalna-wartosc-2');
define('LOGGED_IN_KEY', 'unikalna-wartosc-3');
define('NONCE_KEY', 'unikalna-wartosc-4');
define('AUTH_SALT', 'unikalna-wartosc-5');
define('SECURE_AUTH_SALT', 'unikalna-wartosc-6');
define('LOGGED_IN_SALT', 'unikalna-wartosc-7');
define('NONCE_SALT', 'unikalna-wartosc-8');
$table_prefix = 'wp_';
// S3 dla mediów (po instalacji pluginu WP Offload Media)
define('AS3CF_SETTINGS', serialize(array(
'provider' => 'aws',
'use-server-roles' => true,
'bucket' => 'wordpress-media-bucket',
'region' => 'eu-central-1',
'copy-to-s3' => true,
'serve-from-s3' => true,
)));
define('WP_DEBUG', false);
if (!defined('ABSPATH')) {
define('ABSPATH', __DIR__ . '/');
}
require_once ABSPATH . 'wp-settings.php';
WPCONFIG
Krok 5: S3 dla mediów (obrazków)
Trzymanie mediów na EC2 EBS to zły pomysł - ograniczony rozmiar, brak CDN, trudny backup. Przenieś media na S3:
- Utwórz bucket:
wordpress-media-twojadomena - Zainstaluj plugin WP Offload Media Lite
- Przypisz do EC2 rolę IAM z dostępem do S3
- Skonfiguruj plugin aby nowe uploady szły na S3
- Uruchom migrację istniejących mediów
# IAM policy dla EC2 → S3
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::wordpress-media-twojadomena",
"arn:aws:s3:::wordpress-media-twojadomena/*"
]
}]
}
# Przenieś istniejące media na S3
aws s3 sync /var/www/wordpress/wp-content/uploads/ \
s3://wordpress-media-twojadomena/wp-content/uploads/
Krok 6: CloudFront CDN + SSL
- Wygeneruj certyfikat SSL w ACM (us-east-1 region!) dla Twojej domeny
- Utwórz CloudFront distribution:
- Origin: publiczna nazwa DNS wskazująca na instancję EC2 - CloudFront nie przyjmuje gołego adresu IP jako origin. Przypisz Elastic IP i utwórz rekord A w Route 53 (np.
origin.twojadomena.pl), a jego nazwę podaj jako origin - Cache behavior: Cache static files (CSS/JS/images), bypass cache for PHP
- Alternate domain:
twojadomena.pl,www.twojadomena.pl - SSL: certyfikat z ACM
- Origin: publiczna nazwa DNS wskazująca na instancję EC2 - CloudFront nie przyjmuje gołego adresu IP jako origin. Przypisz Elastic IP i utwórz rekord A w Route 53 (np.
- Ustaw Route 53 ALIAS record na CloudFront distribution
# Certyfikat SSL (MUSI być w us-east-1 dla CloudFront)
aws acm request-certificate \
--domain-name twojadomena.pl \
--subject-alternative-names "*.twojadomena.pl" \
--validation-method DNS \
--region us-east-1
# Po walidacji DNS - utwórz CloudFront
# (użyj konsoli - kreator jest prostszy dla złożonej konfiguracji WP)
wordpress_logged_in. Zainstaluj plugin WP Super Cache lub W3 Total Cache dla page cache.Krok 7: DNS migracja (Route 53)
- Utwórz Hosted Zone w Route 53 dla Twojej domeny
- Zaktualizuj nameservery u rejestratora domeny na nameservery Route 53
- Dodaj rekordy:
twojadomena.pl→ ALIAS → CloudFront distributionwww.twojadomena.pl→ ALIAS → CloudFront distribution
- Poczekaj na propagację DNS (do 48h, zazwyczaj 1-2h)
Krok 8: Elastic IP + finalizacja
# Przypisz Elastic IP (stały IP, nie zmienia się przy restart)
aws ec2 allocate-address --domain vpc
aws ec2 associate-address --instance-id i-xxx --allocation-id eipalloc-xxx
# Utwórz AMI jako backup
aws ec2 create-image --instance-id i-xxx \
--name "wordpress-server-baseline-$(date +%Y%m%d)" \
--no-reboot
Checklist po migracji
- WordPress admin panel działa (/wp-admin/)
- Strony i posty wyświetlają się poprawnie
- Obrazki ładują się (z S3/CloudFront)
- SSL działa (kłódka w przeglądarce)
- Permalink structure działa (nie 404)
- Formularze kontaktowe działają
- Pluginy działają poprawnie
- Automatyczne backupy RDS włączone
- CloudWatch alarmy skonfigurowane
- Security Group SSH ograniczony do Twojego IP
Koszty - ile zapłacisz miesięcznie?
| Serwis | Mały blog (<5K wizyt/mc) | Średni serwis (50K wizyt/mc) |
|---|---|---|
| EC2 t3.micro (Free Tier - konta sprzed 15.07.2025) | $0 (1 rok) | - |
| EC2 t3.small | - | ~$15 |
| RDS db.t3.micro (Free Tier - konta sprzed 15.07.2025) | $0 (1 rok) | - |
| RDS db.t3.small | - | ~$25 |
| S3 (5 GB media) | ~$0.12 | ~$0.50 |
| CloudFront (10 GB transfer) | ~$1 | ~$5 |
| Route 53 | $0.50 | $0.50 |
| Elastic IP (publiczny IPv4, $0.005/h) | ~$3.60 | ~$3.60 |
| SUMA | ~$2/mc (Free Tier) / ~$30 (po) | ~$46/mc |
Optymalizacja wydajności WordPress na AWS
Page cache
Zainstaluj WP Super Cache lub W3 Total Cache. Generują statyczny HTML zamiast uruchamiać PHP przy każdym request. TTFB spada z 800ms do 50ms.
OPcache
# /etc/php.d/10-opcache.ini - zoptymalizuj
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.enable=1
Redis object cache
Zainstaluj ElastiCache Redis (cache.t3.micro, ~$12/mc) + plugin Redis Object Cache. Redukuje zapytania do bazy o 80%.
FAQ - najczęstsze pytania o WordPress na AWS
Czy Lightsail nie jest prostszy do WordPress?
Jak aktualizować WordPress na EC2?
Jak zabezpieczyć WordPress na AWS?
Czy mogę hostować wiele stron WordPress na jednym EC2?
Co dalej?
- Zrób backup starego hostingu (baza + pliki).
- Postaw infrastrukturę AWS według kroków wyżej.
- Zaimportuj bazę i pliki.
- Skonfiguruj CloudFront + SSL + Route 53.
- Przetestuj wszystko na nowej domenie/IP przed przełączeniem DNS.
- Przełącz DNS i monitoruj przez CloudWatch.
Więcej o najlepszych praktykach hostowania WordPress w chmurze znajdziesz w oficjalnym AWS Whitepaper: Best Practices for WordPress. Migracja WordPress na AWS to świetny projekt do nauki. Dotkniesz EC2, RDS, S3, CloudFront, VPC, Route 53, IAM - kluczowych serwisów, które pojawiają się na egzaminie Solutions Architect. Dwa w jednym: szybsza strona + wiedza o AWS.
