Spis treści 15 sekcji
  1. Kiedy migrować WordPress na AWS?
  2. Architektura docelowa
  3. Krok 1: Przygotowanie po stronie starego hostingu
  4. Krok 2: Przygotowanie infrastruktury AWS
  5. Krok 3: Import bazy danych
  6. Krok 4: Konfiguracja wp-config.php
  7. Krok 5: S3 dla mediów (obrazków)
  8. Krok 6: CloudFront CDN + SSL
  9. Krok 7: DNS migracja (Route 53)
  10. Krok 8: Elastic IP + finalizacja
  11. Checklist po migracji
  12. Koszty - ile zapłacisz miesięcznie?
  13. Optymalizacja wydajności WordPress na AWS
  14. FAQ - najczęstsze pytania o WordPress na AWS
  15. Co dalej?
TL;DR: Migracja WordPress na AWS daje pełną kontrolę, lepszą wydajność i skalowalność. Najlepsza konfiguracja to EC2 (serwer) + RDS MySQL (baza) + S3 (media) + CloudFront (CDN). Koszt: od ~$30/mc za małego bloga do ~$50/mc za średni serwis. W tym artykule prowadzę przez całą migrację krok po kroku.
Dwa sposoby, ten sam efekt: Każdy krok poniżej możesz wykonać na dwa sposoby - klikając w panelu webowym AWS albo wpisując komendy w terminalu. Wybierz jedną metodę i trzymaj się jej. Jeśli dopiero zaczynasz, polecam Panel AWS.

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
Uczciwe ostrzeżenie: AWS wymaga zarządzania serwerem - warto zapoznać się z dokumentacją EC2. Jeśli nie chcesz się tym zajmować, rozważ AWS Lightsail ($5/mc; wariant $3.50/mc jest tylko IPv6) lub managed WordPress hosting (np. Kinsta, WP Engine). Jeśli chcesz się uczyć AWS - to idealny projekt!

Architektura docelowa

WarstwaSerwisRola
ComputeEC2 (t3.small)Serwer PHP + Nginx
Baza danychRDS MySQL (db.t3.micro)WordPress database
Media / plikiS3Obrazki, PDFy, uploads
CDNCloudFrontCache globalny, SSL, HTTP/2
DNSRoute 53Zarządzanie domeną
SSLACMDarmowy certyfikat SSL
SiećVPCIzolacja sieciowa

Krok 1: Przygotowanie po stronie starego hostingu

Zanim cokolwiek zrobisz na AWS, wyeksportuj dane z obecnego hostingu:

  1. 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
  2. Backup plików WordPress:
    # Spakuj cały katalog WordPress
    cd /home/user/public_html
    tar -czf wordpress_files.tar.gz .
  3. 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):

  1. Wejdź w VPC → Create VPC
  2. Wybierz VPC and more (kreator automatyczny)
  3. Name: wordpress-vpc
  4. CIDR: 10.0.0.0/16
  5. AZs: 2
  6. Public subnets: 2, Private subnets: 2
  7. NAT Gateway: None (oszczędność $32/mc)
  8. Kliknij Create VPC
Screenshot: VPC Create - kreator z 2 AZ, 2 publiczne i 2 prywatne subnety
# 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

  1. Wejdź w RDS → Create database
  2. Engine: MySQL 8.4 (LTS - dla 8.0 od sierpnia 2026 AWS nalicza płatny Extended Support)
  3. Template: Free tier (db.t3.micro) lub Dev/Test
  4. DB identifier: wordpress-db
  5. Credentials: admin / silne hasło (zapisz!)
  6. Connectivity: Twoje VPC, prywatne subnety
  7. Security Group: utwórz nową, port 3306, źródło = SG instancji EC2
  8. Database name: wordpress
  9. Backup: 7 dni (domyślne, free)
