SSL แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ˜ Docker แƒ•แƒ”แƒ‘-แƒแƒžแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ แƒ›แƒ˜แƒœแƒ“แƒ แƒ’แƒแƒ’แƒ˜แƒ–แƒ˜แƒแƒ แƒแƒ— Docker-แƒ–แƒ” แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ—แƒฅแƒ•แƒ”แƒœแƒ˜ แƒ•แƒ”แƒ‘ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก SSL แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒก แƒ›แƒ”แƒ—แƒแƒ“แƒ˜, แƒ แƒแƒ“แƒ’แƒแƒœ... แƒ˜แƒœแƒขแƒ”แƒ แƒœแƒ”แƒขแƒ˜แƒก แƒ แƒฃแƒกแƒฃแƒšแƒ”แƒœแƒแƒ•แƒแƒœ แƒœแƒแƒฌแƒ˜แƒšแƒจแƒ˜ แƒแƒกแƒ”แƒ—แƒ˜ แƒ’แƒแƒ›แƒแƒกแƒแƒ•แƒแƒšแƒ˜ แƒ•แƒ”แƒ  แƒ•แƒ˜แƒžแƒแƒ•แƒ”.

SSL แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ˜ Docker แƒ•แƒ”แƒ‘-แƒแƒžแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

แƒ›แƒ”แƒขแƒ˜ แƒ“แƒ”แƒขแƒแƒšแƒ˜ แƒญแƒ แƒ˜แƒก แƒฅแƒ•แƒ”แƒจ.

แƒฉแƒ•แƒ”แƒœ แƒ’แƒ•แƒฅแƒแƒœแƒ“แƒ docker v.17.05, docker-compose v.1.21, Ubuntu แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ 18 แƒ“แƒ แƒ”แƒ แƒ—แƒ˜ แƒžแƒ˜แƒœแƒขแƒ˜ แƒกแƒฃแƒคแƒ—แƒ Let'sEncrypt. แƒ”แƒก แƒแƒ  แƒแƒ แƒ˜แƒก แƒ˜แƒก, แƒ แƒแƒ› แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ Docker-แƒ–แƒ” แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒ. แƒ›แƒแƒ’แƒ แƒแƒ› แƒ แƒแƒ’แƒแƒ แƒช แƒ™แƒ˜ Docker-แƒ˜แƒก แƒ›แƒจแƒ”แƒœแƒ”แƒ‘แƒšแƒแƒ‘แƒแƒก แƒ“แƒแƒ˜แƒฌแƒงแƒ”แƒ‘แƒ—, แƒจแƒ”แƒฉแƒ”แƒ แƒ”แƒ‘แƒ แƒ แƒ—แƒฃแƒšแƒ˜ แƒฎแƒ“แƒ”แƒ‘แƒ.

แƒแƒกแƒ” แƒ แƒแƒ›, แƒ“แƒแƒกแƒแƒฌแƒงแƒ˜แƒกแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒ” แƒ›แƒ˜แƒ•แƒชแƒ”แƒ› แƒกแƒขแƒแƒœแƒ“แƒแƒ แƒขแƒฃแƒš แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒก - แƒ แƒแƒช แƒ’แƒ•แƒฅแƒแƒœแƒ“แƒ แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ˜แƒก แƒ”แƒขแƒแƒžแƒ–แƒ”, แƒ”.แƒ˜. 443 แƒžแƒแƒ แƒขแƒ˜แƒก แƒ“แƒ แƒ–แƒแƒ’แƒแƒ“แƒแƒ“ SSL-แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”:

docker-compose.yml

version: '2'
services:
    php:
        build: ./php-fpm
        volumes:
            - ./StomUp:/var/www/StomUp
            - ./php-fpm/php.ini:/usr/local/etc/php/php.ini
        depends_on:
            - mysql
        container_name: "StomPHP"
    web:
        image: nginx:latest
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./StomUp:/var/www/StomUp
            - ./nginx/main.conf:/etc/nginx/conf.d/default.conf
        depends_on:
            - php
    mysql:
        image: mysql:5.7
        command: mysqld --sql_mode=""
        environment:
            MYSQL_ROOT_PASSWORD: xxx
        ports:
            - "3333:3306"

