Migrasi WordPress ke Docker Container
Pada tutorial sebelumnya kita telah belajar bagaimana cara install WordPress di atas Docker container. Kali ini, kita akan belajar bagaimana cara migrasi website WordPress yang sudah berjalan baik itu di shared hosting maupun di VPS ke Docker container. Pada dasarnya tool yang digunakan tetap sama yaitu Docker Compose, yang perlu ditambahkan adalah mengimpor WordPress dan database hasil backup.
Tutorial Environment
WordPress yang ingin dipindahkan:
- WordPress v5.9
- Theme Blocksy dan pluginnya
- Domain musaamin.my.id
- DNS dan SSL Cloudflare
Docker host:
- VPS Ubuntu 20.04
- Docker 20.10
- Docker Compose 2.5
- Nginx reverse proxy
WordPress Backup
Diasumsikan WordPress telah dibackup dan ditransfer ke VPS. Filenya disimpan di folder /home/user.
- Folder WordPress: /home/musa/musaamin.my.id
- File backup database: /home/musa/wp.sql
Install Requirements
Login SSH ke server lalu install Docker.
1 2 3 4 5 6 7 8 9 | sudo apt update sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io sudo usermod -aG docker $USER |
Install Docker Compose.
1 2 | sudo wget https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -O /usr/bin/docker-compose sudo chmod +x /usr/bin/docker-compose |
Install Nginx.
1 | sudo apt install nginx |
Logout dari koneksi SSH, lalu login kembali.
Setup Folder Website
Membuat folder untuk menyimpan file WordPress dan database.
1 2 3 4 | mkdir -pv ~/public_html/musaamin.my.id/src mkdir -pv ~/public_html/musaamin.my.id/database mkdir -pv ~/public_html/musaamin.my.id/database/data mkdir -pv ~/public_html/musaamin.my.id/database/initdb.d |
Copy file WordPress ke folder src.
1 2 | cp -Rv ~/musaamin.my.id/* ~/public_html/musaamin.my.id/src sudo chown -R www-data:www-data ~/public_html/musaamin.my.id/src |
Copy file .sql ke folder initdb.d.
1 | cp ~/wp.sql ~/public_html/musaamin.my.id/database/initdb.d |
Docker Compose
Membuat file docker-compose.
1 2 | cd ~/public_html/musaamin.my.id nano docker-compose.yml |
Isi dari file docker-compose.yml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | version: '3' services: musaamin_db: image: mariadb/server:10.5 container_name: musaamin_db volumes: - ./database/data:/var/lib/mysql - ./database/initdb.d:/docker-entrypoint-initdb.d restart: always environment: MYSQL_ROOT_PASSWORD: rahasia MYSQL_DATABASE: wp MYSQL_USER: wp MYSQL_PASSWORD: rahasia musaamin_site: depends_on: - musaamin_db image: wordpress:php7.4 container_name: musaamin_site ports: - "8080:80" restart: always volumes: - ./src:/var/www/html |
Yang akan dijalankan oleh docker-compose.yml yaitu:
- Membuat container dengan nama musaamin_db dari image mariadb/sever:10.5. Terdapat 2 volume, mount dari folder yang telah dibuat untuk database. Database disimpan di folder data dan folder initdb.d yang berisi file .sql yang akan diimport ketika containter dibuat. MYSQL_USERNAME, PASSWORD, dan DATABASE disesuaikan dengan yang ada di file wp-config.php, sementara untuk MYSQL_ROOT_PASSWORD bisa ditentukan sendiri.
- Membuat container dengan nama musaamin_site dari image wordpress dengan php7.4. Container ini berjalan di port 8080. Folder src yang berisi file WordPress dimount ke /var/www/html
Menjalankan docker-compose.
1 | docker-compose up -d |
Menampilkan Docker container yang sedang berjalan.
1 | docker ps |
Hasil yang ditampilkan.
1 2 3 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fdab7d39e67e wordpress:php7.4 "docker-entrypoint.s…" 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp musaamin_site b1fb65da38f5 mariadb/server:10.5 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 3306/tcp musaamin_db |
Konfigurasi Nginx
Selanjutnya melakukan konfigurasi Nginx untuk reverse proxy ke Docker containter.
Generate dhparam.pem.
1 | sudo openssl dhparam -out /etc/ssl/dhparam.pem 2048 |
Membuat file server block.
1 | sudo nano /etc/nginx/conf.d/musaamin.my.id.conf |
Isi dari file konfigurasi server block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | server { listen 443 ssl; server_name www.musaamin.my.id musaamin.my.id; ssl_certificate /etc/ssl/musaamin.my.id/musaamin.my.id-cert.pem; ssl_certificate_key /etc/ssl/musaamin.my.id/musaamin.my.id-key.pem; ssl_session_cache shared:nginx_SSL:10m; ssl_session_timeout 1440m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA"; ssl_dhparam /etc/ssl/dhparam.pem; location / { proxy_pass http://localhost:8080; proxy_set_header Accept-Encoding ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } access_log /var/log/nginx/musaamin.my.id_access.log; error_log /var/log/nginx/musaamin.my.id_error.log; } server { listen 80; server_name www.musaamin.my.id musaamin.my.id; return 301 https://www.musaamin.my.id$request_uri; } |
Konfigurasinya sama seperti dengan Nginx server block yang berjalan di port 443 (HTTPS). Pastikan sertifikat dan private key SSL sudah tersedia di server, bisa didapatkan di Cloudflare (SSL/TLS -> Origin Server -> Create Certificate). Ketika website diakses, permintaan tersebut akan diteruskan ke container yang berjalan di port 8080.
Uji konfigurasi Nginx lalu restart.
1 2 | sudo nginx -t sudo systemctl restart nginx |
Konfigurasi WordPress
Membuka file wp-config.php dengan nano.
1 | sudo nano ~/public_html/musaamin.my.id/src/wp-config.php |
Mengubah DB_HOST dari localhost menjadi nama containter, musaamin_db.
1 | define( 'DB_HOST', 'musaamin_db' ); |
Masukkan konfigurasi HTTPS berikut di atas /* That’s all, stop editing! Happy publishing. */.
1 2 3 4 | if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; } |
Membuat file .htaccess jika belum ada.
1 | sudo nano ~/public_html/musaamin.my.id/src/.htaccess |
Isi file .htaccess.
1 2 3 4 5 6 7 8 9 | <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> |
Update DNS Record
Update DNS record, ubah ke IP server Docker host.
Pengujian
Lakukan pengujian untuk memastikan semuanya sudah berfungsi dengan baik.
- Akses halaman depan
- Akses post detail
- Akses halaman dashboard
- Install theme atau plugin
- Posting artikel
Membackup Database
Membackup database yang berjalan di container.
1 | docker exec musaamin_db /usr/bin/mysqldump -u root --password=rahasia wp > ~/wp_docker.sql |
Menghapus Container
Menghapus container dengan docker-compose.
1 2 3 | cd ~/public_html/musaamin.my.id docker-compose down docker ps |
Meskipun container sudah terhapus, tetapi datanya masih tetap ada.
1 2 | ls -l ~/public_html/musaamin.my.id/src ls -l ~/public_html/musaamin.my.id/database/data |
Selamat mencoba 🙂
Halo mas mau tanya kalau semisal wp-content nya aja yang mau saya gunain buat migrate bisa engga ya ? atau harus wajib semua website di pack zip ?thanks
kalau tanpa docker, biasanya wp-content yang dicopy karena itu data usernya, sementara yang lain adalah core wordpress. silakan dicoba aja untuk mengetahui hasilnya seperti apa
Hasilnya ga muncul apa” mas, hmm mungkin akan saya coba kalau full zip semua wordpressnya , terimakasih responnya 🙂
Saya udah lakuin semua step dan berhasil tapi kenapa ya hanya bisa akses dari ip internal + dengan port saja, tapi ketika pakai URL yang saya taruh di nginx conf gabisa , padahal udah saya buatin ip public dan saya arahkan ke domain DNS management saya , itu kenapa ya mas, siapa tau ada pencerahan thanks 🙂
cek kembali konfigurasi nginx