Úvod
WordPress je jedním z nejpopulárnějších redakčních systémů (CMS) na světě. Podle statistik pohání více než 39 % všech webových stránek, které na internetu najdete. Je oblíbenou volbou díky své rozšiřitelnosti pomocí zásuvných modulů (pluginů) a flexibilnímu systému šablon. Umožňuje změnit vzhled během několika sekund. Jeho správu lze navíc provádět přes webové rozhraní, aniž by to vyžadovalo velké technické znalosti.
WordPress je navíc zdarma a s otevřeným zdrojovým kódem (open-source) a je postaven na databázi MySQL se zpracováním v PHP. WordPress můžete nasadit na stacku LAMP (Linux, Apache, MySQL a PHP) nebo stacku LEMP (Linux, Nginx, MySQL a PHP). Ukazuje se však, že nastavení tohoto stacku při každém nasazení je časově náročné.
Naštěstí moderní metody doručování softwaru, jako je cloud computing, Docker, a Docker Compose usnadnily celkovou práci vývojářů. Tyto nástroje zjednodušují proces nastavení jakéhokoli stacku tím, že eliminují režii spojenou s instalací a konfigurací jednotlivých komponent při každém nasazení aplikace. Místo toho píšete konfigurační soubory, které se použijí ke stažení a vytvoření obrazů (images) a jejich spuštění v kontejnerech Docker, což vám umožní nasadit aplikaci pomocí jediného příkazu.
Kontejnery jsou lehké, virtualizované, přenosné, softwarově definované standardizované prostředí, které umožňují softwaru běžet izolovaně od ostatního softwaru běžícího na fyzickém hostitelském stroji. Docker Compose umožňuje spravovat více kontejnerů a zajišťovat jejich vzájemnou komunikaci. Například zdrojový kód aplikace a databáze musí komunikovat.
V tomto návodu budeme vytvářet aplikaci WordPress s více kontejnery. Kompletní aplikace WordPress vyžaduje tři kontejnery: databázi MySQL, server Nginx a zdrojový kód WordPressu. Vzhledem k tomu, že bezpečnost je u moderních webových stránek prioritou, získáme SSL certifikát od Let’s Encrypt pro zabezpečení vaší instalace. Poté nastavíme úlohu cron, která bude pravidelně kontrolovat a obnovovat certifikáty, aby byla bezpečnost vašeho webu neustále zachována.
Požadavky
- Jelikož se jedná o praktický návod, měli byste mít jako výchozí operační prostředí nainstalované Ubuntu 20.04. Měli byste také mít uživatele bez oprávnění root s právy sudo. Zde je podrobný návod, který vám pomůže nastavit server Ubuntu.
- Musíte také nainstalovat Docker. Může se podívat na tento návod na téma jak nainstalovat a provozovat Docker na Ubuntu 18.04.
- Instalace Docker Compose. Můžete postupovat podle kroku 1 v návodu Jak nainstalovat a nakonfigurovat Docker Compose na Ubuntu 20.04.
- Pro získání TLS/SSL certifikátu od Let’s Encrypt je vyžadován registrovaný název domény. Pro účely tohoto návodu použijeme
example.com. - Nastavte DNS záznamy tak, aby směrovaly provoz na váš VPS. Budete potřebovat dva DNS záznamy:
- Záznam typu A s
example.comsměřující na veřejnou IP adresu vašeho serveru. - Záznam typu A s
www.example.comsměřující na veřejnou IP adresu vašeho serveru.
- Záznam typu A s
Krok 1: Definování konfigurace webového serveru
Webový server uchovává soubory vašeho webu a umožňuje uživatelům přístup k vaší webové aplikaci. Proto je vhodné v prvním kroku definovat konfiguraci webového serveru. Budeme definovat konfigurační soubor serveru Nginx, který bude obsahovat bloky location specifické pro WordPress. Zahrneme také bloky location pro přesměrování ověřovacích požadavků Let’s Encrypt na klienta Certbot pro automatické obnovování certifikátu.
Začněme vytvořením adresáře pro projekt. Můžete si vybrat název adresáře, který preferujete. V tomto návodu použijeme wordpress_docker pro tento návod. Pro vytvoření adresáře a přechod do něj zadejte následující příkaz:
|
1 |
mkdir wordpress_docker && cd wordpress_docker |
Dále vytvořte adresář pro uložení konfiguračních souborů Nginx pomocí příkazu:
|
1 |
mkdir nginx-conf |
Použijte nano k otevření souboru pomocí následujícího příkazu:
|
1 |
nano nginx-conf/nginx.conf |
V tomto souboru definujeme základní direktivy pro konfiguraci bloku serveru Nginx. Ty zahrnují direktivy pro název serveru, kořenový adresář dokumentů a bloky location pro směrování požadavků pluginu Certbot na certifikáty, statické soubory a zpracování PHP. Více se dozvíte v našem návodu na téma Jak zabezpečit Nginx pomocí Let’s Encrypt, kde se dozvíte více. Do souboru přidejte následující kód a nahraďte example.com svou registrovanou doménou:
|
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 35 36 37 38 39 40 41 42 43 44 45 |
server { listen 80; listen [::]:80; server_name example.com www.example.com; index index.php index.html index.htm; root /var/www/html; location ~ /.well-known/acme-challenge { allow all; root /var/www/html; } location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location ~ /\.ht { deny all; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; allow all; } location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ { expires max; log_not_found off; } } |
Pojďme si definovat sekce, které jste přidali:
-
Direktivy:
listen: říká Nginx, aby naslouchal na portu80. To umožňuje použití webrootu Certbotu pro vytváření požadavků na certifikáty. Jakmile získáme SSL certifikát, aktualizujeme tuto konfiguraci tak, aby používala port443.server_name: definuje doménové jméno, které má tato konfigurace obsluhovat. Provoz na doménovém jménu zde definovaném bude směrován do tohoto konkrétního bloku serveru, a tedy do kořenového adresáře dokumentůroot.root: definuje kořenový adresář pro požadavky na výše uvedené doménové jméno. Obvykle se jedná o adresář, který obsahuje skutečné soubory našeho webu. Tento adresář jsme nastavili na/var/www/html. Bude vytvořen jako přípojný bod Dockeru během sestavování kontejneru. Instrukce pro tento proces definujeme uvnitř WordPress Dockerfile.index: to definuje soubory, které budou použity jako indexy nebo vstupní bod pro váš webový server při zpracování požadavků. Přesunuli jsme index.php před index.html, aby Nginx upřednostnilindex.php.
-
Bloky Location:
location ~ /.well-known/acme-challenge: zpracovává požadavky do adresáře well-known, kam Certbot přidává dočasný soubor pro ověření, že DNS pro zadanou doménu směruje na konkrétní server, od kterého požadujeme SSL certifikáty. Proto byste pro fungování tohoto kroku měli přidat platnou doménu namístoexample.com, kterou používáme v tomto návodu.location /: zachycuje požadavky URI a předává řízení WordPressuindex.phppro vyžádání argumentů ke zpracování.location ~ \.php$: zpracovává PHP a předává požadavek kontejneru WordPress (konfigurační soubor pro tento krok definujeme v pozdějším kroku). Zde jsme definovali konfigurace specifické pro protokol FastCGI, protože Docker obraz WordPressu bude založen na obrazu php:fpm. Nginx používá nezávislý PHP procesor pro požadavky specifické pro PHP. Použijeme procesorphp-fpm, který je součástí Docker obrazuphp:fpm.location ~ /\.ht: zpracovává soubory.htaccess, které Nginx nepoužívá. Direktivadeny allzajišťuje, že tyto soubory nebudou nikdy poskytnuty návštěvníkům webu.location = /favicon.ico, location = /robots.txt: jak je vidět v definici, toto zabraňuje protokolování požadavků na soubory/favicon.icoa/robots.txt.location ~* \.(css|gif|ico|jpeg|jpg|js|png)$: vypíná protokolování požadavků na statické soubory a zajišťuje jejich ukládání do mezipaměti pro snížení zátěže serveru.
Nyní můžete soubor uložit a zavřít stisknutím CTRL+X, Y, poté ENTER. Tím je dokončen první krok.
Krok 2: Definování proměnných prostředí
Proměnné prostředí jsou nezbytné pro usnadnění komunikace mezi aplikací WordPress a databází. Zajišťují také trvalost dat aplikace. Proměnné prostředí zahrnují citlivé informace, jako jsou přihlašovací údaje k databázi, a necitlivé informace, jako je název databáze a hostitel.
Z bezpečnostních důvodů je vždy dobré nepřidávat citlivé informace do repozitářů projektu. Proto namísto nastavování citlivých hodnot v souboru Docker Compose definujeme přihlašovací údaje k MySQL uvnitř souborů .env, které nebudou odeslány do repozitáře projektu, čímž se předejde riziku veřejného odhalení. V kořenovém adresáři projektu root ~/wordpress_docker otevřete soubor .env:
|
1 |
nano .env |
|
1 2 3 |
MYSQL_ROOT_PASSWORD=your_strong_root_password MYSQL_USER=your_wordpress_database_user MYSQL_PASSWORD=strong_wordpress_database_password |
Další věc, kterou musíte udělat, je přidat soubor .env do souborů .gitignore a .dockerignore, abyste zajistili, že se nepřidá do vašich repozitářů, respektive Docker obrazů.
Pro tento návod to není nutné, ale pokud chcete pracovat s nástrojem Git pro správu verzí, zadejte následující příkaz pro inicializaci aktuálního adresáře jako git repozitáře:
|
1 |
git init |
Otevřete .gitignore pomocí nano:
|
1 |
nano .gitignore |
Přidejte následující řádek:
|
1 |
.env |
Uložte a zavřete soubor. Dále otevřete .dockerignore pomocí nano:
|
1 |
nano .dockerignore |
Přidejte následující řádek:
|
1 |
.env |
Při tom můžete volitelně přidat další soubory a adresáře spojené s vývojem vaší aplikace:
|
1 2 3 |
.env .git docker-compose.yml |
Po dokončení soubor uložte a zavřete. To je pro tento krok vše. Přejděme k definici Docker Compose.
Krok 3: Konfigurace služeb pomocí Docker Compose
Docker Compose používá docker-compose.yml soubor k sestavení obrazů. Tento soubor obsahuje definice služeb pro kompletní nastavení aplikace. Definice služeb jsou v podstatě instrukce, jak bude kontejner spuštěn. Služba je skutečně běžící kontejner.
Docker Compose umožňuje definovat různé služby pro aplikace s více kontejnery propojením různých služeb dohromady pomocí sdílených sítí a svazků. Uvidíte to v praxi, protože pro naši aplikaci budeme definovat tři kontejnery: webový server, instalaci WordPressu a databázi. Přidáme čtvrtý kontejner pro spuštění klienta Certbot pro obnovu certifikátů.
Zadejte následující příkaz pro vytvoření souboru docker-compose.yml:
|
1 |
nano docker-compose.yml |
První řádek v souboru docker-compose.yml je řádek s definicí verze. Pro náš jsme nastavili hodnotu 3. Poté můžete začít definovat své služby. Přidejte do souboru následující fragment kódu pro definování služby db:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
version: '3' services: #MySQL Service db: image: mysql:8.0 container_name: db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql command: '--default-authentication-plugin=mysql_native_password' networks: - app-network |
Pojďme si probrat, co máme v definicích služby db níže:
image: určuje obraz, na kterém bude kontejner založen. Vždy je lepší uvést konkrétní verzi (mysql:8.0) než použít značku latest (mysql:latest), protože budoucí verze obrazů MySQL mohou být v konfliktu s naší aplikací, pokud tento obraz znovu sestavíme. Více informací o osvědčených postupech pro Dockerfile najdete v oficiální dokumentaci Dockerfile.container_name: zde specifikujeme název kontejneru.restart: tato direktiva určuje chování kontejneru při restartu. Výchozí hodnota jeno, ale my jsme ji nastavili na restartování vždy (restart) pokud není ručně zastaven.env_file: tato direktiva se používá k určení umístění souboru s proměnnými prostředí (.env) používanými naší aplikací.environment: používá se k určení dalších proměnných prostředí. V tomto návodu jsme specifikovali proměnnouMYSQL_DATABASE, která bude obsahovat název databáze pro naši aplikaci. Název databáze může být zahrnut v souborudocker-compose.yml.volumes: používá se pro určení míst připojení. V našem příkladu jsme připojili pojmenovaný svazek s názvem dbdata do adresáře/var/lib/mysqlv kontejneru, což je obvykle standardní datový adresář pro MySQL.command: tato direktiva specifikuje příkaz, který přepíše výchozí instrukci CMD pro daný obraz. K standardnímu příkazumysqldobrazu Dockeru, který spouští MySQL server uvnitř kontejneru, jsme přidali volbu. Přidaná volba je--default-authentication-plugin=mysql_native_password, která aktualizuje výchozí autentizační plugin pro MySQL tak, aby používal ověřování heslem (mysql_native_password). To je nezbytné pro fungování vašeho PHP (aplikace WordPress), protože k přístupu k databázi používají uživatelské jméno a heslo. V novějších verzích MySQL se výchozí autentizační plugin změnil. Většina aplikací však používá ověřování heslem. Chcete-li tedy, aby aplikace fungovala, musíte toto nastavení změnit.networks: tato direktiva se používá k určení, že by se službadbměla připojit k sítiapp-network, kterou definujeme v průběhu návodu.
Dále definujme konfiguraci služby pro naši aplikaci WordPress. Službu a container_name pojmenujeme app. Přidejte následující fragment kódu pod definici služby db, přičemž dbejte na správné odsazení:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#Služba aplikačního kódu WordPress app: depends_on: - db image: wordpress:5.1.1-fpm-alpine container_name: app restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - app:/var/www/html networks: - app-network |
Stejně jako jsme to udělali u služby db, jsme pojmenovali náš kontejner a definovali politiku restartování. Některé další možnosti, které jsme přidali, jsou definovány níže:
depends_on: tato direktiva zajišťuje, že se kontejnery spouštějí v pořadí závislostí. V našem případě kontejnerappzávisí na kontejnerudb. Spustí se tedy až po spuštění kontejnerudb. K tomu musí dojít v tomto pořadí, protože aplikace WordPress závisí na dostupnosti databáze MySQL, aby mohla fungovat.image: jak je vidět ve fragmentu kódu, budeme používat WordPress verze 5.1.1 fpm alpine obraz. Již dříve jsme vysvětlili fungováníphp-fpm, který Nginx vyžaduje pro zpracování PHP. Tento obraz se o to postará. Obraz alpine založený na projektu Alpine Linux pomáhá udržovat velikost obrazu menší. Pokud potřebujete více informací o variantách obrazů, můžete přejít na tento odkaz pro obrazy WordPress na Docker Hubu.env_file: určuje umístění souboru.env, který obsahuje přihlašovací údaje k databázi.environment: tato direktiva definuje další proměnné prostředí. V našem případě definujeme proměnné, které WordPress očekává, a přiřazujeme jim hodnoty proměnných z našeho souboru.env. Jedná se oWORDPRESS_DB_USER,WORDPRESS_DB_PASSWORD, aWORDPRESS_DB_HOST, který odkazuje na MySQL server běžící v kontejnerudb, přístupný z výchozího portu MySQL3306. Nakonec vidíteWORDPRESS_DB_NAME, který jsme nastavili na wordpress. Stejná hodnota je specifikována v definici služby MySQL v kontejneru db:MYSQL_DATABASE=wordpress.volumes: tato direktiva připojuje svazek s názvem app do přípojného bodu/var/www/html, který vytvořil obraz WordPressu. Pojmenování svazků umožňuje sdílení aplikačního kódu s ostatními kontejnery.networks: nakonec přidáme kontejner app do sítěapp-network, abychom zajistili jeho komunikaci s ostatními kontejnery v síti.
To bude pro kontejner služby app pro obraz WordPress vše. Nyní definujme službu webserver pro obraz Nginx. Nejprve přidejte následující fragment kódu pod definici služby app ve vašem souboru docker-compose.yml:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#Služba webového serveru Nginx webserver: depends_on: - app image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" volumes: - app:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network |
Možnost depends_on jsme již vysvětlili. V případě této služby webserver se kontejner spustí po spuštění kontejneru app. Kontejner webového serveru je založen na obrazu alpine Nginx. Má podobnou politiku restartování jako předchozí definice služeb. Mezi další možnosti v definici služby webserver patří:
ports: mapuje porty mezi hostitelským strojem a kontejnerem. V Kroku 1, jsme definovali port80v souborunginx.conf. Tento port je namapován na port80v kontejneru.volumes: pod touto volbou máme kombinaci připojení typu bind a pojmenovaných svazků:app:/var/www/html: tato definice svazku připojuje aplikaci WordPress do adresáře/var/www/html, který jsme dříve nastavili jako kořenový (root) v bloku serveru Nginx../nginx-conf:/etc/nginx/conf.d: tato definice připojuje (bind mount) konfigurační adresář Nginx na hostitelském stroji do konfiguračního adresáře Nginx, který jsme definovali pro kontejner. Jakékoli změny na hostitelském stroji se proto automaticky projeví v kontejneru.certbot-etc:/etc/letsencrypt: tato definice připojuje certifikáty a klíče Let’s Encrypt pro doménu do příslušného adresáře v kontejneru.
networks: stejně jako v předchozích definicích služeb, direktivanetworkspřidává službu webserver do sítěapp-networks.
Protože jsme s definicí webového serveru hotovi, přidejme instrukce pro službu Certbot. Ta se postará o získání vašich TLS/SSL certifikátů od Let’s Encrypt. Pokud se chcete dozvědět více o zabezpečení serveru Nginx, tento návod na jak zabezpečit Nginx pomocí Let’s Encrypt je dobrým zdrojem.
Dále přidejte následující fragment kódu pod službu webserver. Nezapomeňte nastavit správný název domény a e-mailovou adresu:
|
1 2 3 4 5 6 7 8 9 10 |
#certbot service certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - app:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email hackins@cloudsigma.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com |
Kontejner certbot se spustí až poté, co se spustí webserver, a to kvůli direktivě depends_on. Docker Compose stáhne obraz Certbot z Docker Hubu tak, jak je definováno.
V rámci definice svazků (volumes) bude kontejner Certbot sdílet certifikáty a klíče domény v certbot-etc s kontejnerem Nginx webserver a kód aplikace s kontejnerem app.
V rámci definice command jsme specifikovali podpříkaz pro spuštění výchozího příkazu Certbotu certonly s dalšími volbami, jak je uvedeno níže:
-
--webroot: specifikuje použití pluginu webroot, který ukládá soubory do složky webroot pro účely ověření.--webroot-path: specifikuje cestu k adresáři webroot.--agree-tos: specifikuje, že souhlasíte s podmínkami služby ACME (Terms of Service).--no-eff-email: specifikuje, že nechcete sdílet svůj e-mail s EFF. Pokud jej sdílet chcete, můžete tuto volbu vynechat.--staging: říká Certbotu, že chcete nejprve získat testovací certifikáty ze staging prostředí Let’s Encrypt pro otestování vaší konfigurace před získáním skutečného certifikátu. Let’s Encrypt má omezení počtu požadavků na doménu (rate limiting). Prvotní otestování konfigurace vám proto pomůže vyhnout se omezení vaší domény.-d: tato volba přebírá názvy domén pro žádost o certifikát. V tomto návodu jsme zahrnuliexample.comawww.example.com. Uveďte prosím svou skutečnou registrovanou doménu.
Náš soubor docker-compose.yml je téměř kompletní. Pod službu Certbot však musíte přidat také definice sítí a svazků:
|
1 2 3 4 5 6 7 8 9 10 |
#Svazky volumes: certbot-etc: app: dbdata: #Sítě networks: app-network: driver: bridge |
Klíč volumes definuje svazky, které mají být sdíleny se všemi službami (kontejnery) definovanými v tomto souboru compose: certbot-etc, app, a dbdata. Obsah svazků, které Docker vytvoří, je uložen v adresáři spravovaném Dockerem na hostitelském souborovém systému: /var/lib/docker/volumes/. Obsah každého svazku je pak připojen k jakémukoli kontejneru, který tento svazek používá. To umožňuje sdílet data a kód mezi kontejnery.
Klíč networks definuje bridge síť, která umožňuje komunikaci mezi kontejnery. Kontejnery na stejné bridge síti, jako například webserver a db mohou bezpečně komunikovat přes porty, aniž by byl provoz vystaven vnější síti. Vystavujeme pouze port 80 pro povolení přístupu k front-endovým stránkám webu.
Kompletní soubor docker-compose.yml bude vypadat takto:
|
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
version: '3' services: #Služba MySQL db: image: mysql:8.0 container_name: db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql command: '--default-authentication-plugin=mysql_native_password' networks: - app-network #Služba aplikačního kódu WordPress app: depends_on: - db image: wordpress:5.1.1-fpm-alpine container_name: app restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - app:/var/www/html networks: - app-network #Služba webového serveru Nginx webserver: depends_on: - app image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" volumes: - app:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network #Služba certbot certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - app:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email hackins@cloudsigma.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com #Svazky volumes: certbot-etc: app: dbdata: #Sítě networks: app-network: driver: bridge |
Soubor můžete uložit a zavřít. V dalším kroku spustíme a otestujeme kontejner a požadavky na certifikáty.
Krok 4: Spuštění kontejnerů a získání SSL certifikátů
Největší výhodou Docker Compose je, že jakmile definujete všechny své služby v souboru docker-compose.yml souboru můžete spustit všechny kontejnery pomocí jediného příkazu: docker-compose up. Tento příkaz spustí každou zadanou instrukci. Pokud jsou požadavky na doménu úspěšné, měli byste ve svém terminálu vidět správný stav ukončení. Zadejte následující příkaz pro vytvoření kontejnerů. Příznak -d slouží ke spuštění kontejnerů na pozadí:
|
1 |
docker-compose up -d |
Pokud vidíte výstup jako na snímku obrazovky níže, pak byly služby úspěšně vytvořeny:
Chcete-li potvrdit stav služeb, spusťte příkaz docker-compose ps command:
|
1 |
docker-compose ps |
Výstup příkazu je zobrazen níže, pokud vše proběhlo úspěšně. Stav kontejnerů app, db, a webserver by měl být up a kontejner certbot by měl mít stav Exit0:
Pokud uvidíte cokoli jiného než Up ve sloupci stavu pro app, db nebo webserver, nebo stav Exit, který není 0 pro kontejner certbot, pak se něco pokazilo. Protokoly jednotlivých kontejnerů můžete zkontrolovat pomocí příkazu docker-compose logs a zadat service_name:
|
1 |
docker-compose logs service_name |
Protokoly kontejneru certbot můžete zkontrolovat například zadáním následujícího příkazu:
|
1 |
docker-compose logs certbot |
Chcete-li zkontrolovat, zda byly certifikáty připojeny ke kontejneru webserver, použijte příkaz docker-compose exec command:
|
1 |
docker-compose exec webserver ls -la /etc/letsencrypt/live |
Pokud jste použili skutečný registrovaný název domény jiný než example.com a žádosti o certifikát byly úspěšné, měli byste vidět výstup podobný tomuto:
Jakmile potvrdíte, že žádost o certifikát byla úspěšná, můžete upravit soubor docker-compose.yml a odebrat příznak --staging. Otevřete soubor pomocí nano:
|
1 |
nano docker-compose.yml |
Přejdete dolů k sekci definice služby Certbot, k volbě command a nahraďte příznak --staging příznakem --force-renewal. To sdělí Certbotu, že požadujete obnovení certifikátu pro stejnou doménu. Vaše definice služby Certbot by nyní měla vypadat takto:
|
1 2 3 4 5 6 7 8 9 10 |
#certbot service certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - app:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email hackins@cloudsigma.com --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com |
Po dokončení úprav soubor uložte.
Zadejte následující příkaz pro opětovné vytvoření kontejneru certbot. Zahrnutý příznak --no-deps říká Compose, aby přeskočil restartování služby webového serveru, protože již běží:
|
1 |
docker-compose up --force-recreate --no-deps Certbot |
Příkaz vygeneruje následující snímek obrazovky, který ukazuje, že žádost o certifikát byla úspěšná:
To je pro tento krok vše. V dalším kroku upravíte konfigurační soubor Nginx tak, aby obsahoval SSL certifikát.
Step 5: Enabling SSL in Nginx Configuration and Service Definition
Chcete-li, aby Nginx obsluhoval provoz přes zabezpečené SSL, nejprve upravíte konfigurační soubor Nginx a přidáte přesměrování z HTTP na HTTPS. Poté musíte specifikovat umístění certifikátu a klíče a nakonec přidat bezpečnostní parametry a hlavičky.
Před úpravou konfiguračního souboru byste měli získat doporučené bezpečnostní parametry Nginx z GitHub repozitáře Certbotu pomocí příkazu curl:
|
1 |
curl -sSLo nginx-conf/options-ssl-nginx.conf |
Příkaz se spustí a uloží parametry, které stáhne, do souboru s názvem options-ssl-nginx.conf, uvnitř adresáře nginx-conf. Odstraňte konfigurační soubor Nginx, abychom mohli vytvořit nový pomocí následujících příkazů:
|
1 2 |
rm nginx-conf/nginx.conf nano nginx-conf/nginx.conf |
Do nyní prázdného souboru nginx.conf přidejte následující kód, který obsahuje přesměrování z HTTP na HTTPS, SSL protokoly pověření a bezpečnostní hlavičky. Stejně jako předtím nahraďte doménu example.com svou vlastní registrovanou doménou:
|
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
server { listen 80; listen [::]:80; server_name example.com www.example.com; location ~ /.well-known/acme-challenge { allow all; root /var/www/html; } location / { rewrite ^ https://$host$request_uri? permanent; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com www.example.com; index index.php index.html index.htm; root /var/www/html; server_tokens off; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/nginx/conf.d/options-ssl-nginx.conf; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Zabezpečení-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # povolte strict transport security pouze v případě, že rozumíte důsledkům location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location ~ /\.ht { deny all; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; allow all; } location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ { expires max; log_not_found off; } } |
V prvním bloku serveru, který zpracovává nezabezpečené požadavky pomocí portu 80, specifikujeme webroot pro požadavky na obnovení Certbotu. Zahrnujeme také direktivu přesměrování která přesměrovává HTTP požadavky na HTTPS.
Druhý blok serveru zpracovává zabezpečený HTTPS provoz přicházející na portu 443. Jak můžete vidět, povolujeme také SSL a HTTP2. HTTP/2 zlepšuje výkon vašeho serveru. Více si o tom můžete přečíst v oficiální dokumentaci Nginx k HTTP/2.
V tomto bloku jsme také specifikovali, že Nginx zahrnuje umístění SSL certifikátu a klíče, stejně jako doporučené bezpečnostní parametry Certbotu, které curl uložil do nginx-conf/options-ssl-nginx.conf adresáře.
Dodatečné bezpečnostní hlavičky slouží ke zlepšení hodnocení vašeho webu na testovacích webech zabezpečení, jako jsou Security Headers a SSL Labs. Pro více informací můžete kliknout na odkazy u těchto hlaviček: X-Frame-Options, Referrer Policy, X-Content-Type-Options, X-XSS-Protection, Content-Security-Policy. Zakomentovali jsme hlavičku HTTP Strict Transport Security (HSTS). Můžete si přečíst o její funkci preload a rozhodnout se, zda ji chcete povolit.
Zbytek direktiv, jako je root, index, a bloky location specifické pro WordPress zůstávají stejné, jak bylo popsáno v Kroku 1. Po dokončení úprav můžete soubor uložit a zavřít.
Nyní, když jsme povolili HTTPS provoz, který využívá port 443,, musíme také povolit tento port v definici služby webového serveru. Zadejte následující příkaz pro otevření souboru docker-compose.yml pomocí nano:
|
1 |
nano docker-compose.yml |
V sekci webového serveru pod volbou ports přidejte mapování pro port 443, jak je zvýrazněno níže:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
webserver: depends_on: - app image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - app:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network |
Kompletní soubor docker-compose.yml by nyní měl vypadat takto:
|
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
verze: '3' služby: #Služba MySQL db: obraz: mysql:8.0 container_name: db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=wordpress volumes: - dbdata:/var/lib/mysql command: '--default-authentication-plugin=mysql_native_password' networks: - app-network #Služba aplikačního kódu WordPress app: depends_on: - db image: wordpress:5.1.1-fpm-alpine container_name: app restart: unless-stopped env_file: .env environment: - WORDPRESS_DB_HOST=db:3306 - WORDPRESS_DB_USER=$MYSQL_USER - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD - WORDPRESS_DB_NAME=wordpress volumes: - app:/var/www/html networks: - app-network #Služba webového serveru Nginx webserver: depends_on: - app image: nginx:1.15.12-alpine container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - app:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt networks: - app-network #Služba certbot certbot: depends_on: - webserver image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - app:/var/www/html command: certonly --webroot --webroot-path=/var/www/html --email hackins@cloudsigma.com --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com #Svazky volumes: certbot-etc: app: dbdata: #Sítě networks: app-network: driver: bridge |
Jakmile potvrdíte, že vše vypadá správně, soubor uložte a zavřete. Poté spusťte následující příkaz pro opětovné vytvoření webserver služby:
|
1 |
docker-compose up -d --force-recreate --no-deps webserver |
|
1 |
docker-compose ps |
Nyní, když všechny vaše kontejnery běží, je možné pokračovat v konfiguraci WordPressu z webového rozhraní.
Krok 6: Dokončete konfiguraci WordPressu z webového rozhraní
Přejděte na doménové jméno svého serveru a pokračujte v instalaci. Měli byste vidět úvodní stránku nastavení WordPressu. Vítá vás s možností vybrat si jazyk před pokračováním:
Vyberte svůj jazyk a klikněte na Pokračovat pro přechod na další stránku:
Na této stránce vyplňte název svého webu, zvolte si snadno zapamatovatelné uživatelské jméno a silné heslo. Z bezpečnostních důvodů se doporučuje nepoužívat Admin jako uživatelské jméno. Zadejte svůj e-mail a klikněte na tlačítko Instalovat WordPress pro zahájení instalace WordPressu.
Jakmile bude instalace dokončena, budete přesměrováni na přihlašovací obrazovku, kde zadáte uživatelské jméno a heslo, které jste nastavili. Po zadání platných přihlašovacích údajů byste měli vidět svůj administrační panel WordPressu:
Nyní jste úspěšně nainstalovali WordPress! Dále musíte provést kroky k zajištění automatického obnovování SSL certifikátů.
Krok 7: Konfigurace automatického obnovování SSL certifikátů
TLS/SSL certifikáty Let’s Encrypt jsou platné pouze 90 dní. Je na vás, abyste vytvořili konfiguraci pro automatické obnovování, která zajistí, že nevyprší. Toho můžete dosáhnout vytvořením skriptu a jeho naplánováním pomocí nástroje cron job. V tomto kroku vám ukážeme, jak vytvořit skript, který bude certifikáty obnovovat. Poté jej naplánujeme pomocí nástroje cron job, aby se pravidelně spouštěl a obnovoval certifikáty, pokud se blíží datum jejich vypršení.
Uvnitř adresáře projektu wordpress_docker otevřete skript s názvem ssl_renewer.sh pomocí nano:
|
1 |
nano ssl_renewer.sh |
Do skriptu přidejte následující kód, který se postará o automatické obnovení a opětovné načtení konfigurace Nginx. Nezapomeňte nahradit zvýrazněné uživatelské jméno svým uživatelským jménem bez oprávnění root:
|
1 2 3 4 5 6 7 8 |
#!/bin/bash COMPOSE="/usr/local/bin/docker-compose –ansi never" DOCKER="/usr/bin/docker" cd /home/hackins/wordpress_docker/ $COMPOSE run certbot renew --dry-run && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af |
In this script, we assign the docker-compose binary to a variable called COMPOSE. We also include the –ansi never option which tells the script to run docker-compose commands without ANSI control characters. We further assign the Docker binary to a variable called DOCKER.
Skript se poté přesune do našeho projektového adresáře wordpress_docker a provede následující příkazy:
docker-compose run: spustí kontejner certbot a přepíše příkaz, který jsme uvedli v definici služby certbot. Namísto spuštění podřízeného příkazu certonly spustí podřízený příkaz renew, který obnoví SSL/TLS certifikáty od Let’s Encrypt, pokud se blíží konec jejich platnosti.docker-compose kill: odešle signál SIGHUP kontejneruwebserverpro opětovné načtení konfigurací Nginx. Možná se budete chtít podívat na tento návod od Dockeru o tom, jak používat oficiální Docker obraz Nginx.docker system prune: tento příkaz odstraní všechny nepoužívané kontejnery a obrazy.
Po dokončení úprav soubor uložte a zavřete. Poté spusťte následující příkaz, abyste jej učinili spustitelným:
|
1 |
chmod +x ssl_renewer.sh |
Jakmile jej učiníte spustitelným, otevřete svůj rootovský soubor crontab, abyste skript spouštěli pravidelně v intervalech, které určíme:
|
1 |
sudo crontab -e |
Nástroj crontab vás požádá o výběr preferovaného editoru, pokud jej používáte poprvé:
Vyberte preferovaný editor a stiskněte Enter pro otevření souboru. Na konec souboru přidejte následující řádek:
|
1 |
*/5 * * * * /home/hackins/wordpress_docker/ssl_renewer.sh >> /var/log/cron_docker.log 2>&1 |
Tím se nastaví interval na pět minut, což nám umožní otestovat, zda náš skript pro obnovení bude fungovat. Specifikovali jsme také soubor protokolu, který bude obsahovat výstup z úlohy: cron_docker.log.
Počkejte pět minut a zkontrolujte cron.log, abyste zjistili, zda byl skript úspěšný s požadavkem na obnovení:
|
1 |
tail -f /var/log/cron_docker.log |
Pokud byly požadavky úspěšné, měli byste vidět něco podobného jako na snímku obrazovky níže:
Nyní, když jsme to otestovali a potvrdili, že to funguje, můžete upravit crontab soubor a nastavit denní obnovování. Například můžete chtít určit, aby se skript spouštěl každý den v 18:00. Chcete-li to provést, upravte poslední řádek crontab tak, aby vypadal takto:
|
1 |
0 18 * * * /home/hackins/wordpress_docker/ssl_renewer.sh >> /var/log/cron_docker.log 2>&1 |
Kromě toho musíte odstranit –dry-run příznak ze skriptu ssl_renewer.sh, abyste zajistili, že při jeho spuštění dojde ke skutečnému obnovení. Měl by vypadat takto:
|
1 2 3 4 5 6 7 8 |
#!/bin/bash COMPOSE="/usr/local/bin/docker-compose --ansi never" DOCKER="/usr/bin/docker" cd /home/hackins/wordpress_docker/ $COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver $DOCKER system prune -af |
Poté soubor uložte a zavřete. Jakmile to uděláte, úloha cron bude udržovat vaše certifikáty platné tím, že je obnoví před uplynutím 90 dnů.
Závěr
Pokud jste se v tomto návodu dostali až sem, můžete se považovat za o krok blíže k tomu, abyste se stali DevOps inženýrem. Dokázali jste vytvořit konfigurační skript pro Nginx, vytvořili jste docker-compose.yml soubor a definovali několik služeb potřebných ke spuštění aplikace WordPress pomocí Dockeru a Docker Compose. Získali jste SSL/TLS certifikáty od Let’s Encrypt, abyste zajistili bezpečnost svého webového serveru. Nakonec jste vytvořili úlohu cron, která zajistí, že platnost certifikátů nevyprší. Dobrá práce!
Pokud se chcete ponořit hlouběji do DevOps, podívejte se na další zdroje o kontejnerech na našem blogu:
- Seznámení s Kubernetes
- Jak nasadit aplikaci Node.js (Express.js) pomocí Dockeru na Ubuntu 20.04
- Nasadit PHP aplikaci na Kubernetes cluster s Ubuntu 18.04.
- Nasazení Laravelu, Nginx a MySQL pomocí Docker Compose
Ať se daří!










Komentáře
Zatím žádné komentáře. Buďte první.