Docker alapú VPS tárhely éles környezetben előnézeti képe

Docker alapú VPS tárhely éles környezetben

| Olvasási idő: 7 perc

A korábbi, témához kapcsolódó bejegyzésben már feszegettem a kérdést, hogy shared hosting helyett érdemes lehet saját üzemeltetésű VPS-t használni teszt környezetként. Újra felvéve ezt a fonalat, megírom, hogy én hogyan hosztolom élesben a saját és ügyfeleim weboldalait, VPS-en - ígérem, hogy nem lesz bonyolult. :)

Kezdjük először is azzal, hogy hova tervezünk eljutni, vagyis mik az elvárásaink:

  • a VPS-ről kiszolgált összes domain kapjon automatikusan SSL tanúsítványt, emberi közreműködés nélkül,
  • az újonnan felhúzott oldalak és domainek automatikusan legyenek elérhetőek az Internetről azt követően, hogy a domaineket a VPS-re irányítottuk és a konténereik futnak
  • a projektek teljes mértékben testreszabható futási konfigurációval rendelkezzenek, melyet verziókövetni is lehet
  • a projektek önállóan szabályozható infrastruktúrával rendelkezzenek, vagyis tetszőleges PHP, MySQL, Apache, nginx, whatever verziót használhassunk anélkül, hogy ez a többi projektet befolyásolná
  • tartsuk alacsonyan a VPS-specifikus konfigurációt, gyors "menekülési lehetőséget" hagyva magunknak egy másik VPS-re, ha valami rosszul sülne el

A fenti követelményeket hatékonyan és teljes mértékben teljesíteni tudjuk egy Docker-re épülő infrastruktúrával, mely a következőképpen épül majd fel:

  • az egyes projektek és oldalak tartalmazzák a saját production konfigurációjukat is, vagyis önálló szolgáltatáscsomagot szállítsanak a pl. docker-compose.yml fájlukban
  • a projekt önálló webszerverrel rendelkezik majd, ami (környezeti változókon keresztül) közli az egyetlen, minden projekt előtt "ülő" reverse proxy-val, hogy milyen domainhez tartozó lekéréseket szükséges az adott projekthez irányítani
  • kizárólag a reverse proxy érintkezik a külvilággal, a projektek konténerei nem elérhetőek
  • a reverse proxy a 80-as és 443-as porton keresztül érhető el, de minden forgalmat automatikusan a HTTPS protokollra irányít
  • a HTTPS-hez szükséges tanúsítványt automatikusan, a mögötte ülő projekt elindítását követően beszerzi a Let's Encrypt-et használó kísérő (companion) konténeren keresztül

Segítségül készítettem egy illusztrációt, hátha könnyebben átlátjuk így a működést:

Docker Based Hosting With Vps

a képen látható "elérési útvonalak" tetszőlegesek, csak a példa kedvéért szerepelnek

NB: A cikk további része feltételez egy beállított VPS-t, ami elérhető az Internetről, így ha ilyennel nem rendelkezel, akkor először mindenképpen hozz létre egyet. A létrehozást és beállítást követően pedig telepítsd a Docker-t is.

Reverse proxy

A reverse proxy-nk elindításához szükséges fájlok megtalálhatóak ebben a GitLab tárolóban - a folytatáshoz klónozzuk a repó-t, majd lépjünk be a könyvtárba:

bash
git clone https://gitlab.com/webmenedzser/hosting-with-docker.git && cd hosting-with-docker

Itt találunk egy docker-compose.yml fájlt, a következő tartalommal:

yaml
networks:
  nginx_reverse_proxy:
    external: false

version: '2.3'
services:

  nginx_reverse_proxy:
    build:
      context: .nginx_reverse_proxy
      dockerfile: Dockerfile
    container_name: nginx_reverse_proxy
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - .nginx_reverse_proxy/certs:/etc/nginx/certs:ro
      - .nginx_reverse_proxy/vhost.d:/etc/nginx/vhost.d
      - /usr/share/nginx/html
    networks:
      - nginx_reverse_proxy
    labels:
      - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_reverse_proxy

  letsencrypt_nginx_proxy_companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: letsencrypt_nginx_proxy_companion
    restart: always
    volumes_from:
     - nginx_reverse_proxy
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock:ro
     - .nginx_reverse_proxy/certs:/etc/nginx/certs:rw

Nem túl bonyolult konfiguráció: alapvetően csatoljuk a mappákat a konténerek azon pontjaira, ahova azokat csatolni kell (^.^), illetve beállítunk néhány alapértelmezést - ezek részleteiért keresd fel a reverse proxy, a companion image, illetve az nginx dokumentációt.

Fontos: ez a konfiguráció csak olyan böngészőkkel működik, melyek támogatják az SNI-t (vagyis Internet Explorer 8 + Windows XP kombinációval biztosan nem fog működni), cserébe a Qualys SSL Labs tesztjén A+ értékelést ér el.

Projekt konfiguráció