Screenshot: RDS Create - MySQL 8.0, Free tier, konfiguracja connectivity
# 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

  1. Wejdź w EC2 → Launch instance
  2. Name: wordpress-server
  3. AMI: Amazon Linux 2023
  4. Instance type: t3.small (2 vCPU, 2 GB RAM)
  5. Key pair: utwórz nową lub wybierz istniejącą
  6. Network: Twoje VPC, publiczny subnet
  7. Security Group: HTTP (80), HTTPS (443) z 0.0.0.0/0 + SSH (22) z Twojego IP
  8. Storage: 20 GB gp3
  9. 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:

  1. Utwórz bucket: wordpress-media-twojadomena
  2. Zainstaluj plugin WP Offload Media Lite
  3. Przypisz do EC2 rolę IAM z dostępem do S3
  4. Skonfiguruj plugin aby nowe uploady szły na S3
  5. 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

  1. Wygeneruj certyfikat SSL w ACM (us-east-1 region!) dla Twojej domeny
  2. 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
  3. 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)
Cache strategy dla WordPress: Cachuj agresywnie pliki statyczne (CSS, JS, obrazki - TTL 30 dni). NIE cachuj stron z /wp-admin/, /wp-login.php i requestów z cookie wordpress_logged_in. Zainstaluj plugin WP Super Cache lub W3 Total Cache dla page cache.

Krok 7: DNS migracja (Route 53)

  1. Utwórz Hosted Zone w Route 53 dla Twojej domeny
  2. Zaktualizuj nameservery u rejestratora domeny na nameservery Route 53
  3. Dodaj rekordy:
    • twojadomena.pl → ALIAS → CloudFront distribution
    • www.twojadomena.pl → ALIAS → CloudFront distribution
  4. 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?

SerwisMał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
Porównanie: Hosting współdzielony: 10-50 zł/mc. AWS z Free Tier (konta sprzed 15.07.2025): ~8 zł/mc przez pierwszy rok; nowe konta dostają zamiast tego do $200 kredytów na start (maks. 6 miesięcy). AWS bez Free Tier: ~120-185 zł/mc. AWS jest droższy, ale dostajesz: pełną kontrolę, CDN, auto-backup, szyfrowanie, izolację. Szczegóły kosztów w artykule o cenniku AWS.

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?

Tak! AWS Lightsail ($5/mc; $3.50/mc tylko w wariancie IPv6) to uproszczony interfejs z preinstalowanym WordPress. Idealne dla prostych blogów. Ale nie ma osobnej bazy RDS, zaawansowanego VPC ani łatwej integracji z innymi serwisami AWS. Jeśli chcesz się uczyć - idź w EC2+RDS. Jeśli chcesz szybko i tanio - Lightsail.

Jak aktualizować WordPress na EC2?

Normalnie przez wp-admin → Updates, jak na każdym hostingu. Przed aktualizacją: zrób snapshot EC2 i snapshot RDS. Jeśli coś pójdzie nie tak - przywracasz snapshot w 5 minut. Na współdzielonym hostingu takiej opcji nie masz.

Jak zabezpieczyć WordPress na AWS?

Poza standardowymi praktykami WP (silne hasła, 2FA, ograniczenie wp-admin), na AWS dodajesz: RDS w prywatnym subnecie, WAF przed CloudFront (blokuje boty, SQL injection), Security Group ograniczone do minimum, automatyczne backupy. Więcej w poradniku IAM.

Czy mogę hostować wiele stron WordPress na jednym EC2?

Tak, przez Nginx virtual hosts lub WordPress Multisite. Jedna instancja t3.small spokojnie obsłuży 3-5 małych stron. Ale każda strona powinna mieć osobną bazę danych w RDS dla bezpieczeństwa.

Co dalej?

  1. Zrób backup starego hostingu (baza + pliki).
  2. Postaw infrastrukturę AWS według kroków wyżej.
  3. Zaimportuj bazę i pliki.
  4. Skonfiguruj CloudFront + SSL + Route 53.
  5. Przetestuj wszystko na nowej domenie/IP przed przełączeniem DNS.
  6. 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.

Emil Kowalczyk

Pasjonat chmury i twórca CloudManiak.pl. Na co dzień MSP Engineer w amerykańskiej firmie ClearScale (AWS Premier Tier Partner). Pomagam osobom wchodzącym do świata chmury zdobywać wiedzę i certyfikaty.