nginx/main.conf

 server {
    listen 80;
    server_name *.stomup.ru stomup.ru;
   root /var/www/StomUp/public;
     client_max_body_size 5M;

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
  }

    location ~ ^/index.php(/|$) {
      #fastcgi_pass unix:/var/run/php7.2-fpm.sock;
       fastcgi_pass php:9000;
       fastcgi_split_path_info ^(.+.php)(/.*)$;
      include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
       fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_buffer_size 128k;
       fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
       internal;
    }

    location ~ .php$ {
        return 404;
    }

     error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;
}

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒฉแƒ•แƒ”แƒœ แƒ แƒ”แƒแƒšแƒฃแƒ แƒแƒ“ แƒฃแƒœแƒ“แƒ แƒ’แƒแƒœแƒ•แƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒแƒ— SSL. แƒ›แƒแƒ แƒ—แƒแƒšแƒ˜ แƒ’แƒ˜แƒ—แƒฎแƒ แƒแƒ—, แƒ“แƒแƒแƒฎแƒšแƒแƒ”แƒ‘แƒ˜แƒ— 2 แƒกแƒแƒแƒ—แƒ˜ แƒ’แƒแƒ•แƒแƒขแƒแƒ แƒ” แƒ™แƒแƒ› แƒ–แƒแƒœแƒ˜แƒก แƒจแƒ”แƒกแƒฌแƒแƒ•แƒšแƒแƒจแƒ˜. แƒแƒฅ แƒจแƒ”แƒ›แƒแƒ—แƒแƒ•แƒแƒ–แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒงแƒ•แƒ”แƒšแƒ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜ แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒแƒ. แƒ›แƒแƒ’แƒ แƒแƒ› แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒก แƒแƒ›แƒŸแƒแƒ›แƒ˜แƒœแƒ“แƒ”แƒš แƒ”แƒขแƒแƒžแƒ–แƒ”, แƒฉแƒ•แƒ”แƒœ (แƒ‘แƒ˜แƒ–แƒœแƒ”แƒกแƒ˜) แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ“แƒ แƒกแƒฌแƒ แƒแƒคแƒแƒ“ แƒ“แƒ แƒกแƒแƒ˜แƒ›แƒ”แƒ“แƒแƒ“ แƒ’แƒแƒ“แƒแƒฎแƒ•แƒ”แƒ•แƒ SSL Let'sEnctypt ะบ nginx แƒ™แƒแƒœแƒขแƒ”แƒ˜แƒœแƒ”แƒ แƒ˜ แƒ“แƒ แƒ›แƒ”แƒขแƒ˜ แƒแƒ แƒแƒคแƒ”แƒ แƒ˜.

แƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒ แƒ˜แƒ’แƒจแƒ˜, แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒแƒ˜แƒœแƒกแƒขแƒแƒšแƒ˜แƒ แƒ”แƒ— แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ” แƒกแƒ”แƒ แƒขแƒ‘แƒแƒขแƒ˜
sudo apt-get install certbot

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒฉแƒ•แƒ”แƒœ แƒจแƒ”แƒ•แƒฅแƒ›แƒ”แƒœแƒ˜แƒ— wildcard แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ”แƒ‘แƒ˜ แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ“แƒแƒ›แƒ”แƒœแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

sudo certbot certonly -d stomup.ru -d *.stomup.ru --manual --preferred-challenges dns


แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, certbot แƒ›แƒแƒ’แƒ•แƒแƒฌแƒ•แƒ“แƒ˜แƒก 2 TXT แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒšแƒ˜ DNS แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒจแƒ˜.

_acme-challenge.stomup.ru TXT {ั‚ะพั‚ะšะปัŽั‡ะšะพั‚ะพั€ั‹ะนะ’ะฐะผะ’ั‹ะดะฐะปCertBot}


แƒ“แƒ แƒ“แƒแƒแƒญแƒ˜แƒ แƒ”แƒ— enter.

แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, certbot แƒจแƒ”แƒแƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒก แƒแƒ› แƒฉแƒแƒœแƒแƒฌแƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒแƒก DNS-แƒจแƒ˜ แƒ“แƒ แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒก แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ”แƒ‘แƒก แƒ—แƒฅแƒ•แƒ”แƒœแƒ—แƒ•แƒ˜แƒก.
แƒ—แƒฃ แƒ“แƒแƒแƒ›แƒแƒขแƒ” แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ˜ แƒ›แƒแƒ’แƒ แƒแƒ› แƒกแƒ”แƒ แƒขแƒ‘แƒแƒขแƒ˜ แƒ•แƒ”แƒ  แƒ•แƒ˜แƒžแƒแƒ•แƒ” - แƒกแƒชแƒแƒ“แƒ”แƒ— แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ 5-10 แƒฌแƒฃแƒ—แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’.

แƒแƒฅ แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ แƒ— Let'sEncrypt แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ˜แƒก แƒแƒ›แƒแƒงแƒ˜ แƒ›แƒคแƒšแƒแƒ‘แƒ”แƒšแƒ”แƒ‘แƒ˜ 90 แƒ“แƒฆแƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜, แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒฎแƒšแƒ แƒ˜แƒก แƒฃแƒœแƒ“แƒ แƒแƒ•แƒขแƒ•แƒ˜แƒ แƒ—แƒแƒ— Docker-แƒ–แƒ”.

แƒแƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก, แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒขแƒ แƒ˜แƒ•แƒ˜แƒแƒšแƒฃแƒ แƒ˜ แƒ’แƒ–แƒ˜แƒ—, docker-compose.yml-แƒจแƒ˜, nginx แƒ’แƒแƒœแƒงแƒแƒคแƒ˜แƒšแƒ”แƒ‘แƒแƒจแƒ˜, แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒ— แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ”แƒ‘แƒก.

แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜ docker-compose.yml SSL-แƒ˜แƒ—

version: '2'
services:
    php:
        build: ./php-fpm
        volumes:
            - ./StomUp:/var/www/StomUp
            - /etc/letsencrypt/live/stomup.ru/:/etc/letsencrypt/live/stomup.ru/
            - ./php-fpm/php.ini:/usr/local/etc/php/php.ini
        depends_on:
            - mysql
        container_name: "StomPHP"
    web:
        image: nginx:latest
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./StomUp:/var/www/StomUp
            - /etc/letsencrypt/:/etc/letsencrypt/
            - ./nginx/main.conf:/etc/nginx/conf.d/default.conf
        depends_on:
            - php
    mysql:
        image: mysql:5.7
        command: mysqld --sql_mode=""
        environment:
            MYSQL_ROOT_PASSWORD: xxx
        ports:
            - "3333:3306"

แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ? แƒ›แƒจแƒ•แƒ”แƒœแƒ˜แƒ”แƒ แƒ˜แƒ - แƒ’แƒแƒœแƒ•แƒแƒ’แƒ แƒซแƒแƒ—:

แƒแƒฎแƒšแƒ แƒฉแƒ•แƒ”แƒœ แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒ•แƒชแƒ•แƒแƒšแƒแƒ— แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ nginx แƒ˜แƒ›แƒฃแƒจแƒแƒแƒก 443 แƒžแƒแƒ แƒขแƒ˜ แƒ“แƒ SSL แƒ–แƒแƒ’แƒแƒ“แƒแƒ“:

แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜ main.conf แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ SSL-แƒ˜แƒ—

#
server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;

	server_name *.stomup.ru stomup.ru;
	set $base /var/www/StomUp;
	root $base/public;

	# SSL
	ssl_certificate /etc/letsencrypt/live/stomup.ru/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/stomup.ru/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/stomup.ru/chain.pem;

      client_max_body_size 5M;

      location / {
          # try to serve file directly, fallback to index.php
          try_files $uri /index.php$is_args$args;
      }

      location ~ ^/index.php(/|$) {
          #fastcgi_pass unix:/var/run/php7.2-fpm.sock;
          fastcgi_pass php:9000;
          fastcgi_split_path_info ^(.+.php)(/.*)$;
          include fastcgi_params;
          fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
          fastcgi_param DOCUMENT_ROOT $realpath_root;
          fastcgi_buffer_size 128k;
          fastcgi_buffers 4 256k;
          fastcgi_busy_buffers_size 256k;
          internal;
      }

      location ~ .php$ {
          return 404;
      }

      error_log /var/log/nginx/project_error.log;
      access_log /var/log/nginx/project_access.log;
}