Ahhoz, hogy a reverse proxy megfelelően tudja a projektünk konténereire irányítani a forgalmat, jeleznünk kell, hogy melyik domainhez tartozó kéréseket szeretné a projekt, hogy a reverse proxy oda irányítsa. Ehhez a VIRTUAL_HOST és LETSENCRYPT_HOST környezeti változókat fogjuk használni: előbbi a konténerre irányítandó domainek listáját tartalmazza, a második pedig azoknak a domaineknek a listáját jelzi a companion konténernek, melyekre tanúsítványt szeretnénk igényelni. Mivel ezek nagy eséllyel megegyeznek, ezért a docker-compose.yml fájlunk "melletti" .env fájlban akár definiálhatnánk is egy változót, melyet a docker-compose.yml-ben használni fogunk. Ezenkívül a projektünkben a webszervert (a fenti ábrán kékkel jelölt elemet) csatlakoztatnunk is kell ahhoz a hálózathoz, amin az nginx reverse proxy ül (ez a példában az nginx_reverse_proxy nevű hálózat). 

.env:

VIRTUAL_HOST=www.webmenedzser.hu,webmenedzser.hu,cdn.webmenedzser.hu
[email protected]

docker-compose.yml:

yaml
networks:
  nginx_reverse_proxy:
    external: true
  default:
    external: false

volumes:
  database_volume: {}

version: '3.6'
services:

  web:
    build:
      context: ./.docker
      dockerfile: Dockerfile_webserver
    container_name: ${COMPOSE_PROJECT_NAME}_web
    working_dir: /var/www/
    restart: always
    volumes:
      - ./:/var/www/
    depends_on:
      - database
    expose:
      - 80
    networks:
      - default
      - nginx_reverse_proxy
    environment:
      - APACHE_RUN_USER=#1000
      - VIRTUAL_HOST=${VIRTUAL_HOST}
      - LETSENCRYPT_HOST=${VIRTUAL_HOST}
      - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
    logging:
      driver: json-file
      options:
        max-size: '1m'
        max-file: '3'

  database:
    image: mariadb:latest
    container_name: ${COMPOSE_PROJECT_NAME}_database
    restart: always
    environment:
     - MYSQL_USER=${DB_USER}
     - MYSQL_PASSWORD=${DB_PASSWORD}
     - MYSQL_DATABASE=${DB_DATABASE}
     - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
    expose:
     - 3306
    networks:
     - default
    volumes:
     - database_volume:/var/lib/mysql
    logging:
      driver: json-file
      options:
        max-size: '1m'
        max-file: '3'

Látszik, hogy több változót is használunk, ennek pedig az oka az, hogy - mivel a Docker képes a .env fájl használatára - a docker-compose.yml fájlunk ezáltal újrahasznosíthatóvá vált: elég, ha projektenként csak a .env fájl tartalma tér el, és akkor a docker-compose.yml fájlunkhoz nem is kell nyúlnunk (a fenti minta az aktuálisan kedvenc tartalomkezelőmhöz, Craft CMS-hez készült, WordPress-hez példa docker-compose.yml-t itt találhatsz).

Ami még említésre méltó:

  • nem teszünk elérhetővé egyetlen portot sem a hoszton, csak a Docker hálózaton keresztül (expose),
  • rövid logolást állítunk be (max 3 fájl, fájlonként max. 1 MB)
  • a konténereket MINDIG újraindítjuk: rossz lenne arra riadni, hogy nem elérhető valamelyik weboldalunk

Elindítva tehát a projektet (docker-compose up -d) a letsencrypt_nginx_proxy_companion image máris érzékeli az eventet, hogy Docker konténer indult el (docker logs letsencrypt_nginx_proxy_companion), és el is indítja a tanúsítvány generálási folyamatot. Amire eddig nem sikerült rájönnöm (vagy csak béna voltam), hogy Cloudflare-rel hogyan tudna együttműködni ez a konfiguráció, erre tehát figyelj te is: ha redirect loop-ba kerülsz, akkor törölj HSTS cache-t és vedd ki a Cloudflare-en a kapcsolódó aldomainek mögül a narancs felhőt. Frissítés: Matt Stein javaslatára átállítottam a Crypto -> SSL részt Flexible-ről Full-ra, ami - úgy tűnik - megoldotta a problémát. Ha a nem-www vagy www-s aldomained átirányítási hurokba kerülne, állíts be egy redirect rule-t a Cloudflare-n arról az aldomainről a másikra (tehát ha pl. a nem-www-s kerül loopba, akkor a nem-www => www átirányítási szabály megoldja a gondot). 

Ezzel nagyjából a bejegyzés végére is értünk: ha mindent jól csináltunk (te is és én is), akkor most van egy szervered, ami A+ minősítésű HTTPS kapcsolatot tud kiépíteni, miközben szeparáltan futnak rajta a projektjeid (akár teljesen eltérő, vagy csak verziókban különböző stackeken), és addig pakolhatsz ügyfél siteokat a szerverre, amíg bírja a VPS-ed.

Utóirat: a DigitalOcean-en még mindig 100 dollárnak megfelelő kezdeti kreditet adnak a friss regisztrálóknak - lehet, hogy valami beakadt náluk, vagy ez az új ajánlat. Mindegy: ha VPS-t szeretnél, akkor ez egy jó lehetőség a kipróbálásra. A kreditek 60 napig használható fel.

Ha bármilyen kérdésed, kérésed van, vagy hibát találtál, keress bizalommal