هرچند وقت یکبار زمانی که میخوام سرور سایتم رو عوض کنم، سعی میکنم وضعیت مدیریت سرویس‌ها رو کمی بهبود بدم و کارها رو راحتتر بکنم، تو سرور قبلی همه سرویس‌ها رو برده بودم روی داکر و همه چیز بخوبی کار میکرد. این‌بار با کمک دوتا ابزار خیلی خوب فرآیند راه‌اندازی سرویس‌ها خیلی ساده‌تر و بهتر شده. توی این پست قصد دارم راه قبلی و تغییرات جدید رو بنویسم.

با دانشی که اون موقع داشتم به ازای هر سرویس یک دایرکتوری درست کرده بودم که فایل docker-compose.yml مخصوص هر سرویس درون اون تعریف شده بود و اگه سرویسی قرار بود build بشه فایل‌های مورد نیاز اون هم توی همین فولدر قرار داشت. ولی اگه سرویس تو طول مدت حیات خودش قرار بود فایلی رو ذخیره کنه یا تغییر بده، اون فایل‌ها توی دایرکتوری data بیرون این فولدر قرار میگرفتند. ساختار دایرکتوری‌ها چیزی مشابه این می‌شد.

- service1
---- docker-compose.yml
- service2
---- dokcer-compose.yml
---- src
---- Dockerfile
- data
---- service1
-----service2

ساختار یک docker-compose.yml هم بطور کلی شبیه این بود

version: '3.5'

services:
	service:
		image: dummey-image
		volumes:
			- ../data/service:/path/to/right/place
		ports:
			- "10080:80"
        

با اجرای این container  پورت 10080 سیستم عامل به پورت  ۸۰ سرویس من متصل می‌شد و من می‌تونستم توی انجین‌ایکسی که روی سیستم‌عامل نصب کردم یک دامنه تعریف کنم و اون دامنه رو به این سرویس از طریق پورت 10080 متصل کنم. علاوه بر این می‌تونستم با استفاده از cert-bot گواهینامه ssl معتبر برای دامنه‌های خودم تهیه کنم، خوشبختانه cert-bot خودش پشتیبانی خوبی از ان‌جین‌ایکس داشت و خودش تنظیمات رو بروزرسانی می‌کرد و سرویس Nginx رو ریستارت می‌کرد. ولی باز باید هر چند وقت یکبار cert-bot اجرا می‌شد تا گواهینامه‌ها بروز شوند.

server {
	server_name service.farnabaz.ir;

	location / {
		proxy_pass http://localhost:10080;
	}
}

توی سرور جدید راه کمی ساده‌تر شد و خودم رو از نصب nginx روی سیستم‌عامل خود سرور و کانفیگ اون بی‌نیاز کردم و با کمک ‍jrcs/letsencrypt-nginx-proxy-companion حتی ساخت و تمدید گواهینامه‌های ssl هم خودکار انجام می‌شوند.

برای اینکه نوشتن فایل کانفیگ nginx رو هم از سر خودم باز کنم ، از jwilder/nginx-proxy استفاده کردم. این سرویس تمامی کانتینرهایی که در حال اجرا هستند و بررسی می‌کنه و در صورتی که شرایط لازم رو داشته باشند، کانفیگ مناسب برای اونها رو ایجاد میکنه و در حقیقت اونارو به دامنه مورد نظر ما متصل می‌کنه.

version: '3.5'

services:
    nginx-proxy:
        image: jwilder/nginx-proxy
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./data/certs:/etc/nginx/certs:ro
            - /etc/nginx/vhost.d
            - /usr/share/nginx/html
            - /var/run/docker.sock:/tmp/docker.sock:ro
        labels:
            - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
        networks:
            - nginx

    nginx-letsencrypt:
        image: jrcs/letsencrypt-nginx-proxy-companion
        volumes:
            - ./data/certs:/etc/nginx/certs:rw
            - /var/run/docker.sock:/var/run/docker.sock:ro
            - /etc/nginx/vhost.d
            - /usr/share/nginx/html
        depends_on:
            - nginx-proxy
        networks:
            - nginx

networks:
    nginx:

توی کد بالا کافیگ ساده برای راه‌اندازی این دو سرویس رو می‌بینیم. نکته مهمی که توی کانفیگ بالا وجود داره اینه که، برای اینکه lets-encrypt بتونه دامنه‌هایی توسط nginx-proxy ایجاد شده رو پیدا کنه و برای اون‌ها گواهینامه بسازه باید سرویس nginx-proxy برچسب com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy رو داشته باشه.

بعد از اجرای این دو سرویس، هرسرویس دیگه‌ای که اجرا بشه و دو شرط زیر رو داشته باشه، به دامنه متصل میشه و گواهینامه معتبر خودش رو خواهد داشت.

  • کانتینری که اجرا میشه یک پورت خروجی داشته باشه. مثلا توی Dockerfile خودش دستور expose استفاده شده باشه
  • توی environment variable های کامنتینر اجرا شده دامنه مورد نظر ما و دامنه‌ای که قراره برای اون گواهینامه معتبر صادر بشه مشخص شده باشند

کد زیر محتویات docker-compose.yml یک سایت استاتیک رو نشون میده.

version: '3.5'

services:
	my_static_site:
        image: nginx
        volumes:
            - ../data/static_site:/usr/share/nginx/html
        environment:
            VIRTUAL_HOST: static.farnabaz.ir
            LETSENCRYPT_EMAIL: farnabaz@gmail.com
            LETSENCRYPT_HOST: static.farnabaz.ir
        networks:
            - nginx
        restart: always

تو این حالت دیگه نیازی به هیچ نگرانی درمورد سرویس‌ها و گواهینامه‌های فعال نیست و هر وقت نیازی به ایجاد سرویس جدید و اتصال به دامنه خاصی باشه تنها کاری که لازمه نوشتن فایل docker-compose برای اون سرویس هست. بقیه کارها بصورت خودکار انجام می‌شوند.