{"id":41479,"date":"2026-06-03T16:10:14","date_gmt":"2026-06-03T09:10:14","guid":{"rendered":"https:\/\/interdata.vn\/blog\/?p=41479"},"modified":"2026-06-03T16:25:20","modified_gmt":"2026-06-03T09:25:20","slug":"cai-dat-wordpress-bang-docker-compose","status":"publish","type":"post","link":"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/","title":{"rendered":"H\u01b0\u1edbng D\u1eabn C\u00e1ch C\u00e0i \u0110\u1eb7t WordPress B\u1eb1ng Docker Compose (2026)"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-white ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">N\u1ed8I DUNG<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Cac-Diem-Chinh-Cua-Bai-Viet\" >C\u00e1c \u0110i\u1ec3m Ch\u00ednh C\u1ee7a B\u00e0i Vi\u1ebft:<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Yeu-Cau-Chuan-Bi\" >Y\u00eau C\u1ea7u Chu\u1ea9n B\u1ecb<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Cac-Buoc-Trien-Khai-WordPress-Voi-Docker-Compose\" >C\u00e1c B\u01b0\u1edbc Tri\u1ec3n Khai WordPress V\u1edbi Docker Compose<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Buoc-1-%E2%80%94-Dinh-Cau-Hinh-Cho-May-Chu-Web-Nginx\" >B\u01b0\u1edbc 1 \u2014 \u0110\u1ecbnh C\u1ea5u H\u00ecnh Cho M\u00e1y Ch\u1ee7 Web Nginx<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Buoc-2-%E2%80%94-Dinh-Nghia-Cac-Bien-Moi-Truong-env\" >B\u01b0\u1edbc 2 \u2014 \u0110\u1ecbnh Ngh\u0129a C\u00e1c Bi\u1ebfn M\u00f4i Tr\u01b0\u1eddng (.env)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Buoc-3-%E2%80%94-Xay-Dung-File-Docker-Compose\" >B\u01b0\u1edbc 3 \u2014 X\u00e2y D\u1ef1ng File Docker Compose<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Buoc-4-%E2%80%94-Lay-Chung-Chi-SSL-Lets-Encrypt\" >B\u01b0\u1edbc 4 \u2014 L\u1ea5y Ch\u1ee9ng Ch\u1ec9 SSL Let&#8217;s Encrypt<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Buoc-5-%E2%80%94-Cap-Nhat-Cau-Hinh-Nginx-Va-File-Compose-Cho-SSL\" >B\u01b0\u1edbc 5 \u2014 C\u1eadp Nh\u1eadt C\u1ea5u H\u00ecnh Nginx V\u00e0 File Compose Cho SSL<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Buoc-6-%E2%80%94-Hoan-Tat-Cai-Dat-WordPress-Tren-Giao-Dien-Web\" >B\u01b0\u1edbc 6 \u2014 Ho\u00e0n T\u1ea5t C\u00e0i \u0110\u1eb7t WordPress Tr\u00ean Giao Di\u1ec7n Web<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Buoc-7-%E2%80%94-Thiet-Lap-Tu-Dong-Gia-Han-SSL\" >B\u01b0\u1edbc 7 \u2014 Thi\u1ebft L\u1eadp T\u1ef1 \u0110\u1ed9ng Gia H\u1ea1n SSL<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Cac-Cau-Hoi-Thuong-Gap-FAQs\" >C\u00e1c C\u00e2u H\u1ecfi Th\u01b0\u1eddng G\u1eb7p (FAQs)<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#1-Tai-sao-toi-nen-su-dung-Docker-Compose-de-trien-khai-WordPress\" >1. T\u1ea1i sao t\u00f4i n\u00ean s\u1eed d\u1ee5ng Docker Compose \u0111\u1ec3 tri\u1ec3n khai WordPress?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#2-May-chu-web-Nginx-ket-noi-va-truyen-tin-den-WordPress-nhu-the-nao\" >2. M\u00e1y ch\u1ee7 web Nginx k\u1ebft n\u1ed1i v\u00e0 truy\u1ec1n tin \u0111\u1ebfn WordPress nh\u01b0 th\u1ebf n\u00e0o?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#3-Phuong-thuc-quan-ly-thong-tin-dang-nhap-nhay-cam-nhu-mat-khau-co-so-du-lieu-duoc-thuc-hien-the-nao-de-dam-bao-tinh-an-toan\" >3. Ph\u01b0\u01a1ng th\u1ee9c qu\u1ea3n l\u00fd th\u00f4ng tin \u0111\u0103ng nh\u1eadp nh\u1ea1y c\u1ea3m (nh\u01b0 m\u1eadt kh\u1ea9u c\u01a1 s\u1edf d\u1eef li\u1ec7u) \u0111\u01b0\u1ee3c th\u1ef1c hi\u1ec7n th\u1ebf n\u00e0o \u0111\u1ec3 \u0111\u1ea3m b\u1ea3o t\u00ednh an to\u00e0n?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#4-Quy-trinh-dang-ky-chung-chi-SSL-duoc-thuc-thi-nhu-the-nao\" >4. Quy tr\u00ecnh \u0111\u0103ng k\u00fd ch\u1ee9ng ch\u1ec9 SSL \u0111\u01b0\u1ee3c th\u1ef1c thi nh\u01b0 th\u1ebf n\u00e0o?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#5-Co-che-tu-dong-gia-han-chung-chi-SSL-hoat-dong-ra-sao\" >5. C\u01a1 ch\u1ebf t\u1ef1 \u0111\u1ed9ng gia h\u1ea1n ch\u1ee9ng ch\u1ec9 SSL ho\u1ea1t \u0111\u1ed9ng ra sao?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#6-Neu-toi-tat-hoac-khoi-dong-lai-cac-container-du-lieu-trang-web-cua-toi-co-bi-mat-khong\" >6. N\u1ebfu t\u00f4i t\u1eaft ho\u1eb7c kh\u1edfi \u0111\u1ed9ng l\u1ea1i c\u00e1c container, d\u1eef li\u1ec7u trang web c\u1ee7a t\u00f4i c\u00f3 b\u1ecb m\u1ea5t kh\u00f4ng?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#7-Tham-so-cau-hinh-bo-sung-trong-phan-dich-vu-db-co-y-nghia-gi\" >7. Tham s\u1ed1 c\u1ea5u h\u00ecnh b\u1ed5 sung trong ph\u1ea7n d\u1ecbch v\u1ee5\u00a0db\u00a0c\u00f3 \u00fd ngh\u0129a g\u00ec?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#8-Container-Nginx-lay-tep-chung-chi-SSL-tu-container-Certbot-bang-cach-nao\" >8. Container Nginx l\u1ea5y t\u1ec7p ch\u1ee9ng ch\u1ec9 SSL t\u1eeb container Certbot b\u1eb1ng c\u00e1ch n\u00e0o?<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/interdata.vn\/blog\/cai-dat-wordpress-bang-docker-compose\/#Loi-Ket\" >L\u1eddi K\u1ebft<\/a><\/li><\/ul><\/nav><\/div>\n<p><a href=\"https:\/\/wordpress.org\/\" target=\"_blank\" rel=\"nofollow noopener\">WordPress<\/a>\u00a0l\u00e0 m\u1ed9t h\u1ec7 qu\u1ea3n tr\u1ecb n\u1ed9i dung (CMS) m\u00e3 ngu\u1ed3n m\u1edf ho\u00e0n to\u00e0n mi\u1ec5n ph\u00ed, \u0111\u01b0\u1ee3c x\u00e2y d\u1ef1ng tr\u00ean n\u1ec1n t\u1ea3ng c\u01a1 s\u1edf d\u1eef li\u1ec7u MySQL v\u00e0 ng\u00f4n ng\u1eef l\u1eadp tr\u00ecnh PHP. Nh\u1edd h\u1ec7 th\u1ed1ng plugin phong ph\u00fa v\u00e0 kho giao di\u1ec7n (template) \u0111a d\u1ea1ng, h\u1ea7u h\u1ebft c\u00e1c t\u00e1c v\u1ee5 qu\u1ea3n tr\u1ecb website \u0111\u1ec1u c\u00f3 th\u1ec3 th\u1ef1c hi\u1ec7n d\u1ec5 d\u00e0ng qua giao di\u1ec7n web. \u0110\u00e2y c\u0169ng l\u00e0 l\u00fd do t\u1ea1i sao WordPress lu\u00f4n l\u00e0 l\u1ef1a ch\u1ecdn h\u00e0ng \u0111\u1ea7u khi x\u00e2y d\u1ef1ng c\u00e1c lo\u1ea1i trang web, t\u1eeb blog c\u00e1 nh\u00e2n, trang gi\u1edbi thi\u1ec7u s\u1ea3n ph\u1ea9m cho \u0111\u1ebfn c\u00e1c h\u1ec7 th\u1ed1ng th\u01b0\u01a1ng m\u1ea1i \u0111i\u1ec7n t\u1eed (eCommerce) quy m\u00f4.<\/p>\n<p>Th\u00f4ng th\u01b0\u1eddng, vi\u1ec7c v\u1eadn h\u00e0nh WordPress \u0111\u00f2i h\u1ecfi b\u1ea1n ph\u1ea3i c\u00e0i \u0111\u1eb7t th\u1ee7 c\u00f4ng m\u1ed9t b\u1ed9 c\u00f4ng c\u1ee5 LAMP (Linux, Apache, MySQL, PHP) ho\u1eb7c LEMP (Linux, Nginx, MySQL, PHP), \u0111i\u1ec1u n\u00e0y kh\u00e1 t\u1ed1n th\u1eddi gian v\u00e0 d\u1ec5 ph\u00e1t sinh l\u1ed7i c\u1ea5u h\u00ecnh. Tuy nhi\u00ean, b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng c\u00e1c c\u00f4ng c\u1ee5 hi\u1ec7n \u0111\u1ea1i nh\u01b0\u00a0<strong>Docker<\/strong>\u00a0v\u00e0\u00a0<strong>Docker Compose<\/strong>, b\u1ea1n c\u00f3 th\u1ec3 tinh gi\u1ea3n to\u00e0n b\u1ed9 qu\u00e1 tr\u00ecnh thi\u1ebft l\u1eadp m\u00f4i tr\u01b0\u1eddng n\u00e0y. Thay v\u00ec c\u00e0i \u0111\u1eb7t t\u1eebng th\u00e0nh ph\u1ea7n ri\u00eang l\u1ebb, ch\u00fang ta s\u1eed d\u1ee5ng c\u00e1c\u00a0<strong>image<\/strong>\u00a0(h\u00ecnh \u1ea3nh \u0111\u00f3ng g\u00f3i s\u1eb5n th\u01b0 vi\u1ec7n, t\u1ec7p c\u1ea5u h\u00ecnh v\u00e0 bi\u1ebfn m\u00f4i tr\u01b0\u1eddng) \u0111\u1ec3 ch\u1ea1y trong c\u00e1c\u00a0<strong>container<\/strong>\u00a0(c\u00e1c ti\u1ebfn tr\u00ecnh \u0111\u1ed9c l\u1eadp ho\u1ea1t \u0111\u1ed9ng tr\u00ean c\u00f9ng m\u1ed9t h\u1ec7 \u0111i\u1ec1u h\u00e0nh m\u00e1y ch\u1ee7). Th\u00eam v\u00e0o \u0111\u00f3, Docker Compose s\u1ebd gi\u00fap b\u1ea1n \u0111i\u1ec1u ph\u1ed1i nhi\u1ec1u container \u2014 v\u00ed d\u1ee5 nh\u01b0 container \u1ee9ng d\u1ee5ng v\u00e0 container c\u01a1 s\u1edf d\u1eef li\u1ec7u \u2014 \u0111\u1ec3 ch\u00fang giao ti\u1ebfp tr\u1ef1c ti\u1ebfp v\u1edbi nhau m\u1ed9t c\u00e1ch an to\u00e0n.<\/p>\n<p>Trong b\u00e0i vi\u1ebft n\u00e0y, <a href=\"https:\/\/interdata.vn\/\" target=\"_blank\" rel=\"noopener\"><strong>InterData<\/strong><\/a> s\u1ebd h\u01b0\u1edbng d\u1eabn b\u1ea1n c\u00e1ch x\u00e2y d\u1ef1ng m\u1ed9t h\u1ec7 th\u1ed1ng WordPress \u0111a container. C\u00e1c container c\u1ee7a b\u1ea1n s\u1ebd bao g\u1ed3m c\u01a1 s\u1edf d\u1eef li\u1ec7u MySQL, m\u00e1y ch\u1ee7 web Nginx v\u00e0 ch\u00ednh m\u00e3 ngu\u1ed3n WordPress. Ngo\u00e0i ra, ch\u00fang ta c\u0169ng s\u1ebd b\u1ea3o m\u1eadt h\u1ec7 th\u1ed1ng b\u1eb1ng c\u00e1ch c\u00e0i \u0111\u1eb7t ch\u1ee9ng ch\u1ec9 TLS\/SSL mi\u1ec5n ph\u00ed t\u1eeb Let\u2019s Encrypt th\u00f4ng qua c\u00f4ng c\u1ee5 Certbot, \u0111\u1ed3ng th\u1eddi thi\u1ebft l\u1eadp m\u1ed9t t\u00e1c v\u1ee5 t\u1ef1 \u0111\u1ed9ng (cron job) \u0111\u1ec3 gia h\u1ea1n ch\u1ee9ng ch\u1ec9 tr\u01b0\u1edbc khi h\u1ebft h\u1ea1n.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-41481\" src=\"https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2026\/06\/Cach-Cai-Dat-WordPress-Bang-Docker-Compose.jpg\" alt=\"C\u00e1ch C\u00e0i \u0110\u1eb7t WordPress B\u1eb1ng Docker Compose\" width=\"700\" height=\"467\" title=\"\" srcset=\"https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2026\/06\/Cach-Cai-Dat-WordPress-Bang-Docker-Compose.jpg 1000w, https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2026\/06\/Cach-Cai-Dat-WordPress-Bang-Docker-Compose-300x200.jpg 300w, https:\/\/interdata.vn\/blog\/wp-content\/uploads\/2026\/06\/Cach-Cai-Dat-WordPress-Bang-Docker-Compose-768x512.jpg 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Cac-Diem-Chinh-Cua-Bai-Viet\"><\/span>C\u00e1c \u0110i\u1ec3m Ch\u00ednh C\u1ee7a B\u00e0i Vi\u1ebft:<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><strong>Docker Compose t\u1ed1i \u01b0u h\u00f3a quy tr\u00ecnh tri\u1ec3n khai<\/strong>: Lo\u1ea1i b\u1ecf vi\u1ec7c c\u00e0i \u0111\u1eb7t th\u1ee7 c\u00f4ng b\u1ed9 c\u00f4ng c\u1ee5 LAMP\/LEMP ph\u1ee9c t\u1ea1p.<\/li>\n<li><strong>M\u00f4 h\u00ecnh 4 d\u1ecbch v\u1ee5 \u0111\u1ed9c l\u1eadp ph\u1ed1i h\u1ee3p ch\u1eb7t ch\u1ebd<\/strong>: G\u1ed3m c\u01a1 s\u1edf d\u1eef li\u1ec7u MySQL, \u1ee9ng d\u1ee5ng WordPress (s\u1eed d\u1ee5ng PHP-FPM), m\u00e1y ch\u1ee7 web Nginx v\u00e0 Certbot qu\u1ea3n l\u00fd ch\u1ee9ng ch\u1ec9 SSL.<\/li>\n<li><strong>B\u1ea3o m\u1eadt th\u00f4ng tin \u0111\u0103ng nh\u1eadp<\/strong>: C\u00e1c th\u00f4ng tin nh\u1ea1y c\u1ea3m nh\u01b0 m\u1eadt kh\u1ea9u root MySQL, t\u00e0i kho\u1ea3n\/m\u1eadt kh\u1ea9u c\u01a1 s\u1edf d\u1eef li\u1ec7u \u0111\u01b0\u1ee3c l\u01b0u tr\u1eef an to\u00e0n trong t\u1ec7p\u00a0<code>.env<\/code>\u00a0v\u00e0 \u0111\u01b0\u1ee3c lo\u1ea1i tr\u1eeb kh\u1ecfi h\u1ec7 th\u1ed1ng ki\u1ec3m so\u00e1t phi\u00ean b\u1ea3n (nh\u01b0 Git) b\u1eb1ng t\u1ec7p\u00a0<code>.gitignore<\/code>\u00a0v\u00e0\u00a0<code>.dockerignore<\/code>.<\/li>\n<li><strong>S\u1eed d\u1ee5ng ch\u1ee9ng ch\u1ec9 SSL Let&#8217;s Encrypt mi\u1ec5n ph\u00ed<\/strong>: S\u1eed d\u1ee5ng c\u01a1 ch\u1ebf ki\u1ec3m th\u1ef1c t\u00ean mi\u1ec1n th\u00f4ng qua plugin webroot c\u1ee7a Certbot, b\u1eaft \u0111\u1ea7u v\u1edbi ch\u1ee9ng ch\u1ec9 th\u1eed nghi\u1ec7m (staging) tr\u01b0\u1edbc khi c\u1ea5p ch\u1ee9ng ch\u1ec9 ch\u00ednh th\u1ee9c (production).<\/li>\n<li><strong>\u0110\u1ea3m b\u1ea3o t\u00ednh to\u00e0n v\u1eb9n d\u1eef li\u1ec7u qua Docker Volumes<\/strong>: S\u1eed d\u1ee5ng c\u00e1c volume t\u0129nh (<code>dbdata<\/code>,\u00a0<code>wordpress<\/code>,\u00a0<code>certbot-etc<\/code>) \u0111\u1ec3 l\u01b0u tr\u1eef d\u1eef li\u1ec7u tr\u00ean \u1ed5 \u0111\u0129a v\u1eadt l\u00fd c\u1ee7a m\u00e1y ch\u1ee7, gi\u00fap d\u1eef li\u1ec7u kh\u00f4ng b\u1ecb m\u1ea5t ngay c\u1ea3 khi container b\u1ecb kh\u1edfi \u0111\u1ed9ng l\u1ea1i ho\u1eb7c x\u00f3a b\u1ecf.<\/li>\n<li><strong>C\u1ea5u h\u00ecnh Nginx t\u1ed1i \u01b0u cho WordPress<\/strong>: Thi\u1ebft l\u1eadp x\u1eed l\u00fd PHP qua FastCGI, l\u01b0u b\u1ed9 nh\u1edb \u0111\u1ec7m (caching) cho t\u00e0i nguy\u00ean t\u0129nh, \u00e1p d\u1ee5ng c\u00e1c ti\u00eau chu\u1ea9n b\u1ea3o m\u1eadt (X-Frame-Options, Content-Security-Policy) v\u00e0 t\u1ef1 \u0111\u1ed9ng chuy\u1ec3n h\u01b0\u1edbng HTTP sang HTTPS.<\/li>\n<li><strong>Giao ti\u1ebfp n\u1ed9i b\u1ed9 an to\u00e0n<\/strong>: T\u1ea5t c\u1ea3 c\u00e1c container k\u1ebft n\u1ed1i chung qua m\u1ed9t m\u1ea1ng c\u1ea7u n\u1ed9i b\u1ed9 t\u1ef1 \u0111\u1ecbnh ngh\u0129a (<code>app-network<\/code>), ch\u1ec9 m\u1edf c\u1ed5ng c\u00f4ng khai 80 v\u00e0 443 ra m\u00f4i tr\u01b0\u1eddng ngo\u00e0i.<\/li>\n<li><strong>T\u1ef1 \u0111\u1ed9ng gia h\u1ea1n SSL kh\u00f4ng g\u00e2y gi\u00e1n \u0111o\u1ea1n<\/strong>: S\u1eed d\u1ee5ng m\u1ed9t t\u1eadp l\u1ec7nh shell k\u1ebft h\u1ee3p cron job \u0111\u1ec3 ch\u1ea1y l\u1ec7nh\u00a0<code>certbot renew<\/code>, sau \u0111\u00f3 y\u00eau c\u1ea7u Nginx t\u1ea3i l\u1ea1i c\u1ea5u h\u00ecnh (reload) m\u1ed9t c\u00e1ch m\u01b0\u1ee3t m\u00e0.<\/li>\n<\/ul>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Yeu-Cau-Chuan-Bi\"><\/span>Y\u00eau C\u1ea7u Chu\u1ea9n B\u1ecb<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0110\u1ec3 th\u1ef1c hi\u1ec7n th\u00e0nh c\u00f4ng h\u01b0\u1edbng d\u1eabn n\u00e0y, qu\u00fd kh\u00e1ch c\u1ea7n chu\u1ea9n b\u1ecb:<\/p>\n<ul>\n<li>M\u1ed9t m\u00e1y ch\u1ee7 s\u1eed d\u1ee5ng h\u1ec7 \u0111i\u1ec1u h\u00e0nh Ubuntu phi\u00ean b\u1ea3n m\u1edbi (khuy\u1ebfn kh\u00edch c\u00e1c phi\u00ean b\u1ea3n LTS \u0111\u01b0\u1ee3c h\u1ed7 tr\u1ee3 l\u00e2u d\u00e0i). N\u1ebfu qu\u00fd kh\u00e1ch ch\u01b0a c\u00f3 m\u00e1y ch\u1ee7 ho\u1eb7c \u0111ang t\u00ecm ki\u1ebfm m\u1ed9t gi\u1ea3i ph\u00e1p l\u01b0u tr\u1eef m\u1ea1nh m\u1ebd, h\u00e3y tham kh\u1ea3o ngay d\u1ecbch v\u1ee5\u00a0<a href=\"https:\/\/interdata.vn\/thue-vps\/\" target=\"_blank\" rel=\"noopener\"><strong>Thu\u00ea VPS gi\u00e1 r\u1ebb<\/strong><\/a> c\u1ee7a InterData. C\u00e1c g\u00f3i VPS t\u1ea1i InterData \u0111\u01b0\u1ee3c t\u1ed1i \u01b0u h\u00f3a to\u00e0n di\u1ec7n v\u1ec1 hi\u1ec7u n\u0103ng ph\u1ea7n c\u1ee9ng, trang b\u1ecb \u1ed5 c\u1ee9ng NVMe U.2 si\u00eau t\u1ed1c v\u00e0 cung c\u1ea5p \u0111\u1ecba ch\u1ec9 IP t\u0129nh ri\u00eang bi\u1ec7t, c\u1ef1c k\u1ef3 ph\u00f9 h\u1ee3p \u0111\u1ec3 tri\u1ec3n khai c\u00e1c \u1ee9ng d\u1ee5ng Docker.<\/li>\n<li>Docker \u0111\u00e3 \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t tr\u00ean m\u00e1y ch\u1ee7 Ubuntu.<\/li>\n<li>Docker Compose \u0111\u00e3 \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t tr\u00ean m\u00e1y ch\u1ee7.<\/li>\n<li>M\u1ed9t t\u00ean mi\u1ec1n (domain) \u0111\u00e3 \u0111\u0103ng k\u00fd. Trong b\u00e0i vi\u1ebft n\u00e0y, ch\u00fang t\u00f4i s\u1ebd s\u1eed d\u1ee5ng m\u1eabu l\u00e0\u00a0<code>your_domain<\/code>\u00a0(qu\u00fd kh\u00e1ch c\u1ea7n thay th\u1ebf b\u1eb1ng t\u00ean mi\u1ec1n th\u1ef1c t\u1ebf c\u1ee7a m\u00ecnh).<\/li>\n<li>Hai b\u1ea3n ghi DNS (A record) \u0111\u00e3 tr\u1ecf v\u1ec1 \u0111\u1ecba ch\u1ec9 IP c\u00f4ng khai c\u1ee7a m\u00e1y ch\u1ee7 VPS:\n<ul>\n<li>B\u1ea3n ghi A v\u1edbi t\u00ean mi\u1ec1n g\u1ed1c (<code>your_domain<\/code>) tr\u1ecf v\u1ec1 IP m\u00e1y ch\u1ee7.<\/li>\n<li>B\u1ea3n ghi A v\u1edbi ti\u1ec1n t\u1ed1\u00a0<code>www<\/code>\u00a0(<code>www.your_domain<\/code>) tr\u1ecf v\u1ec1 IP m\u00e1y ch\u1ee7.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Khi m\u1ecdi \u0111i\u1ec1u ki\u1ec7n chu\u1ea9n b\u1ecb \u0111\u00e3 ho\u00e0n t\u1ea5t, ch\u00fang ta c\u00f3 th\u1ec3 b\u1eaft \u0111\u1ea7u b\u01b0\u1edbc \u0111\u1ea7u ti\u00ean.<\/p>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Cac-Buoc-Trien-Khai-WordPress-Voi-Docker-Compose\"><\/span>C\u00e1c B\u01b0\u1edbc Tri\u1ec3n Khai WordPress V\u1edbi Docker Compose<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ol>\n<li>\u0110\u1ecbnh C\u1ea5u H\u00ecnh Cho M\u00e1y Ch\u1ee7 Web Nginx<\/li>\n<li>\u0110\u1ecbnh Ngh\u0129a C\u00e1c Bi\u1ebfn M\u00f4i Tr\u01b0\u1eddng (.env)<\/li>\n<li>X\u00e2y D\u1ef1ng File Docker Compose<\/li>\n<li>L\u1ea5y Ch\u1ee9ng Ch\u1ec9 SSL Let&#8217;s Encrypt<\/li>\n<li>C\u1eadp Nh\u1eadt C\u1ea5u H\u00ecnh Nginx V\u00e0 File Compose Cho SSL<\/li>\n<li>Ho\u00e0n T\u1ea5t C\u00e0i \u0110\u1eb7t WordPress Tr\u00ean Giao Di\u1ec7n Web<\/li>\n<li>Thi\u1ebft L\u1eadp T\u1ef1 \u0110\u1ed9ng Gia H\u1ea1n SSL<\/li>\n<\/ol>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Buoc-1-%E2%80%94-Dinh-Cau-Hinh-Cho-May-Chu-Web-Nginx\"><\/span>B\u01b0\u1edbc 1 \u2014 \u0110\u1ecbnh C\u1ea5u H\u00ecnh Cho M\u00e1y Ch\u1ee7 Web Nginx<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Tr\u01b0\u1edbc khi k\u00edch ho\u1ea1t c\u00e1c container, c\u00f4ng vi\u1ec7c \u0111\u1ea7u ti\u00ean c\u1ea7n l\u00e0m l\u00e0 thi\u1ebft l\u1eadp t\u1ec7p c\u1ea5u h\u00ecnh cho m\u00e1y ch\u1ee7 web Nginx. T\u1ec7p n\u00e0y s\u1ebd ch\u1ee9a c\u00e1c ch\u1ec9 th\u1ecb \u0111\u1ecbnh tuy\u1ebfn ri\u00eang cho WordPress, \u0111\u1ed3ng th\u1eddi m\u1edf m\u1ed9t l\u1ed1i d\u1eabn \u0111\u1ec3 Certbot c\u00f3 th\u1ec3 t\u01b0\u01a1ng t\u00e1c v\u00e0 x\u00e1c th\u1ef1c t\u00ean mi\u1ec1n khi g\u1eedi y\u00eau c\u1ea7u c\u1ea5p ch\u1ee9ng ch\u1ec9 SSL.<\/p>\n<p>\u0110\u1ea7u ti\u00ean, h\u00e3y t\u1ea1o m\u1ed9t th\u01b0 m\u1ee5c ch\u1ee9a d\u1ef1 \u00e1n. Ch\u00fang t\u00f4i \u0111\u1eb7t t\u00ean th\u01b0 m\u1ee5c n\u00e0y l\u00e0\u00a0<code>wordpress<\/code>:<\/p>\n<pre><code class=\"language-bash\">mkdir wordpress\r\ncd wordpress\r\n<\/code><\/pre>\n<p>Ti\u1ebfp theo, t\u1ea1o th\u01b0 m\u1ee5c \u0111\u1ec3 l\u01b0u tr\u1eef t\u1ec7p c\u1ea5u h\u00ecnh c\u1ee7a Nginx:<\/p>\n<pre><code class=\"language-bash\">mkdir nginx-conf\r\n<\/code><\/pre>\n<p>M\u1edf m\u1ed9t t\u1ec7p m\u1edbi c\u00f3 t\u00ean\u00a0<code>nginx.conf<\/code>\u00a0b\u1eb1ng c\u00f4ng c\u1ee5 so\u1ea1n th\u1ea3o v\u0103n b\u1ea3n\u00a0<code>nano<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano nginx-conf\/nginx.conf\r\n<\/code><\/pre>\n<p>Qu\u00fd kh\u00e1ch h\u00e3y sao ch\u00e9p v\u00e0 d\u00e1n \u0111o\u1ea1n m\u00e3 c\u1ea5u h\u00ecnh d\u01b0\u1edbi \u0111\u00e2y v\u00e0o t\u1ec7p. L\u01b0u \u00fd thay th\u1ebf t\u1ea5t c\u1ea3 c\u00e1c gi\u00e1 tr\u1ecb\u00a0<code>your_domain<\/code>\u00a0b\u1eb1ng t\u00ean mi\u1ec1n ch\u00ednh th\u1ee9c c\u1ee7a qu\u00fd kh\u00e1ch:<\/p>\n<pre><code class=\"language-nginx\">server {\r\n        listen 80;\r\n        listen [::]:80;\r\n\r\n        server_name your_domain www.your_domain;\r\n\r\n        index index.php index.html index.htm;\r\n\r\n        root \/var\/www\/html;\r\n\r\n        location ~ \/.well-known\/acme-challenge {\r\n                allow all;\r\n                root \/var\/www\/html;\r\n        }\r\n\r\n        location \/ {\r\n                try_files $uri $uri\/ \/index.php$is_args$args;\r\n        }\r\n\r\n        location ~ \\.php$ {\r\n                try_files $uri =404;\r\n                fastcgi_split_path_info ^(.+\\.php)(\/.+)$;\r\n                fastcgi_pass wordpress:9000;\r\n                fastcgi_index index.php;\r\n                include fastcgi_params;\r\n                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\r\n                fastcgi_param PATH_INFO $fastcgi_path_info;\r\n        }\r\n\r\n        location ~ \/\\.ht {\r\n                deny all;\r\n        }\r\n\r\n        location = \/favicon.ico {\r\n                log_not_found off; access_log off;\r\n        }\r\n        location = \/robots.txt {\r\n                log_not_found off; access_log off; allow all;\r\n        }\r\n        location ~* \\.(css|gif|ico|jpeg|jpg|js|png)$ {\r\n                expires max;\r\n                log_not_found off;\r\n        }\r\n}\r\n<\/code><\/pre>\n<p><strong>Gi\u1ea3i th\u00edch c\u00e1c th\u00e0nh ph\u1ea7n c\u1ea5u h\u00ecnh ch\u00ednh:<\/strong><\/p>\n<ul>\n<li><strong>Ch\u1ec9 th\u1ecb (Directives)<\/strong>:\n<ul>\n<li><code>listen<\/code>: Thi\u1ebft l\u1eadp Nginx l\u1eafng nghe \u1edf c\u1ed5ng\u00a0<code>80<\/code>\u00a0nh\u1eb1m \u0111\u00e1p \u1ee9ng y\u00eau c\u1ea7u x\u00e1c th\u1ef1c qua HTTP c\u1ee7a plugin webroot thu\u1ed9c Certbot. \u1ede giai \u0111o\u1ea1n n\u00e0y, ch\u00fang ta ch\u01b0a \u0111\u1ecbnh ngh\u0129a c\u1ed5ng\u00a0<code>443<\/code>\u00a0v\u00ec ch\u01b0a c\u00f3 ch\u1ee9ng ch\u1ec9 SSL th\u1ef1c t\u1ebf.<\/li>\n<li><code>server_name<\/code>: Khai b\u00e1o t\u00ean mi\u1ec1n h\u1ec7 th\u1ed1ng s\u1ebd \u0111\u00f3n nh\u1eadn c\u00e1c y\u00eau c\u1ea7u truy c\u1eadp g\u1eedi t\u1edbi.<\/li>\n<li><code>index<\/code>: Th\u1ee9 t\u1ef1 \u01b0u ti\u00ean c\u00e1c t\u1ec7p tin \u0111\u00f3ng vai tr\u00f2 l\u00e0 trang ch\u1ee7 c\u1ee7a h\u1ec7 th\u1ed1ng. \u1ede \u0111\u00e2y ch\u00fang t\u00f4i \u01b0u ti\u00ean \u0111\u1eb7t\u00a0<code>index.php<\/code>\u00a0l\u00ean tr\u01b0\u1edbc\u00a0<code>index.html<\/code>.<\/li>\n<li><code>root<\/code>: \u0110\u01b0\u1eddng d\u1eabn th\u01b0 m\u1ee5c g\u1ed1c ch\u1ee9a m\u00e3 ngu\u1ed3n tr\u00ean m\u00e1y ch\u1ee7. Gi\u00e1 tr\u1ecb\u00a0<code>\/var\/www\/html<\/code>\u00a0l\u00e0 th\u01b0 m\u1ee5c \u0111\u00edch m\u1eb7c \u0111\u1ecbnh m\u00e0 Docker image WordPress s\u1eed d\u1ee5ng \u0111\u1ec3 ch\u1ee9a m\u00e3 ngu\u1ed3n.<\/li>\n<\/ul>\n<\/li>\n<li><strong>C\u00e1c kh\u1ed1i \u0111\u1ecbnh tuy\u1ebfn (Location Blocks)<\/strong>:\n<ul>\n<li><code>location ~ \/.well-known\/acme-challenge<\/code>: \u0110\u00e2y l\u00e0 n\u01a1i ti\u1ebfp nh\u1eadn c\u00e1c y\u00eau c\u1ea7u t\u1eeb Let&#8217;s Encrypt \u0111\u1ec3 ki\u1ec3m tra xem t\u00ean mi\u1ec1n c\u1ee7a qu\u00fd kh\u00e1ch c\u00f3 th\u1ef1c s\u1ef1 tr\u1ecf \u0111\u00fang v\u1ec1 \u0111\u1ecba ch\u1ec9 IP c\u1ee7a VPS hay kh\u00f4ng.<\/li>\n<li><code>location \/<\/code>: S\u1eed d\u1ee5ng ch\u1ec9 th\u1ecb\u00a0<code>try_files<\/code>\u00a0\u0111\u1ec3 ki\u1ec3m tra s\u1ef1 t\u1ed3n t\u1ea1i c\u1ee7a t\u1ec7p tin hay th\u01b0 m\u1ee5c \u0111\u01b0\u1ee3c y\u00eau c\u1ea7u. N\u1ebfu kh\u00f4ng t\u00ecm th\u1ea5y, h\u1ec7 th\u1ed1ng s\u1ebd t\u1ef1 \u0111\u1ed9ng chuy\u1ec3n ti\u1ebfp y\u00eau c\u1ea7u \u0111\u1ebfn t\u1ec7p\u00a0<code>index.php<\/code>\u00a0k\u00e8m theo c\u00e1c tham s\u1ed1 g\u1ed1c thay v\u00ec hi\u1ec3n th\u1ecb l\u1ed7i 404.<\/li>\n<li><code>location ~ \\.php$<\/code>: Ti\u1ebfp nh\u1eadn v\u00e0 x\u1eed l\u00fd c\u00e1c y\u00eau c\u1ea7u ch\u1ea1y t\u1ec7p tin PHP, chuy\u1ec3n giao cho ti\u1ebfn tr\u00ecnh\u00a0<code>php-fpm<\/code>\u00a0ho\u1ea1t \u0111\u1ed9ng t\u1ea1i c\u1ed5ng\u00a0<code>9000<\/code>\u00a0b\u00ean trong container\u00a0<code>wordpress<\/code>.<\/li>\n<li><code>location ~ \/\\.ht<\/code>: Ng\u0103n ch\u1eb7n tuy\u1ec7t \u0111\u1ed1i vi\u1ec7c truy c\u1eadp v\u00e0 t\u1ea3i xu\u1ed1ng c\u00e1c t\u1ec7p tin c\u1ea5u h\u00ecnh nh\u1ea1y c\u1ea3m nh\u01b0\u00a0<code>.htaccess<\/code>.<\/li>\n<li>Kh\u1ed1i x\u1eed l\u00fd h\u00ecnh \u1ea3nh v\u00e0 t\u00e0i nguy\u00ean t\u0129nh gi\u00fap t\u1eaft vi\u1ec7c ghi nh\u1eadt k\u00fd (log) kh\u00f4ng c\u1ea7n thi\u1ebft v\u00e0 thi\u1ebft l\u1eadp th\u1eddi gian l\u01b0u b\u1ed9 nh\u1edb \u0111\u1ec7m (cache) d\u00e0i h\u1ea1n nh\u1eb1m t\u1ed1i \u01b0u h\u00f3a t\u1ed1c \u0111\u1ed9 t\u1ea3i trang.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Nh\u1ea5n t\u1ed5 h\u1ee3p ph\u00edm\u00a0<code>CTRL+X<\/code>, ch\u1ecdn\u00a0<code>Y<\/code>, r\u1ed3i g\u00f5\u00a0<code>ENTER<\/code>\u00a0\u0111\u1ec3 l\u01b0u l\u1ea1i v\u00e0 \u0111\u00f3ng t\u1ec7p c\u1ea5u h\u00ecnh.<\/p>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Buoc-2-%E2%80%94-Dinh-Nghia-Cac-Bien-Moi-Truong-env\"><\/span>B\u01b0\u1edbc 2 \u2014 \u0110\u1ecbnh Ngh\u0129a C\u00e1c Bi\u1ebfn M\u00f4i Tr\u01b0\u1eddng (.env)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>H\u1ec7 qu\u1ea3n tr\u1ecb c\u01a1 s\u1edf d\u1eef li\u1ec7u v\u00e0 \u1ee9ng d\u1ee5ng WordPress c\u1ea7n c\u00e1c th\u00f4ng tin k\u1ebft n\u1ed1i \u0111\u1ec3 c\u00f3 th\u1ec3 kh\u1edfi ch\u1ea1y v\u00e0 l\u01b0u tr\u1eef d\u1eef li\u1ec7u l\u00e2u d\u00e0i. \u0110\u1ec3 tr\u00e1nh vi\u1ec7c \u0111\u1ec3 l\u1ed9 c\u00e1c th\u00f4ng tin \u0111\u0103ng nh\u1eadp quan tr\u1ecdng (nh\u01b0 m\u1eadt kh\u1ea9u qu\u1ea3n tr\u1ecb database) khi chia s\u1ebb d\u1ef1 \u00e1n l\u00ean c\u00e1c kho l\u01b0u tr\u1eef tr\u1ef1c tuy\u1ebfn (nh\u01b0 GitHub), c\u00e1ch an to\u00e0n nh\u1ea5t l\u00e0 s\u1eed d\u1ee5ng m\u1ed9t t\u1ec7p ch\u1ee9a c\u00e1c bi\u1ebfn m\u00f4i tr\u01b0\u1eddng ri\u00eang bi\u1ec7t c\u00f3 t\u00ean\u00a0<code>.env<\/code>.<\/p>\n<p>T\u1ea1i th\u01b0 m\u1ee5c l\u00e0m vi\u1ec7c ch\u00ednh (<code>~\/wordpress<\/code>), h\u00e3y t\u1ea1o t\u1ec7p\u00a0<code>.env<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano .env\r\n<\/code><\/pre>\n<p>Th\u00eam c\u00e1c kh\u00f3a v\u00e0 gi\u00e1 tr\u1ecb m\u1eadt kh\u1ea9u c\u1ee7a qu\u00fd kh\u00e1ch v\u00e0o t\u1ec7p n\u00e0y (qu\u00fd kh\u00e1ch h\u00e3y thay \u0111\u1ed5i c\u00e1c gi\u00e1 tr\u1ecb m\u1eadt kh\u1ea9u m\u1eabu d\u01b0\u1edbi \u0111\u00e2y b\u1eb1ng c\u00e1c chu\u1ed7i b\u1ea3o m\u1eadt ph\u1ee9c t\u1ea1p h\u01a1n):<\/p>\n<pre><code class=\"language-ini\">MYSQL_ROOT_PASSWORD=your_root_password\r\nMYSQL_USER=your_wordpress_database_user\r\nMYSQL_PASSWORD=your_wordpress_database_password\r\n<\/code><\/pre>\n<p>L\u01b0u v\u00e0 \u0111\u00f3ng t\u1ec7p.<\/p>\n<p>\u0110\u1ec3 \u0111\u1ea3m b\u1ea3o t\u1ec7p\u00a0<code>.env<\/code>\u00a0kh\u00f4ng b\u1ecb \u0111\u1ea9y l\u00ean Git ho\u1eb7c Docker container m\u1ed9t c\u00e1ch ngo\u00e0i \u00fd mu\u1ed1n, h\u00e3y c\u1ea5u h\u00ecnh c\u00e1c t\u1ec7p lo\u1ea1i tr\u1eeb. \u0110\u1ea7u ti\u00ean, kh\u1edfi t\u1ea1o th\u01b0 m\u1ee5c n\u00e0y nh\u01b0 m\u1ed9t kho l\u01b0u tr\u1eef Git (n\u1ebfu qu\u00fd kh\u00e1ch c\u00f3 \u00fd \u0111\u1ecbnh qu\u1ea3n l\u00fd phi\u00ean b\u1ea3n m\u00e3 ngu\u1ed3n):<\/p>\n<pre><code class=\"language-bash\">git init\r\n<\/code><\/pre>\n<p>T\u1ea1o v\u00e0 m\u1edf t\u1ec7p\u00a0<code>.gitignore<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano .gitignore\r\n<\/code><\/pre>\n<p>Th\u00eam d\u00f2ng sau v\u00e0o t\u1ec7p tin:<\/p>\n<pre><code>.env\r\n<\/code><\/pre>\n<p>L\u01b0u v\u00e0 \u0111\u00f3ng t\u1ec7p. T\u01b0\u01a1ng t\u1ef1, ch\u00fang ta c\u0169ng t\u1ea1o t\u1ec7p\u00a0<code>.dockerignore<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano .dockerignore\r\n<\/code><\/pre>\n<p>\u0110\u1ecbnh ngh\u0129a c\u00e1c t\u1ec7p v\u00e0 th\u01b0 m\u1ee5c c\u1ea7n b\u1ecf qua khi x\u00e2y d\u1ef1ng Docker image:<\/p>\n<pre><code>.env\r\n.git\r\ndocker-compose.yml\r\n.dockerignore\r\n<\/code><\/pre>\n<p>L\u01b0u l\u1ea1i v\u00e0 \u0111\u00f3ng t\u1ec7p. B\u01b0\u1edbc chu\u1ea9n b\u1ecb bi\u1ebfn m\u00f4i tr\u01b0\u1eddng \u0111\u00e3 ho\u00e0n th\u00e0nh.<\/p>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Buoc-3-%E2%80%94-Xay-Dung-File-Docker-Compose\"><\/span>B\u01b0\u1edbc 3 \u2014 X\u00e2y D\u1ef1ng File Docker Compose<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>T\u1ec7p\u00a0<code>docker-compose.yml<\/code>\u00a0c\u00f3 nhi\u1ec7m v\u1ee5 m\u00f4 t\u1ea3 chi ti\u1ebft c\u00e1ch th\u1ee9c v\u1eadn h\u00e0nh c\u0169ng nh\u01b0 m\u1ed1i li\u00ean k\u1ebft gi\u1eefa c\u00e1c container trong h\u1ec7 th\u1ed1ng \u1ee9ng d\u1ee5ng c\u1ee7a qu\u00fd kh\u00e1ch.<\/p>\n<p>T\u1ea1o v\u00e0 m\u1edf t\u1ec7p\u00a0<code>docker-compose.yml<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano docker-compose.yml\r\n<\/code><\/pre>\n<p>D\u00e1n to\u00e0n b\u1ed9 n\u1ed9i dung c\u1ea5u h\u00ecnh h\u1ec7 th\u1ed1ng d\u01b0\u1edbi \u0111\u00e2y v\u00e0o t\u1ec7p:<\/p>\n<pre><code class=\"language-yaml\">version: '3'\r\n\r\nservices:\r\n  db:\r\n    image: mysql:8.0\r\n    container_name: db\r\n    restart: unless-stopped\r\n    env_file: .env\r\n    environment:\r\n      - MYSQL_DATABASE=wordpress\r\n    volumes:\r\n      - dbdata:\/var\/lib\/mysql\r\n    command: '--default-authentication-plugin=mysql_native_password'\r\n    networks:\r\n      - app-network\r\n\r\n  wordpress:\r\n    depends_on:\r\n      - db\r\n    image: wordpress:5.1.1-fpm-alpine\r\n    container_name: wordpress\r\n    restart: unless-stopped\r\n    env_file: .env\r\n    environment:\r\n      - WORDPRESS_DB_HOST=db:3306\r\n      - WORDPRESS_DB_USER=$MYSQL_USER\r\n      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD\r\n      - WORDPRESS_DB_NAME=wordpress\r\n    volumes:\r\n      - wordpress:\/var\/www\/html\r\n    networks:\r\n      - app-network\r\n\r\n  webserver:\r\n    depends_on:\r\n      - wordpress\r\n    image: nginx:1.15.12-alpine\r\n    container_name: webserver\r\n    restart: unless-stopped\r\n    ports:\r\n      - \"80:80\"\r\n    volumes:\r\n      - wordpress:\/var\/www\/html\r\n      - .\/nginx-conf:\/etc\/nginx\/conf.d\r\n      - certbot-etc:\/etc\/letsencrypt\r\n    networks:\r\n      - app-network\r\n\r\n  certbot:\r\n    depends_on:\r\n      - webserver\r\n    image: certbot\/certbot\r\n    container_name: certbot\r\n    volumes:\r\n      - certbot-etc:\/etc\/letsencrypt\r\n      - wordpress:\/var\/www\/html\r\n    command: certonly --webroot --webroot-path=\/var\/www\/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain\r\n\r\nvolumes:\r\n  certbot-etc:\r\n  wordpress:\r\n  dbdata:\r\n\r\nnetworks:\r\n  app-network:\r\n    driver: bridge\r\n<\/code><\/pre>\n<p><strong>Chi ti\u1ebft c\u00e1c th\u00e0nh ph\u1ea7n ch\u00ednh trong t\u1ec7p c\u1ea5u h\u00ecnh:<\/strong><\/p>\n<ul>\n<li><strong>D\u1ecbch v\u1ee5\u00a0<code>db<\/code>\u00a0(MySQL Database)<\/strong>: S\u1eed d\u1ee5ng phi\u00ean b\u1ea3n \u1ed5n \u0111\u1ecbnh\u00a0<code>mysql:8.0<\/code>. Ch\u1ec9 th\u1ecb\u00a0<code>volumes<\/code>\u00a0g\u1eafn k\u1ebft th\u01b0 m\u1ee5c l\u01b0u tr\u1eef d\u1eef li\u1ec7u c\u1ee7a MySQL v\u1edbi m\u1ed9t volume tr\u00ean \u1ed5 \u0111\u0129a v\u1eadt l\u00fd c\u00f3 t\u00ean\u00a0<code>dbdata<\/code>\u00a0\u0111\u1ec3 b\u1ea3o to\u00e0n c\u01a1 s\u1edf d\u1eef li\u1ec7u. L\u1ec7nh kh\u1edfi ch\u1ea1y \u0111\u01b0\u1ee3c thi\u1ebft l\u1eadp t\u00f9y ch\u1ecdn\u00a0<code>--default-authentication-plugin=mysql_native_password<\/code>\u00a0nh\u1eb1m \u0111\u1ea3m b\u1ea3o t\u00ednh t\u01b0\u01a1ng th\u00edch v\u1edbi c\u01a1 ch\u1ebf \u0111\u0103ng nh\u1eadp c\u0169 c\u1ee7a PHP-FPM trong WordPress.<\/li>\n<li><strong>D\u1ecbch v\u1ee5\u00a0<code>wordpress<\/code><\/strong>: Container n\u00e0y ph\u1ee5 thu\u1ed9c tr\u1ef1c ti\u1ebfp v\u00e0o ti\u1ebfn tr\u00ecnh c\u01a1 s\u1edf d\u1eef li\u1ec7u (<code>depends_on: db<\/code>). Ch\u00fang t\u00f4i l\u1ef1a ch\u1ecdn phi\u00ean b\u1ea3n nh\u1ecf g\u1ecdn x\u00e2y d\u1ef1ng tr\u00ean n\u1ec1n Alpine Linux (<code>wordpress:5.1.1-fpm-alpine<\/code>). Bi\u1ebfn m\u00f4i tr\u01b0\u1eddng k\u1ebft n\u1ed1i c\u01a1 s\u1edf d\u1eef li\u1ec7u s\u1ebd t\u1ef1 \u0111\u1ed9ng l\u1ea5y t\u1eeb t\u1ec7p\u00a0<code>.env<\/code>. Th\u01b0 m\u1ee5c g\u1ed1c ch\u1ee9a m\u00e3 ngu\u1ed3n c\u1ee7a WordPress \u0111\u01b0\u1ee3c \u00e1nh x\u1ea1 v\u00e0o volume t\u0129nh\u00a0<code>wordpress<\/code>.<\/li>\n<li><strong>D\u1ecbch v\u1ee5\u00a0<code>webserver<\/code>\u00a0(Nginx)<\/strong>: L\u1eafng nghe v\u00e0 m\u1edf c\u1ed5ng\u00a0<code>80<\/code>\u00a0k\u1ebft n\u1ed1i tr\u1ef1c ti\u1ebfp ra b\u00ean ngo\u00e0i VPS. N\u00f3 chia s\u1ebb chung m\u00e3 ngu\u1ed3n qua volume t\u0129nh\u00a0<code>wordpress<\/code>\u00a0v\u00e0 l\u1ea5y c\u1ea5u h\u00ecnh Nginx c\u1ee5c b\u1ed9 t\u1eeb th\u01b0 m\u1ee5c\u00a0<code>nginx-conf<\/code>\u00a0th\u00f4ng qua c\u01a1 ch\u1ebf bind mount.<\/li>\n<li><strong>D\u1ecbch v\u1ee5\u00a0<code>certbot<\/code><\/strong>: \u0110\u00e2y l\u00e0 d\u1ecbch v\u1ee5 ch\u1ea1y m\u1ed9t l\u1ea7n r\u1ed3i t\u1eaft, c\u00f3 nhi\u1ec7m v\u1ee5 g\u1eedi y\u00eau c\u1ea7u x\u00e1c th\u1ef1c t\u00ean mi\u1ec1n t\u1edbi Let&#8217;s Encrypt. Tham s\u1ed1\u00a0<code>--staging<\/code>\u00a0gi\u00fap b\u1ea1n g\u1eedi y\u00eau c\u1ea7u th\u1eed nghi\u1ec7m nh\u1eb1m ki\u1ec3m tra c\u1ea5u h\u00ecnh h\u1ec7 th\u1ed1ng m\u00e0 kh\u00f4ng lo b\u1ecb ch\u1eb7n ho\u1eb7c d\u00ednh gi\u1edbi h\u1ea1n y\u00eau c\u1ea7u (rate limit) t\u1eeb m\u00e1y ch\u1ee7 Let&#8217;s Encrypt. Qu\u00fd kh\u00e1ch nh\u1edb \u0111\u1ed5i\u00a0<code>sammy@your_domain<\/code>\u00a0sang email c\u1ee7a m\u00ecnh v\u00e0\u00a0<code>your_domain<\/code>\u00a0sang t\u00ean mi\u1ec1n th\u1eadt.<\/li>\n<li><strong>Volumes &amp; Networks<\/strong>: \u0110\u1ecbnh ngh\u0129a c\u00e1c volume d\u00f9ng chung cho h\u1ec7 th\u1ed1ng v\u00e0 thi\u1ebft l\u1eadp m\u1ea1ng c\u1ea7u n\u1ed9i b\u1ed9\u00a0<code>app-network<\/code>\u00a0gi\u00fap c\u00e1c container nh\u1eadn di\u1ec7n v\u00e0 truy\u1ec1n t\u1ea3i g\u00f3i tin qua l\u1ea1i m\u1ed9t c\u00e1ch an to\u00e0n m\u00e0 kh\u00f4ng c\u1ea7n c\u00f4ng khai to\u00e0n b\u1ed9 c\u00e1c c\u1ed5ng ra ngo\u00e0i internet.<\/li>\n<\/ul>\n<p>L\u01b0u v\u00e0 \u0111\u00f3ng t\u1ec7p sau khi \u0111\u00e3 ch\u1ec9nh s\u1eeda ch\u00ednh x\u00e1c c\u00e1c gi\u00e1 tr\u1ecb.<\/p>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Buoc-4-%E2%80%94-Lay-Chung-Chi-SSL-Lets-Encrypt\"><\/span>B\u01b0\u1edbc 4 \u2014 L\u1ea5y Ch\u1ee9ng Ch\u1ec9 SSL Let&#8217;s Encrypt<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>B\u00e2y gi\u1edd l\u00e0 l\u00fac ch\u00fang ta ti\u1ebfn h\u00e0nh kh\u1edfi \u0111\u1ed9ng h\u1ec7 th\u1ed1ng container \u0111\u1ec3 b\u1eaft \u0111\u1ea7u y\u00eau c\u1ea7u ch\u1ee9ng ch\u1ec9 SSL th\u1eed nghi\u1ec7m.<\/p>\n<p>S\u1eed d\u1ee5ng l\u1ec7nh sau \u0111\u1ec3 kh\u1edfi ch\u1ea1y c\u00e1c container d\u01b0\u1edbi d\u1ea1ng ch\u1ea1y ng\u1ea7m (<code>-d<\/code>):<\/p>\n<pre><code class=\"language-bash\">docker-compose up -d\r\n<\/code><\/pre>\n<p>H\u1ec7 th\u1ed1ng s\u1ebd t\u1ea3i c\u00e1c image c\u1ea7n thi\u1ebft v\u00e0 kh\u1edfi ch\u1ea1y c\u00e1c d\u1ecbch v\u1ee5:<\/p>\n<pre><code>OutputCreating db ... done\r\nCreating wordpress ... done\r\nCreating webserver ... done\r\nCreating certbot   ... done\r\n<\/code><\/pre>\n<p>Ki\u1ec3m tra tr\u1ea1ng th\u00e1i ho\u1ea1t \u0111\u1ed9ng c\u1ee7a c\u00e1c ti\u1ebfn tr\u00ecnh b\u1eb1ng l\u1ec7nh:<\/p>\n<pre><code class=\"language-bash\">docker-compose ps\r\n<\/code><\/pre>\n<p>N\u1ebfu th\u00e0nh c\u00f4ng, tr\u1ea1ng th\u00e1i c\u1ee7a\u00a0<code>db<\/code>,\u00a0<code>wordpress<\/code>, v\u00e0\u00a0<code>webserver<\/code>\u00a0s\u1ebd hi\u1ec3n th\u1ecb l\u00e0\u00a0<code>Up<\/code>, ri\u00eang container\u00a0<code>certbot<\/code>\u00a0s\u1ebd hi\u1ec3n th\u1ecb tr\u1ea1ng th\u00e1i k\u1ebft th\u00fac th\u00e0nh c\u00f4ng l\u00e0\u00a0<code>Exit 0<\/code>:<\/p>\n<pre><code>Output  Name                 Command               State           Ports\r\n-------------------------------------------------------------------------\r\ncertbot     certbot certonly --webroot ...   Exit 0\r\ndb          docker-entrypoint.sh --def ...   Up       3306\/tcp, 33060\/tcp\r\nwebserver   nginx -g daemon off;             Up       0.0.0.0:80-&gt;80\/tcp\r\nwordpress   docker-entrypoint.sh php-fpm     Up       9000\/tcp\r\n<\/code><\/pre>\n<p><em>(M\u1eb9o b\u1ea3o tr\u00ec: N\u1ebfu c\u00f3 d\u1ecbch v\u1ee5 n\u00e0o g\u1eb7p l\u1ed7i kh\u00f4ng th\u1ec3 chuy\u1ec3n sang tr\u1ea1ng th\u00e1i Up, qu\u00fd kh\u00e1ch c\u00f3 th\u1ec3 ki\u1ec3m tra nh\u1eadt k\u00fd l\u1ed7i b\u1eb1ng l\u1ec7nh\u00a0<code>docker-compose logs &lt;t\u00ean_d\u1ecbch_v\u1ee5&gt;<\/code>\u00a0\u0111\u1ec3 kh\u1eafc ph\u1ee5c).<\/em><\/p>\n<p>B\u00e2y gi\u1edd h\u00e3y x\u00e1c nh\u1eadn xem ch\u1ee9ng ch\u1ec9 th\u1eed nghi\u1ec7m \u0111\u00e3 \u0111\u01b0\u1ee3c l\u01b0u v\u00e0o th\u01b0 m\u1ee5c chia s\u1ebb c\u1ee7a Nginx hay ch\u01b0a b\u1eb1ng l\u1ec7nh:<\/p>\n<pre><code class=\"language-bash\">docker-compose exec webserver ls -la \/etc\/letsencrypt\/live\r\n<\/code><\/pre>\n<p>N\u1ebfu th\u1ea5y c\u00f3 th\u01b0 m\u1ee5c ch\u1ee9a t\u00ean mi\u1ec1n c\u1ee7a qu\u00fd kh\u00e1ch xu\u1ea5t hi\u1ec7n, qu\u00e1 tr\u00ecnh ki\u1ec3m tra th\u1eed nghi\u1ec7m \u0111\u00e3 ho\u00e0n t\u1ea5t th\u00e0nh c\u00f4ng:<\/p>\n<pre><code>Outputtotal 16\r\ndrwx------    3 root     root          4096 May 10 15:45 .\r\ndrwxr-xr-x    9 root     root          4096 May 10 15:45 ..\r\n-rw-r--r--    1 root     root           740 May 10 15:45 README\r\ndrwxr-xr-x    2 root     root          4096 May 10 15:45 your_domain\r\n<\/code><\/pre>\n<p>Khi c\u1ea5u h\u00ecnh \u0111\u00e3 ch\u1ea1y t\u1ed1t, ch\u00fang ta s\u1ebd ti\u1ebfn h\u00e0nh xin c\u1ea5p ch\u1ee9ng ch\u1ec9 SSL ch\u00ednh th\u1ee9c (production). M\u1edf l\u1ea1i t\u1ec7p\u00a0<code>docker-compose.yml<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano docker-compose.yml\r\n<\/code><\/pre>\n<p>T\u00ecm \u0111\u1ebfn ph\u1ea7n khai b\u00e1o c\u1ee7a d\u1ecbch v\u1ee5\u00a0<code>certbot<\/code>, s\u1eeda \u0111\u1ed5i c\u00e2u l\u1ec7nh th\u1ef1c thi b\u1eb1ng c\u00e1ch x\u00f3a b\u1ecf tham s\u1ed1\u00a0<code>--staging<\/code>\u00a0v\u00e0 th\u00eam v\u00e0o tham s\u1ed1\u00a0<code>--force-renewal<\/code>\u00a0\u0111\u1ec3 b\u1eaft bu\u1ed9c \u0111\u0103ng k\u00fd m\u1edbi \u0111\u00e8 l\u00ean ch\u1ee9ng ch\u1ec9 c\u0169:<\/p>\n<pre><code class=\"language-yaml\">...\r\n  certbot:\r\n    depends_on:\r\n      - webserver\r\n    image: certbot\/certbot\r\n    container_name: certbot\r\n    volumes:\r\n      - certbot-etc:\/etc\/letsencrypt\r\n      - wordpress:\/var\/www\/html\r\n    command: certonly --webroot --webroot-path=\/var\/www\/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain\r\n...\r\n<\/code><\/pre>\n<p>Ch\u1ea1y l\u1ec7nh d\u01b0\u1edbi \u0111\u00e2y \u0111\u1ec3 y\u00eau c\u1ea7u Docker Compose t\u00e1i t\u1ea1o ri\u00eang container\u00a0<code>certbot<\/code>\u00a0v\u00e0 b\u1ecf qua vi\u1ec7c ki\u1ec3m tra c\u00e1c d\u1ecbch v\u1ee5 kh\u00e1c (<code>--no-deps<\/code>):<\/p>\n<pre><code class=\"language-bash\">docker-compose up --force-recreate --no-deps certbot\r\n<\/code><\/pre>\n<p>Nh\u1eadt k\u00fd m\u00e0n h\u00ecnh s\u1ebd hi\u1ec7n th\u00f4ng b\u00e1o ch\u00fac m\u1eebng ch\u1ee9ng ch\u1ec9 SSL ch\u00ednh th\u1ee9c c\u1ee7a qu\u00fd kh\u00e1ch \u0111\u00e3 \u0111\u01b0\u1ee3c t\u1ea1o l\u1eadp v\u00e0 l\u01b0u tr\u1eef th\u00e0nh c\u00f4ng tr\u00ean \u1ed5 \u0111\u0129a m\u00e1y ch\u1ee7 VPS:<\/p>\n<pre><code>OutputRecreating certbot ... done\r\nAttaching to certbot\r\n...\r\ncertbot      | IMPORTANT NOTES:\r\ncertbot      |  - Congratulations! Your certificate and chain have been saved at:\r\ncertbot      |    \/etc\/letsencrypt\/live\/your_domain\/fullchain.pem\r\n...\r\ncertbot exited with code 0\r\n<\/code><\/pre>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Buoc-5-%E2%80%94-Cap-Nhat-Cau-Hinh-Nginx-Va-File-Compose-Cho-SSL\"><\/span>B\u01b0\u1edbc 5 \u2014 C\u1eadp Nh\u1eadt C\u1ea5u H\u00ecnh Nginx V\u00e0 File Compose Cho SSL<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>C\u00f3 \u0111\u01b0\u1ee3c ch\u1ee9ng ch\u1ec9 SSL, ch\u00fang ta c\u1ea7n c\u1ea5u h\u00ecnh l\u1ea1i Nginx \u0111\u1ec3 k\u00edch ho\u1ea1t giao th\u1ee9c HTTPS b\u1ea3o m\u1eadt t\u1ea1i c\u1ed5ng\u00a0<code>443<\/code>\u00a0v\u00e0 thi\u1ebft l\u1eadp chuy\u1ec3n h\u01b0\u1edbng t\u1ef1 \u0111\u1ed9ng to\u00e0n b\u1ed9 truy c\u1eadp kh\u00f4ng b\u1ea3o m\u1eadt (HTTP c\u1ed5ng\u00a0<code>80<\/code>) sang HTTPS.<\/p>\n<p>\u0110\u1ea7u ti\u00ean, t\u1ea1m th\u1eddi d\u1eebng ho\u1ea1t \u0111\u1ed9ng c\u1ee7a container Nginx:<\/p>\n<pre><code class=\"language-bash\">docker-compose stop webserver\r\n<\/code><\/pre>\n<p>Ti\u1ebfp theo, t\u1ea3i t\u1ec7p c\u1ea5u h\u00ecnh b\u1ea3o m\u1eadt SSL ti\u00eau chu\u1ea9n do Certbot khuy\u1ebfn ngh\u1ecb b\u1eb1ng l\u1ec7nh\u00a0<code>curl<\/code>\u00a0sau:<\/p>\n<pre><code class=\"language-bash\">curl -sSLo nginx-conf\/options-ssl-nginx.conf https:\/\/raw.githubusercontent.com\/certbot\/certbot\/master\/certbot-nginx\/certbot_nginx\/_internal\/tls_configs\/options-ssl-nginx.conf\r\n<\/code><\/pre>\n<p>X\u00f3a b\u1ecf t\u1ec7p c\u1ea5u h\u00ecnh Nginx c\u0169:<\/p>\n<pre><code class=\"language-bash\">rm nginx-conf\/nginx.conf\r\n<\/code><\/pre>\n<p>T\u1ea1o m\u1ed9t t\u1ec7p c\u1ea5u h\u00ecnh m\u1edbi:<\/p>\n<pre><code class=\"language-bash\">nano nginx-conf\/nginx.conf\r\n<\/code><\/pre>\n<p>Sao ch\u00e9p to\u00e0n b\u1ed9 m\u00e3 c\u1ea5u h\u00ecnh h\u1ed7 tr\u1ee3 SSL ho\u00e0n ch\u1ec9nh d\u01b0\u1edbi \u0111\u00e2y. Ch\u00fa \u00fd thay \u0111\u1ed5i\u00a0<code>your_domain<\/code>\u00a0th\u00e0nh t\u00ean mi\u1ec1n th\u1ef1c t\u1ebf:<\/p>\n<pre><code class=\"language-nginx\">server {\r\n        listen 80;\r\n        listen [::]:80;\r\n\r\n        server_name your_domain www.your_domain;\r\n\r\n        location ~ \/.well-known\/acme-challenge {\r\n                allow all;\r\n                root \/var\/www\/html;\r\n        }\r\n\r\n        location \/ {\r\n                rewrite ^ https:\/\/$host$request_uri? permanent;\r\n        }\r\n}\r\n\r\nserver {\r\n        listen 443 ssl http2;\r\n        listen [::]:443 ssl http2;\r\n        server_name your_domain www.your_domain;\r\n\r\n        index index.php index.html index.htm;\r\n\r\n        root \/var\/www\/html;\r\n\r\n        server_tokens off;\r\n\r\n        ssl_certificate \/etc\/letsencrypt\/live\/your_domain\/fullchain.pem;\r\n        ssl_certificate_key \/etc\/letsencrypt\/live\/your_domain\/privkey.pem;\r\n\r\n        include \/etc\/nginx\/conf.d\/options-ssl-nginx.conf;\r\n\r\n        add_header X-Frame-Options \"SAMEORIGIN\" always;\r\n        add_header X-XSS-Protection \"1; mode=block\" always;\r\n        add_header X-Content-Type-Options \"nosniff\" always;\r\n        add_header Referrer-Policy \"no-referrer-when-downgrade\" always;\r\n        add_header Content-Security-Policy \"default-src * data: 'unsafe-eval' 'unsafe-inline'\" always;\r\n\r\n        location \/ {\r\n                try_files $uri $uri\/ \/index.php$is_args$args;\r\n        }\r\n\r\n        location ~ \\.php$ {\r\n                try_files $uri =404;\r\n                fastcgi_split_path_info ^(.+\\.php)(\/.+)$;\r\n                fastcgi_pass wordpress:9000;\r\n                fastcgi_index index.php;\r\n                include fastcgi_params;\r\n                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\r\n                fastcgi_param PATH_INFO $fastcgi_path_info;\r\n        }\r\n\r\n        location ~ \/\\.ht {\r\n                deny all;\r\n        }\r\n\r\n        location = \/favicon.ico {\r\n                log_not_found off; access_log off;\r\n        }\r\n        location = \/robots.txt {\r\n                log_not_found off; access_log off; allow all;\r\n        }\r\n        location ~* \\.(css|gif|ico|jpeg|jpg|js|png)$ {\r\n                expires max;\r\n                log_not_found off;\r\n        }\r\n}\r\n<\/code><\/pre>\n<p>L\u01b0u v\u00e0 \u0111\u00f3ng t\u1ec7p c\u1ea5u h\u00ecnh Nginx.<\/p>\n<p>B\u00e2y gi\u1edd ch\u00fang ta c\u1ea7n \u00e1nh x\u1ea1 c\u1ed5ng\u00a0<code>443<\/code>\u00a0t\u1eeb container Nginx ra ngo\u00e0i m\u00e1y ch\u1ee7 trong t\u1ec7p\u00a0<code>docker-compose.yml<\/code>\u00a0\u0111\u1ec3 ng\u01b0\u1eddi d\u00f9ng c\u00f3 th\u1ec3 truy c\u1eadp qua HTTPS.<\/p>\n<p>M\u1edf t\u1ec7p\u00a0<code>docker-compose.yml<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano docker-compose.yml\r\n<\/code><\/pre>\n<p>T\u00ecm \u0111\u1ebfn ph\u1ea7n d\u1ecbch v\u1ee5\u00a0<code>webserver<\/code>\u00a0v\u00e0 c\u1eadp nh\u1eadt danh s\u00e1ch c\u1ed5ng (ports) nh\u01b0 sau:<\/p>\n<pre><code class=\"language-yaml\">...\r\n  webserver:\r\n    depends_on:\r\n      - wordpress\r\n    image: nginx:1.15.12-alpine\r\n    container_name: webserver\r\n    restart: unless-stopped\r\n    ports:\r\n      - \"80:80\"\r\n      - \"443:443\"\r\n    volumes:\r\n      - wordpress:\/var\/www\/html\r\n      - .\/nginx-conf:\/etc\/nginx\/conf.d\r\n      - certbot-etc:\/etc\/letsencrypt\r\n    networks:\r\n      - app-network\r\n...\r\n<\/code><\/pre>\n<p>L\u01b0u t\u1ec7p\u00a0<code>docker-compose.yml<\/code>\u00a0v\u00e0 tho\u00e1t. Kh\u1edfi ch\u1ea1y l\u1ea1i d\u1ecbch v\u1ee5\u00a0<code>webserver<\/code>\u00a0\u0111\u1ec3 \u00e1p d\u1ee5ng c\u1ea5u h\u00ecnh m\u1edbi:<\/p>\n<pre><code class=\"language-bash\">docker-compose up -d --force-recreate --no-deps webserver\r\n<\/code><\/pre>\n<p>Xem tr\u1ea1ng th\u00e1i ho\u1ea1t \u0111\u1ed9ng c\u1ee7a h\u1ec7 th\u1ed1ng b\u1eb1ng l\u1ec7nh\u00a0<code>docker-compose ps<\/code>. L\u00fac n\u00e0y, m\u00e1y ch\u1ee7 web c\u1ee7a qu\u00fd kh\u00e1ch \u0111\u00e3 m\u1edf c\u1ea3 hai c\u1ed5ng truy c\u1eadp ti\u00eau chu\u1ea9n:<\/p>\n<pre><code>Output  Name                 Command               State                     Ports\r\n----------------------------------------------------------------------------------------------\r\ncertbot     certbot certonly --webroot ...   Exit 0\r\ndb          docker-entrypoint.sh --def ...   Up       3306\/tcp, 33060\/tcp\r\nwebserver   nginx -g daemon off;             Up       0.0.0.0:443-&gt;443\/tcp, 0.0.0.0:80-&gt;80\/tcp\r\nwordpress   docker-entrypoint.sh php-fpm     Up       9000\/tcp\r\n<\/code><\/pre>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Buoc-6-%E2%80%94-Hoan-Tat-Cai-Dat-WordPress-Tren-Giao-Dien-Web\"><\/span>B\u01b0\u1edbc 6 \u2014 Ho\u00e0n T\u1ea5t C\u00e0i \u0110\u1eb7t WordPress Tr\u00ean Giao Di\u1ec7n Web<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>T\u1ea1i tr\u00ecnh duy\u1ec7t web c\u00e1 nh\u00e2n, h\u00e3y truy c\u1eadp v\u00e0o \u0111\u1ecba ch\u1ec9 t\u00ean mi\u1ec1n c\u1ee7a qu\u00fd kh\u00e1ch:<\/p>\n<pre><code>https:\/\/your_domain\r\n<\/code><\/pre>\n<p>Qu\u00fd kh\u00e1ch s\u1ebd th\u1ea5y giao di\u1ec7n c\u00e0i \u0111\u1eb7t ch\u00e0o m\u1eebng m\u1eb7c \u0111\u1ecbnh c\u1ee7a h\u1ec7 th\u1ed1ng WordPress \u0111\u01b0\u1ee3c hi\u1ec3n th\u1ecb an to\u00e0n qua giao th\u1ee9c b\u1ea3o m\u1eadt HTTPS:<\/p>\n<ol>\n<li><strong>L\u1ef1a ch\u1ecdn ng\u00f4n ng\u1eef<\/strong>: Ch\u1ecdn ng\u00f4n ng\u1eef ph\u00f9 h\u1ee3p (v\u00ed d\u1ee5: Ti\u1ebfng Vi\u1ec7t ho\u1eb7c English) r\u1ed3i b\u1ea5m\u00a0<strong>Ti\u1ebfp t\u1ee5c (Continue)<\/strong>.<\/li>\n<li><strong>Khai b\u00e1o th\u00f4ng tin qu\u1ea3n tr\u1ecb<\/strong>: Nh\u1eadp ti\u00eau \u0111\u1ec1 cho website, \u0111\u1eb7t t\u00ean t\u00e0i kho\u1ea3n qu\u1ea3n tr\u1ecb (tr\u00e1nh d\u00f9ng t\u00ean m\u1eb7c \u0111\u1ecbnh &#8220;admin&#8221; \u0111\u1ec3 t\u0103ng c\u01b0\u1eddng \u0111\u1ed9 b\u1ea3o m\u1eadt) v\u00e0 \u0111i\u1ec1n m\u1eadt kh\u1ea9u \u0111\u0103ng nh\u1eadp c\u00e1 nh\u00e2n b\u1ea3o m\u1eadt cao. \u0110i\u1ec1n ch\u00ednh x\u00e1c \u0111\u1ecba ch\u1ec9 th\u01b0 \u0111i\u1ec7n t\u1eed (email) c\u1ee7a qu\u00fd kh\u00e1ch.<\/li>\n<li>B\u1ea5m n\u00fat\u00a0<strong>C\u00e0i \u0111\u1eb7t WordPress (Install WordPress)<\/strong>\u00a0\u1edf g\u00f3c d\u01b0\u1edbi c\u00f9ng m\u00e0n h\u00ecnh.<\/li>\n<\/ol>\n<p>H\u1ec7 th\u1ed1ng s\u1ebd chuy\u1ec3n h\u01b0\u1edbng qu\u00fd kh\u00e1ch sang trang \u0111\u0103ng nh\u1eadp qu\u1ea3n tr\u1ecb. Sau khi \u0111\u0103ng nh\u1eadp th\u00e0nh c\u00f4ng, b\u1ea3ng \u0111i\u1ec1u khi\u1ec3n qu\u1ea3n tr\u1ecb WordPress (Dashboard) s\u1ebd hi\u1ec3n th\u1ecb \u0111\u1ea7y \u0111\u1ee7 t\u00ednh n\u0103ng.<\/p>\n<hr \/>\n<h3><span class=\"ez-toc-section\" id=\"Buoc-7-%E2%80%94-Thiet-Lap-Tu-Dong-Gia-Han-SSL\"><\/span>B\u01b0\u1edbc 7 \u2014 Thi\u1ebft L\u1eadp T\u1ef1 \u0110\u1ed9ng Gia H\u1ea1n SSL<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Ch\u1ee9ng ch\u1ec9 c\u1ea5p b\u1edfi t\u1ed5 ch\u1ee9c Let\u2019s Encrypt ch\u1ec9 c\u00f3 gi\u00e1 tr\u1ecb hi\u1ec7u l\u1ef1c trong v\u00f2ng 90 ng\u00e0y. \u0110\u1ec3 \u0111\u1ea3m b\u1ea3o website ho\u1ea1t \u0111\u1ed9ng \u1ed5n \u0111\u1ecbnh v\u00e0 li\u00ean t\u1ee5c m\u00e0 kh\u00f4ng lo ch\u1ee9ng ch\u1ec9 h\u1ebft h\u1ea1n, ch\u00fang ta s\u1ebd thi\u1ebft l\u1eadp quy tr\u00ecnh t\u1ef1 \u0111\u1ed9ng ki\u1ec3m tra v\u00e0 gia h\u1ea1n.<\/p>\n<p>T\u1ea1o m\u1ed9t t\u1eadp l\u1ec7nh shell m\u1edbi c\u00f3 t\u00ean\u00a0<code>ssl_renew.sh<\/code>:<\/p>\n<pre><code class=\"language-bash\">nano ssl_renew.sh\r\n<\/code><\/pre>\n<p>D\u00e1n n\u1ed9i dung t\u1eadp l\u1ec7nh sau v\u00e0o t\u1ec7p tin. L\u01b0u \u00fd thay th\u1ebf \u0111\u01b0\u1eddng d\u1eabn\u00a0<code>\/home\/sammy\/wordpress\/<\/code>\u00a0th\u00e0nh \u0111\u01b0\u1eddng d\u1eabn th\u01b0 m\u1ee5c d\u1ef1 \u00e1n th\u1ef1c t\u1ebf tr\u00ean m\u00e1y ch\u1ee7 c\u1ee7a qu\u00fd kh\u00e1ch (v\u00ed d\u1ee5\u00a0<code>\/home\/ten_user\/wordpress\/<\/code>):<\/p>\n<pre><code class=\"language-bash\">#!\/bin\/bash\r\n\r\nCOMPOSE=\"\/usr\/local\/bin\/docker-compose --no-ansi\"\r\nDOCKER=\"\/usr\/bin\/docker\"\r\n\r\ncd \/home\/sammy\/wordpress\/\r\n$COMPOSE run certbot renew --dry-run &amp;&amp; $COMPOSE kill -s SIGHUP webserver\r\n$DOCKER system prune -af\r\n<\/code><\/pre>\n<p><strong>Nguy\u00ean l\u00fd ho\u1ea1t \u0111\u1ed9ng c\u1ee7a \u0111o\u1ea1n m\u00e3 l\u1ec7nh tr\u00ean:<\/strong><\/p>\n<ul>\n<li>Di chuy\u1ec3n v\u00e0o th\u01b0 m\u1ee5c l\u00e0m vi\u1ec7c ch\u1ee9a t\u1ec7p compose c\u1ee7a WordPress.<\/li>\n<li>Kh\u1edfi ch\u1ea1y container\u00a0<code>certbot<\/code>\u00a0t\u1ea1m th\u1eddi \u0111\u1ec3 ch\u1ea1y l\u1ec7nh ki\u1ec3m tra gia h\u1ea1n SSL v\u1edbi t\u00f9y ch\u1ecdn th\u1eed nghi\u1ec7m\u00a0<code>--dry-run<\/code>. N\u1ebfu ph\u00e1t hi\u1ec7n ch\u1ee9ng ch\u1ec9 s\u1eafp h\u1ebft h\u1ea1n v\u00e0 gia h\u1ea1n th\u00e0nh c\u00f4ng, n\u00f3 s\u1ebd g\u1eedi t\u00edn hi\u1ec7u\u00a0<code>SIGHUP<\/code>\u00a0\u0111\u1ec3 y\u00eau c\u1ea7u Nginx t\u1ea3i l\u1ea1i c\u1ea5u h\u00ecnh m\u1edbi m\u00e0 kh\u00f4ng l\u00e0m gi\u00e1n \u0111o\u1ea1n c\u00e1c k\u1ebft n\u1ed1i hi\u1ec7n t\u1ea1i c\u1ee7a kh\u00e1ch h\u00e0ng truy c\u1eadp website.<\/li>\n<li>Ch\u1ea1y l\u1ec7nh d\u1ecdn d\u1eb9p h\u1ec7 th\u1ed1ng\u00a0<code>docker system prune -af<\/code>\u00a0\u0111\u1ec3 gi\u1ea3i ph\u00f3ng dung l\u01b0\u1ee3ng \u1ed5 c\u1ee9ng b\u1ecb chi\u1ebfm d\u1ee5ng b\u1edfi c\u00e1c container t\u1ea1m th\u1eddi v\u00e0 c\u00e1c b\u1ea3n build kh\u00f4ng c\u00f2n s\u1eed d\u1ee5ng.<\/li>\n<\/ul>\n<p>L\u01b0u t\u1ec7p tin v\u00e0 c\u1ea5p quy\u1ec1n th\u1ef1c thi cho t\u1eadp l\u1ec7nh:<\/p>\n<pre><code class=\"language-bash\">chmod +x ssl_renew.sh\r\n<\/code><\/pre>\n<p>Ti\u1ebfp theo, ch\u00fang ta \u0111\u0103ng k\u00fd t\u1eadp l\u1ec7nh n\u00e0y v\u1edbi tr\u00ecnh l\u1eadp l\u1ecbch t\u00e1c v\u1ee5 t\u1ef1 \u0111\u1ed9ng\u00a0<code>cron<\/code>\u00a0c\u1ee7a h\u1ec7 th\u1ed1ng m\u00e1y ch\u1ee7 d\u01b0\u1edbi quy\u1ec1n t\u00e0i kho\u1ea3n root:<\/p>\n<pre><code class=\"language-bash\">sudo crontab -e\r\n<\/code><\/pre>\n<p>N\u1ebfu \u0111\u00e2y l\u00e0 l\u1ea7n \u0111\u1ea7u truy c\u1eadp c\u1ea5u h\u00ecnh\u00a0<code>cron<\/code>, qu\u00fd kh\u00e1ch h\u00e3y ch\u1ecdn s\u1ed1 \u1ee9ng v\u1edbi tr\u00ecnh so\u1ea1n th\u1ea3o v\u0103n b\u1ea3n d\u1ec5 d\u00f9ng nh\u1ea5t (v\u00ed d\u1ee5 ch\u1ecdn\u00a0<code>1<\/code>\u00a0cho\u00a0<code>\/bin\/nano<\/code>).<\/p>\n<p>\u1ede d\u00f2ng cu\u1ed1i c\u00f9ng c\u1ee7a t\u1ec7p, th\u00eam d\u00f2ng ki\u1ec3m tra th\u1eed nghi\u1ec7m (ch\u1ea1y t\u1ef1 \u0111\u1ed9ng m\u1ed7i 5 ph\u00fat m\u1ed9t l\u1ea7n):<\/p>\n<pre><code>*\/5 * * * * \/home\/sammy\/wordpress\/ssl_renew.sh &gt;&gt; \/var\/log\/cron.log 2&gt;&amp;1\r\n<\/code><\/pre>\n<p>L\u01b0u t\u1ec7p c\u1ea5u h\u00ecnh cron l\u1ea1i v\u00e0 tho\u00e1t ra ngo\u00e0i. Sau kho\u1ea3ng 5 ph\u00fat, qu\u00fd kh\u00e1ch ki\u1ec3m tra t\u1ec7p tin nh\u1eadt k\u00fd ghi nh\u1eadn \u0111\u1ec3 xem t\u00e1c v\u1ee5 t\u1ef1 \u0111\u1ed9ng c\u00f3 ch\u1ea1y b\u00ecnh th\u01b0\u1eddng v\u00e0 kh\u00f4ng x\u1ea3y ra l\u1ed7i hay kh\u00f4ng:<\/p>\n<pre><code class=\"language-bash\">tail -f \/var\/log\/cron.log\r\n<\/code><\/pre>\n<p>Khi nh\u00ecn th\u1ea5y d\u00f2ng ch\u1eef x\u00e1c nh\u1eadn gi\u1ea3 l\u1eadp th\u00e0nh c\u00f4ng d\u01b0\u1edbi \u0111\u00e2y, t\u1eadp l\u1ec7nh c\u1ee7a qu\u00fd kh\u00e1ch \u0111\u00e3 ho\u1ea1t \u0111\u1ed9ng tr\u01a1n tru:<\/p>\n<pre><code>Output** DRY RUN: simulating 'certbot renew' close to cert expiry\r\n**          (The test certificates below have not been saved.)\r\n\r\nCongratulations, all renewals succeeded. The following certs have been renewed:\r\n  \/etc\/letsencrypt\/live\/your_domain\/fullchain.pem (success)\r\n<\/code><\/pre>\n<p>Nh\u1ea5n\u00a0<code>CTRL+C<\/code>\u00a0\u0111\u1ec3 tho\u00e1t m\u00e0n h\u00ecnh xem nh\u1eadt k\u00fd.<\/p>\n<p>Gi\u1edd \u0111\u00e2y, khi quy tr\u00ecnh \u0111\u00e3 \u0111\u01b0\u1ee3c ki\u1ec3m tra th\u00e0nh c\u00f4ng, h\u00e3y m\u1edf l\u1ea1i b\u1ea3ng c\u1ea5u h\u00ecnh\u00a0<code>crontab -e<\/code>\u00a0v\u00e0 c\u1eadp nh\u1eadt l\u1ea1i chu k\u1ef3 ch\u1ea1y th\u1ef1c t\u1ebf (v\u00ed d\u1ee5 ch\u1ea1y v\u00e0o l\u00fac 12:00 tr\u01b0a m\u1ed7i ng\u00e0y thay v\u00ec m\u1ed7i 5 ph\u00fat):<\/p>\n<pre><code>0 12 * * * \/home\/sammy\/wordpress\/ssl_renew.sh &gt;&gt; \/var\/log\/cron.log 2&gt;&amp;1\r\n<\/code><\/pre>\n<p>\u0110\u1ed3ng th\u1eddi, m\u1edf l\u1ea1i t\u1ec7p tin\u00a0<code>ssl_renew.sh<\/code>\u00a0\u0111\u1ec3 lo\u1ea1i b\u1ecf c\u1edd th\u1eed nghi\u1ec7m\u00a0<code>--dry-run<\/code>\u00a0nh\u1eb1m ti\u1ebfn h\u00e0nh th\u1ef1c hi\u1ec7n gia h\u1ea1n th\u1eadt khi \u0111\u1ebfn h\u1ea1n:<\/p>\n<pre><code class=\"language-bash\">nano ssl_renew.sh\r\n<\/code><\/pre>\n<p>C\u1eadp nh\u1eadt d\u00f2ng l\u1ec7nh ch\u1ea1y certbot:<\/p>\n<pre><code class=\"language-bash\">...\r\n$COMPOSE run certbot renew &amp;&amp; $COMPOSE kill -s SIGHUP webserver\r\n...\r\n<\/code><\/pre>\n<p>L\u01b0u t\u1ec7p tin v\u00e0 ho\u00e0n t\u1ea5t. To\u00e0n b\u1ed9 h\u1ec7 th\u1ed1ng WordPress Docker Compose v\u00e0 c\u01a1 ch\u1ebf b\u1ea3o m\u1eadt t\u1ef1 \u0111\u1ed9ng c\u1ee7a qu\u00fd kh\u00e1ch \u0111\u00e3 \u0111\u01b0\u1ee3c v\u1eadn h\u00e0nh ho\u00e0n ch\u1ec9nh v\u00e0 an to\u00e0n.<\/p>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Cac-Cau-Hoi-Thuong-Gap-FAQs\"><\/span>C\u00e1c C\u00e2u H\u1ecfi Th\u01b0\u1eddng G\u1eb7p (FAQs)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"1-Tai-sao-toi-nen-su-dung-Docker-Compose-de-trien-khai-WordPress\"><\/span>1. T\u1ea1i sao t\u00f4i n\u00ean s\u1eed d\u1ee5ng Docker Compose \u0111\u1ec3 tri\u1ec3n khai WordPress?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Vi\u1ec7c s\u1eed d\u1ee5ng Docker Compose gi\u00fap \u0111\u01a1n gi\u1ea3n h\u00f3a to\u00e0n b\u1ed9 qu\u00e1 tr\u00ecnh c\u00e0i \u0111\u1eb7t. Thay v\u00ec ph\u1ea3i m\u1ea5t h\u00e0ng gi\u1edd \u0111\u1ec3 c\u00e0i \u0111\u1eb7t v\u00e0 c\u1ea5u h\u00ecnh th\u1ee7 c\u00f4ng t\u1eebng th\u00e0nh ph\u1ea7n c\u1ee7a b\u1ed9 c\u00f4ng c\u1ee5 LEMP hay LAMP tr\u00ean h\u1ec7 \u0111i\u1ec1u h\u00e0nh m\u00e1y ch\u1ee7, b\u1ea1n ch\u1ec9 c\u1ea7n \u0111\u1ecbnh ngh\u0129a t\u1ea5t c\u1ea3 c\u00e1c d\u1ecbch v\u1ee5 (Database, WordPress, Web Server Nginx) trong m\u1ed9t t\u1ec7p duy nh\u1ea5t l\u00e0\u00a0<code>docker-compose.yml<\/code>\u00a0\u0111\u1ec3 k\u00edch ho\u1ea1t to\u00e0n b\u1ed9 h\u1ec7 th\u1ed1ng ch\u1ec9 b\u1eb1ng m\u1ed9t d\u00f2ng l\u1ec7nh. Ph\u01b0\u01a1ng ph\u00e1p n\u00e0y c\u0169ng gi\u00fap \u0111\u1ed3ng nh\u1ea5t m\u00f4i tr\u01b0\u1eddng ho\u1ea1t \u0111\u1ed9ng v\u00e0 d\u1ec5 d\u00e0ng sao ch\u00e9p ho\u1eb7c di chuy\u1ec3n d\u1ef1 \u00e1n sang c\u00e1c h\u1ec7 th\u1ed1ng m\u00e1y ch\u1ee7 kh\u00e1c.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"2-May-chu-web-Nginx-ket-noi-va-truyen-tin-den-WordPress-nhu-the-nao\"><\/span>2. M\u00e1y ch\u1ee7 web Nginx k\u1ebft n\u1ed1i v\u00e0 truy\u1ec1n tin \u0111\u1ebfn WordPress nh\u01b0 th\u1ebf n\u00e0o?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Container Nginx (<code>webserver<\/code>) v\u00e0 container WordPress k\u1ebft n\u1ed1i n\u1ed9i b\u1ed9 qua m\u1ed9t m\u1ea1ng c\u1ea7u \u1ea3o \u0111\u01b0\u1ee3c \u0111\u1eb7t t\u00ean l\u00e0\u00a0<code>app-network<\/code>. Trong t\u1ec7p c\u1ea5u h\u00ecnh\u00a0<code>nginx.conf<\/code>, ch\u00fang ta c\u1ea5u h\u00ecnh ch\u1ec9 th\u1ecb\u00a0<code>fastcgi_pass wordpress:9000;<\/code>. Nginx s\u1ebd ph\u00e2n gi\u1ea3i t\u00ean d\u1ecbch v\u1ee5\u00a0<code>wordpress<\/code>\u00a0th\u00e0nh \u0111\u1ecba ch\u1ec9 IP n\u1ed9i b\u1ed9 c\u1ee7a container t\u01b0\u01a1ng \u1ee9ng trong m\u1ea1ng \u1ea3o Docker v\u00e0 chuy\u1ec3n ti\u1ebfp c\u00e1c y\u00eau c\u1ea7u x\u1eed l\u00fd m\u00e3 ngu\u1ed3n PHP \u0111\u1ebfn \u0111\u00f3 m\u1ed9t c\u00e1ch an to\u00e0n.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"3-Phuong-thuc-quan-ly-thong-tin-dang-nhap-nhay-cam-nhu-mat-khau-co-so-du-lieu-duoc-thuc-hien-the-nao-de-dam-bao-tinh-an-toan\"><\/span>3. Ph\u01b0\u01a1ng th\u1ee9c qu\u1ea3n l\u00fd th\u00f4ng tin \u0111\u0103ng nh\u1eadp nh\u1ea1y c\u1ea3m (nh\u01b0 m\u1eadt kh\u1ea9u c\u01a1 s\u1edf d\u1eef li\u1ec7u) \u0111\u01b0\u1ee3c th\u1ef1c hi\u1ec7n th\u1ebf n\u00e0o \u0111\u1ec3 \u0111\u1ea3m b\u1ea3o t\u00ednh an to\u00e0n?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>To\u00e0n b\u1ed9 th\u00f4ng tin nh\u1ea1y c\u1ea3m \u0111\u01b0\u1ee3c t\u00e1ch bi\u1ec7t ho\u00e0n to\u00e0n kh\u1ecfi c\u1ea5u h\u00ecnh m\u00e3 ngu\u1ed3n v\u00e0 t\u1ec7p compose b\u1eb1ng c\u00e1ch l\u01b0u tr\u1eef t\u1eadp trung t\u1ea1i t\u1ec7p\u00a0<code>.env<\/code>. C\u1ea3 hai container\u00a0<code>db<\/code>\u00a0v\u00e0\u00a0<code>wordpress<\/code>\u00a0s\u1ebd \u0111\u1ecdc tr\u1ef1c ti\u1ebfp gi\u00e1 tr\u1ecb n\u00e0y th\u00f4ng qua ch\u1ec9 th\u1ecb\u00a0<code>env_file: .env<\/code>. B\u1eb1ng vi\u1ec7c b\u1ed5 sung t\u1ec7p\u00a0<code>.env<\/code>\u00a0v\u00e0o c\u00e1c danh s\u00e1ch t\u1eeb ch\u1ed1i theo d\u00f5i\u00a0<code>.gitignore<\/code>\u00a0v\u00e0\u00a0<code>.dockerignore<\/code>, th\u00f4ng tin \u0111\u0103ng nh\u1eadp c\u1ee7a qu\u00fd kh\u00e1ch s\u1ebd kh\u00f4ng b\u1ecb l\u1ed9 ra ngo\u00e0i internet ho\u1eb7c t\u00edch h\u1ee3p nh\u1ea7m v\u00e0o Docker image.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"4-Quy-trinh-dang-ky-chung-chi-SSL-duoc-thuc-thi-nhu-the-nao\"><\/span>4. Quy tr\u00ecnh \u0111\u0103ng k\u00fd ch\u1ee9ng ch\u1ec9 SSL \u0111\u01b0\u1ee3c th\u1ef1c thi nh\u01b0 th\u1ebf n\u00e0o?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Quy tr\u00ecnh \u0111\u01b0\u1ee3c th\u1ef1c hi\u1ec7n qua 4 giai \u0111o\u1ea1n ch\u00ednh:<\/p>\n<ol>\n<li><strong>Ch\u1ea1y th\u1eed nghi\u1ec7m (Staging)<\/strong>: Kh\u1edfi ch\u1ea1y h\u1ec7 th\u1ed1ng ban \u0111\u1ea7u v\u1edbi c\u1edd\u00a0<code>--staging<\/code>\u00a0c\u1ee7a Certbot \u0111\u1ec3 ki\u1ec3m th\u1eed k\u1ebft n\u1ed1i \u0111\u1ecbnh tuy\u1ebfn v\u00e0 tr\u00e1nh d\u00ednh c\u00e1c h\u1ea1n ch\u1ebf v\u1ec1 s\u1ed1 l\u1ea7n y\u00eau c\u1ea7u t\u1eeb t\u1ed5 ch\u1ee9c c\u1ea5p ch\u1ee9ng ch\u1ec9.<\/li>\n<li><strong>Ki\u1ec3m tra<\/strong>: X\u00e1c th\u1ef1c t\u1ec7p ch\u1ee9ng ch\u1ec9 th\u1eed nghi\u1ec7m \u0111\u01b0\u1ee3c ghi nh\u1eadn ch\u00ednh x\u00e1c t\u1ea1i th\u01b0 m\u1ee5c\u00a0<code>\/etc\/letsencrypt\/live<\/code>\u00a0c\u1ee7a m\u00e1y ch\u1ee7 web.<\/li>\n<li><strong>C\u1ea5u h\u00ecnh ch\u1ee9ng ch\u1ec9 ch\u00ednh th\u1ee9c<\/strong>: Ch\u1ec9nh s\u1eeda c\u1ea5u h\u00ecnh, lo\u1ea1i b\u1ecf tham s\u1ed1\u00a0<code>--staging<\/code>, \u0111\u1ed3ng th\u1eddi c\u1ea5u h\u00ecnh th\u00eam tham s\u1ed1\u00a0<code>--force-renewal<\/code>.<\/li>\n<li><strong>Nh\u1eadn ch\u1ee9ng ch\u1ec9 th\u1ef1c t\u1ebf<\/strong>: Ch\u1ea1y l\u1ec7nh c\u1eadp nh\u1eadt \u0111\u1ec3 Certbot th\u1ef1c hi\u1ec7n l\u1ea5y ch\u1ee9ng ch\u1ec9 b\u1ea3o m\u1eadt th\u1ef1c t\u1ebf \u0111\u1ec3 \u0111\u01b0a v\u00e0o s\u1eed d\u1ee5ng c\u00f4ng khai.<\/li>\n<\/ol>\n<h3><span class=\"ez-toc-section\" id=\"5-Co-che-tu-dong-gia-han-chung-chi-SSL-hoat-dong-ra-sao\"><\/span>5. C\u01a1 ch\u1ebf t\u1ef1 \u0111\u1ed9ng gia h\u1ea1n ch\u1ee9ng ch\u1ec9 SSL ho\u1ea1t \u0111\u1ed9ng ra sao?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Ch\u1ee9ng ch\u1ec9 SSL mi\u1ec5n ph\u00ed \u0111\u01b0\u1ee3c t\u1ef1 \u0111\u1ed9ng ki\u1ec3m tra \u0111\u1ecbnh k\u1ef3 th\u00f4ng qua m\u1ed9t t\u1eadp l\u1ec7nh shell c\u00f3 t\u00ean\u00a0<code>ssl_renew.sh<\/code>. Khi ch\u1ea1y, t\u1eadp l\u1ec7nh s\u1ebd k\u00edch ho\u1ea1t t\u1ea1m th\u1eddi container Certbot \u0111\u1ec3 ki\u1ec3m tra h\u1ea1n d\u00f9ng c\u1ee7a ch\u1ee9ng ch\u1ec9 hi\u1ec7n t\u1ea1i. N\u1ebfu ch\u1ee9ng ch\u1ec9 chu\u1ea9n b\u1ecb h\u1ebft h\u1ea1n, Certbot t\u1ef1 \u0111\u1ed9ng gia h\u1ea1n m\u1edbi v\u00e0 g\u1eedi t\u00edn hi\u1ec7u\u00a0<code>SIGHUP<\/code>\u00a0y\u00eau c\u1ea7u Nginx t\u1ea3i l\u1ea1i c\u1ea5u h\u00ecnh \u0111\u1ec3 \u00e1p d\u1ee5ng ch\u1ee9ng ch\u1ec9 m\u1edbi m\u00e0 kh\u00f4ng l\u00e0m d\u1eebng ho\u1ea1t \u0111\u1ed9ng c\u1ee7a m\u00e1y ch\u1ee7 web. Quy tr\u00ecnh n\u00e0y \u0111\u01b0\u1ee3c \u0111i\u1ec1u ph\u1ed1i t\u1ef1 \u0111\u1ed9ng h\u00e0ng ng\u00e0y b\u1eb1ng c\u00f4ng c\u1ee5 l\u1eadp l\u1ecbch t\u00e1c v\u1ee5\u00a0<code>cron<\/code>\u00a0tr\u00ean m\u00e1y ch\u1ee7.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"6-Neu-toi-tat-hoac-khoi-dong-lai-cac-container-du-lieu-trang-web-cua-toi-co-bi-mat-khong\"><\/span>6. N\u1ebfu t\u00f4i t\u1eaft ho\u1eb7c kh\u1edfi \u0111\u1ed9ng l\u1ea1i c\u00e1c container, d\u1eef li\u1ec7u trang web c\u1ee7a t\u00f4i c\u00f3 b\u1ecb m\u1ea5t kh\u00f4ng?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>D\u1eef li\u1ec7u c\u1ee7a qu\u00fd kh\u00e1ch \u0111\u01b0\u1ee3c b\u1ea3o v\u1ec7 an to\u00e0n nh\u1edd c\u01a1 ch\u1ebf\u00a0<strong>Docker Named Volumes<\/strong>\u00a0(Volume t\u0129nh \u0111\u01b0\u1ee3c \u0111\u1eb7t t\u00ean). C\u00e1c th\u01b0 m\u1ee5c quan tr\u1ecdng nh\u01b0 d\u1eef li\u1ec7u c\u01a1 s\u1edf d\u1eef li\u1ec7u (<code>\/var\/lib\/mysql<\/code>), m\u00e3 ngu\u1ed3n v\u00e0 \u1ea3nh t\u1ea3i l\u00ean c\u1ee7a WordPress (<code>\/var\/www\/html<\/code>), c\u00f9ng c\u00e1c ch\u1ee9ng ch\u1ec9 b\u1ea3o m\u1eadt (<code>\/etc\/letsencrypt<\/code>) \u0111\u1ec1u \u0111\u01b0\u1ee3c li\u00ean k\u1ebft tr\u1ef1c ti\u1ebfp v\u1edbi \u1ed5 \u0111\u0129a v\u1eadt l\u00fd c\u1ee7a m\u00e1y ch\u1ee7 VPS. Do \u0111\u00f3, c\u00e1c ho\u1ea1t \u0111\u1ed9ng t\u1eaft, b\u1eadt ho\u1eb7c n\u00e2ng c\u1ea5p container s\u1ebd kh\u00f4ng g\u00e2y m\u1ea5t m\u00e1t d\u1eef li\u1ec7u c\u1ee7a trang web.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"7-Tham-so-cau-hinh-bo-sung-trong-phan-dich-vu-db-co-y-nghia-gi\"><\/span>7. Tham s\u1ed1 c\u1ea5u h\u00ecnh b\u1ed5 sung trong ph\u1ea7n d\u1ecbch v\u1ee5\u00a0<code>db<\/code>\u00a0c\u00f3 \u00fd ngh\u0129a g\u00ec?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>K\u1ec3 t\u1eeb phi\u00ean b\u1ea3n MySQL 8.0, h\u1ec7 th\u1ed1ng s\u1eed d\u1ee5ng c\u01a1 ch\u1ebf b\u1ea3o m\u1eadt x\u00e1c th\u1ef1c m\u1eb7c \u0111\u1ecbnh m\u1edbi cao h\u01a1n. Tuy nhi\u00ean, c\u00e1c phi\u00ean b\u1ea3n PHP c\u0169 d\u00f9ng trong WordPress ch\u01b0a k\u1ecbp h\u1ed7 tr\u1ee3 chu\u1ea9n x\u00e1c th\u1ef1c m\u1edbi n\u00e0y, d\u1eabn \u0111\u1ebfn l\u1ed7i m\u1ea5t k\u1ebft n\u1ed1i c\u01a1 s\u1edf d\u1eef li\u1ec7u. Ch\u1ec9 th\u1ecb c\u1ea5u h\u00ecnh\u00a0<code>command: '--default-authentication-plugin=mysql_native_password'<\/code>\u00a0bu\u1ed9c container MySQL s\u1eed d\u1ee5ng ph\u01b0\u01a1ng th\u1ee9c x\u00e1c th\u1ef1c truy\u1ec1n th\u1ed1ng t\u01b0\u01a1ng th\u00edch t\u1ed1t v\u1edbi m\u00e3 ngu\u1ed3n PHP c\u1ee7a WordPress.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"8-Container-Nginx-lay-tep-chung-chi-SSL-tu-container-Certbot-bang-cach-nao\"><\/span>8. Container Nginx l\u1ea5y t\u1ec7p ch\u1ee9ng ch\u1ec9 SSL t\u1eeb container Certbot b\u1eb1ng c\u00e1ch n\u00e0o?<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>C\u1ea3 hai container\u00a0<code>webserver<\/code>\u00a0v\u00e0\u00a0<code>certbot<\/code>\u00a0c\u00f9ng g\u1eafn k\u1ebft chung v\u00e0o m\u1ed9t volume t\u0129nh c\u00f3 t\u00ean l\u00e0\u00a0<code>certbot-etc<\/code>\u00a0tr\u1ecf \u0111\u1ebfn th\u01b0 m\u1ee5c\u00a0<code>\/etc\/letsencrypt<\/code>. Khi Certbot ho\u00e0n t\u1ea5t vi\u1ec7c x\u00e1c th\u1ef1c v\u00e0 ghi t\u1ec7p ch\u1ee9ng ch\u1ec9 m\u1edbi v\u00e0o volume n\u00e0y, Nginx c\u00f3 th\u1ec3 ngay l\u1eadp t\u1ee9c truy c\u1eadp v\u00e0 \u0111\u1ecdc c\u00e1c t\u1ec7p kh\u00f3a b\u1ea3o m\u1eadt t\u01b0\u01a1ng \u1ee9ng \u0111\u1ec3 ph\u1ee5c v\u1ee5 vi\u1ec7c gi\u1ea3i m\u00e3 k\u1ebft n\u1ed1i HTTPS c\u1ee7a ng\u01b0\u1eddi d\u00f9ng.<\/p>\n<hr \/>\n<h2><span class=\"ez-toc-section\" id=\"Loi-Ket\"><\/span>L\u1eddi K\u1ebft<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Trong t\u00e0i li\u1ec7u h\u01b0\u1edbng d\u1eabn n\u00e0y, ch\u00fang ta \u0111\u00e3 \u00e1p d\u1ee5ng th\u00e0nh c\u00f4ng c\u00f4ng ngh\u1ec7 Docker Compose \u0111\u1ec3 x\u00e2y d\u1ef1ng nhanh ch\u00f3ng m\u1ed9t trang web WordPress ho\u1ea1t \u0111\u1ed9ng \u0111\u1ed3ng b\u1ed9 v\u1edbi m\u00e1y ch\u1ee7 web Nginx tr\u00ean n\u1ec1n t\u1ea3ng m\u00e1y ch\u1ee7 Ubuntu. Qu\u00fd kh\u00e1ch c\u0169ng \u0111\u00e3 t\u1ef1 tay b\u1ea3o m\u1eadt website c\u1ee7a m\u00ecnh b\u1eb1ng ch\u1ee9ng ch\u1ec9 b\u1ea3o m\u1eadt cao c\u1ea5p Let\u2019s Encrypt th\u00f4ng qua c\u00f4ng c\u1ee5 t\u1ef1 \u0111\u1ed9ng Certbot v\u00e0 l\u1eadp l\u1ecbch t\u1ef1 \u0111\u1ed9ng gia h\u1ea1n m\u1ed9t c\u00e1ch an to\u00e0n.<\/p>\n<p>\u0110\u1ec3 t\u1ed1i \u01b0u h\u00f3a tr\u1ea3i nghi\u1ec7m t\u1ea3i trang c\u1ee7a ng\u01b0\u1eddi d\u00f9ng v\u00e0 x\u00e2y d\u1ef1ng h\u1ec7 th\u1ed1ng website l\u1edbn m\u1ea1nh, ho\u1ea1t \u0111\u1ed9ng li\u00ean t\u1ee5c kh\u00f4ng gi\u00e1n \u0111o\u1ea1n, m\u1ed9t h\u1ea1 t\u1ea7ng l\u01b0u tr\u1eef m\u1ea1nh m\u1ebd \u0111\u00f3ng vai tr\u00f2 v\u00f4 c\u00f9ng then ch\u1ed1t. <a href=\"https:\/\/interdata.vn\/thue-vps\/\" target=\"_blank\" rel=\"noopener\"><strong>D\u1ecbch v\u1ee5\u00a0VPS c\u1ee7a InterData<\/strong><\/a>\u00a0t\u1ef1 h\u00e0o mang \u0111\u1ebfn cho qu\u00fd kh\u00e1ch gi\u1ea3i ph\u00e1p m\u00e1y ch\u1ee7 ri\u00eang \u1ea3o v\u01b0\u1ee3t tr\u1ed9i, s\u1edf h\u1eefu c\u1ea5u h\u00ecnh ph\u1ea7n c\u1ee9ng th\u1ebf h\u1ec7 m\u1edbi, t\u1ed1i \u01b0u h\u00f3a ri\u00eang cho m\u00f4i tr\u01b0\u1eddng ch\u1ea1y Docker, c\u00f9ng \u0111\u1ed9i ng\u0169 k\u1ef9 thu\u1eadt vi\u00ean gi\u00e0u kinh nghi\u1ec7m h\u1ed7 tr\u1ee3 24\/7\/365. H\u00e3y li\u00ean h\u1ec7 ngay v\u1edbi InterData \u0111\u1ec3 l\u1ef1a ch\u1ecdn g\u00f3i VPS ph\u00f9 h\u1ee3p nh\u1ea5t cho d\u1ef1 \u00e1n c\u1ee7a qu\u00fd kh\u00e1ch!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>WordPress\u00a0l\u00e0 m\u1ed9t h\u1ec7 qu\u1ea3n tr\u1ecb n\u1ed9i dung (CMS) m\u00e3 ngu\u1ed3n m\u1edf ho\u00e0n to\u00e0n mi\u1ec5n ph\u00ed, \u0111\u01b0\u1ee3c x\u00e2y d\u1ef1ng tr\u00ean n\u1ec1n t\u1ea3ng c\u01a1 s\u1edf d\u1eef li\u1ec7u MySQL v\u00e0 ng\u00f4n ng\u1eef l\u1eadp tr\u00ecnh PHP. Nh\u1edd h\u1ec7 th\u1ed1ng plugin phong ph\u00fa v\u00e0 kho giao di\u1ec7n (template) \u0111a d\u1ea1ng, h\u1ea7u h\u1ebft c\u00e1c t\u00e1c v\u1ee5 qu\u1ea3n tr\u1ecb website \u0111\u1ec1u c\u00f3<\/p>\n","protected":false},"author":2,"featured_media":41481,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[161],"tags":[],"class_list":["post-41479","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-huong-dan-chung"],"_links":{"self":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts\/41479","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/comments?post=41479"}],"version-history":[{"count":2,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts\/41479\/revisions"}],"predecessor-version":[{"id":41482,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/posts\/41479\/revisions\/41482"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/media\/41481"}],"wp:attachment":[{"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/media?parent=41479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/categories?post=41479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/interdata.vn\/blog\/wp-json\/wp\/v2\/tags?post=41479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}