# HTTP redirect
server {
	listen 80;
	listen [::]:80;

	server_name *.stomup.ru stomup.ru;

	location / {
		return 301 https://stomup.ru$request_uri;
	}
}

แƒกแƒ˜แƒœแƒแƒ›แƒ“แƒ•แƒ˜แƒšแƒ”แƒจแƒ˜, แƒแƒ› แƒ›แƒแƒœแƒ˜แƒžแƒฃแƒšแƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒฉแƒ•แƒ”แƒœ แƒ›แƒ˜แƒ•แƒ“แƒ˜แƒ•แƒแƒ แƒ— แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒจแƒ˜ Docker-compose-แƒ˜แƒ—, แƒ•แƒฌแƒ”แƒ แƒ— docker-compose up -d. แƒ“แƒ แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ— SSL-แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒแƒก. แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒฃแƒœแƒ“แƒ แƒแƒคแƒ แƒ˜แƒœแƒ“แƒ”แƒก.

แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜แƒ แƒแƒ  แƒ“แƒแƒ’แƒ•แƒแƒ•แƒ˜แƒฌแƒงแƒ“แƒ”แƒก, แƒ แƒแƒ› Let'sEnctypt แƒกแƒ”แƒ แƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ˜ แƒ’แƒแƒ˜แƒชแƒ”แƒ›แƒ 90 แƒ“แƒฆแƒ˜แƒ— แƒ“แƒ แƒ›แƒ˜แƒกแƒ˜ แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ— แƒ›แƒแƒ’แƒ˜แƒฌแƒ”แƒ•แƒ—. sudo certbot renewแƒ“แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ’แƒแƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ— แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜ แƒ‘แƒ แƒซแƒแƒœแƒ”แƒ‘แƒ˜แƒ— docker-compose restart

แƒ™แƒ˜แƒ“แƒ”แƒ• แƒ”แƒ แƒ—แƒ˜ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜แƒ แƒแƒ› แƒ—แƒแƒœแƒ›แƒ˜แƒ›แƒ“แƒ”แƒ•แƒ แƒแƒ‘แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ crontab-แƒจแƒ˜.

แƒฉแƒ”แƒ›แƒ˜ แƒแƒ–แƒ แƒ˜แƒ—, แƒ”แƒก แƒแƒ แƒ˜แƒก แƒฃแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒกแƒ˜ แƒ’แƒ–แƒ SSL-แƒ˜แƒก แƒ“แƒแƒกแƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒšแƒแƒ“ Docker Web-แƒแƒžแƒ—แƒแƒœ.

PS แƒ’แƒ—แƒฎแƒแƒ•แƒ— แƒ’แƒแƒ˜แƒ—แƒ•แƒแƒšแƒ˜แƒกแƒฌแƒ˜แƒœแƒแƒ—, แƒ แƒแƒ› แƒขแƒ”แƒฅแƒกแƒขแƒจแƒ˜ แƒฌแƒแƒ แƒ›แƒแƒ“แƒ’แƒ”แƒœแƒ˜แƒšแƒ˜ แƒงแƒ•แƒ”แƒšแƒ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒแƒ‘แƒแƒšแƒแƒ, แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜ แƒแƒฎแƒšแƒ แƒฆแƒ แƒ›แƒ Dev-แƒ˜แƒก แƒ”แƒขแƒแƒžแƒ–แƒ”แƒ, แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ›แƒ˜แƒœแƒ“แƒ แƒ’แƒ—แƒฎแƒแƒ•แƒแƒ— แƒแƒ  แƒ’แƒแƒแƒ™แƒ แƒ˜แƒขแƒ˜แƒ™แƒแƒ— แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ - แƒ˜แƒกแƒ˜แƒœแƒ˜ แƒ‘แƒ”แƒ•แƒ แƒฏแƒ”แƒ  แƒจแƒ”แƒ˜แƒชแƒ•แƒšแƒ”แƒ‘แƒ.

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