แƒ’แƒแƒœแƒแƒ—แƒแƒ•แƒกแƒ”แƒ— แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ Docker Swarm-แƒ˜แƒ—

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

I แƒœแƒแƒฌแƒ˜แƒšแƒ˜

แƒฏแƒ”แƒ  แƒ™แƒ˜แƒ“แƒ”แƒ• แƒจแƒแƒ แƒ”แƒฃแƒš, แƒจแƒแƒ แƒ”แƒฃแƒš แƒฌแƒ”แƒšแƒก, แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ˜แƒงแƒ CI / CD แƒžแƒ แƒแƒชแƒ”แƒกแƒ˜แƒก แƒ แƒแƒช แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒกแƒฌแƒ แƒแƒคแƒแƒ“ แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ. แƒ”แƒ แƒ—-แƒ”แƒ แƒ—แƒ˜ แƒžแƒ˜แƒ แƒแƒ‘แƒ แƒ˜แƒงแƒ Docker-แƒ˜แƒก แƒแƒ  แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ›แƒ˜แƒ–แƒ”แƒ–แƒ˜แƒก แƒ’แƒแƒ›แƒ:

  • แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒฃแƒคแƒ แƒ แƒกแƒแƒ˜แƒ›แƒ”แƒ“แƒ แƒ“แƒ แƒกแƒขแƒแƒ‘แƒ˜แƒšแƒฃแƒ แƒ˜ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒแƒจแƒ˜ (แƒ”แƒก แƒแƒ แƒ˜แƒก, แƒคแƒแƒฅแƒขแƒแƒ‘แƒ แƒ˜แƒ•แƒแƒ“, แƒ•แƒ˜แƒ แƒขแƒฃแƒแƒšแƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒแƒ  แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ)
  • แƒฌแƒแƒ›แƒงแƒ•แƒแƒœ แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ”แƒ‘แƒก แƒแƒ  แƒกแƒฃแƒ แƒ“แƒแƒ— Docker-แƒ—แƒแƒœ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ (แƒฃแƒชแƒœแƒแƒฃแƒ แƒ˜แƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒกแƒ” แƒ˜แƒงแƒ)
  • R&D แƒ›แƒ”แƒœแƒ”แƒฏแƒ›แƒ”แƒœแƒขแƒ˜แƒก แƒ˜แƒ“แƒ”แƒแƒšแƒแƒ’แƒ˜แƒฃแƒ  แƒกแƒแƒคแƒฃแƒซแƒ•แƒšแƒ”แƒ‘แƒ–แƒ”

แƒ˜แƒœแƒคแƒ แƒแƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒ, แƒ“แƒแƒกแƒขแƒ แƒ“แƒ MVP-แƒ˜แƒก แƒกแƒแƒ•แƒแƒ แƒแƒฃแƒ“แƒ แƒกแƒแƒฌแƒงแƒ˜แƒกแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜ แƒฌแƒแƒ แƒ›แƒแƒ“แƒ’แƒ”แƒœแƒ˜แƒšแƒ˜ แƒ˜แƒงแƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒœแƒแƒ˜แƒ แƒแƒ“:

  • 4 Intelยฎ X5650 แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ Debian-แƒ˜แƒ— (แƒ™แƒ˜แƒ“แƒ”แƒ• แƒ”แƒ แƒ—แƒ˜ แƒซแƒšแƒ˜แƒ”แƒ แƒ˜ แƒ›แƒแƒœแƒฅแƒแƒœแƒ แƒกแƒ แƒฃแƒšแƒแƒ“ แƒแƒ แƒ˜แƒก แƒ’แƒแƒœแƒ•แƒ˜แƒ—แƒแƒ แƒ”แƒ‘แƒฃแƒšแƒ˜)
  • แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜ แƒžแƒ”แƒ แƒกแƒแƒœแƒแƒšแƒฃแƒ แƒ˜ แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒ แƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ”แƒ‘แƒ C ++, Python3-แƒจแƒ˜
  • แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒ˜ แƒ›แƒ”แƒกแƒแƒ›แƒ” แƒ›แƒฎแƒแƒ แƒ˜แƒก แƒ˜แƒœแƒกแƒขแƒ แƒฃแƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜: Kafka, Clickhouse, Airflow, Redis, Grafana, Postgresql, Mysql,โ€ฆ
  • แƒ›แƒ˜แƒšแƒกแƒแƒ“แƒ”แƒœแƒ”แƒ‘แƒ˜ แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒ›แƒจแƒ”แƒœแƒ”แƒ‘แƒšแƒแƒ‘แƒ˜แƒกแƒ แƒ“แƒ แƒขแƒ”แƒกแƒขแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒชแƒแƒšแƒ™แƒ” แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒกแƒ แƒ“แƒ แƒ’แƒแƒ›แƒแƒจแƒ•แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก

แƒ”แƒ แƒ—-แƒ”แƒ แƒ—แƒ˜ แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฃแƒœแƒ“แƒ แƒ’แƒแƒœแƒ˜แƒฎแƒ˜แƒšแƒ”แƒ‘แƒแƒ“แƒ”แƒก แƒกแƒแƒฌแƒงแƒ˜แƒก แƒ”แƒขแƒแƒžแƒ–แƒ”, แƒแƒ แƒ˜แƒก แƒ˜แƒก, แƒ—แƒฃ แƒ แƒแƒ’แƒแƒ  แƒ’แƒแƒœแƒšแƒแƒ’แƒ“แƒ”แƒ‘แƒ แƒกแƒแƒ‘แƒแƒŸแƒ แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ  แƒ’แƒแƒ แƒ”แƒ›แƒแƒจแƒ˜ (CI / CD).

แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ”แƒ— แƒ›แƒ”แƒกแƒแƒ›แƒ” แƒ›แƒฎแƒแƒ แƒ˜แƒก แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒแƒ“ แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ“แƒ แƒ›แƒแƒ—แƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒ’แƒแƒœแƒแƒฎแƒšแƒ”แƒ‘แƒ. C++ แƒแƒœ Python-แƒจแƒ˜ แƒจแƒ”แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒžแƒ”แƒ แƒกแƒแƒœแƒแƒšแƒฃแƒ แƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ“แƒ”แƒก แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ’แƒ–แƒ˜แƒ—. แƒ›แƒแƒ— แƒจแƒแƒ แƒ˜แƒก, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“: แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒฃแƒ แƒ˜ แƒžแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ, แƒฉแƒแƒจแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒชแƒแƒ•แƒจแƒ˜ แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ แƒ“แƒ แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ”แƒ‘แƒ–แƒ” แƒ˜แƒœแƒกแƒขแƒแƒšแƒแƒชแƒ˜แƒ. แƒ’แƒแƒฃแƒ แƒ™แƒ•แƒ”แƒ•แƒ”แƒšแƒ˜ แƒ›แƒ˜แƒ–แƒ”แƒ–แƒ˜แƒก แƒ’แƒแƒ›แƒ, แƒแƒ แƒฉแƒ”แƒฃแƒšแƒ˜ แƒ˜แƒฅแƒœแƒ แƒกแƒฎแƒ•แƒ แƒ›แƒ”แƒ—แƒแƒ“แƒ˜, แƒ™แƒ”แƒ แƒซแƒแƒ“: CI-แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒแƒ“แƒ˜ แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ, แƒ•แƒ˜แƒ แƒขแƒฃแƒแƒšแƒฃแƒ แƒ˜ แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒก แƒ’แƒแƒ แƒ”แƒ›แƒแƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ, py แƒ›แƒแƒ“แƒฃแƒšแƒ”แƒ‘แƒ˜แƒก แƒ˜แƒœแƒกแƒขแƒแƒšแƒแƒชแƒ˜แƒ แƒ“แƒแƒ˜แƒœแƒกแƒขแƒแƒšแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜.txt-แƒ“แƒแƒœ แƒ“แƒ แƒงแƒ•แƒ”แƒšแƒ แƒ”แƒก แƒแƒ แƒขแƒ”แƒคแƒแƒฅแƒขแƒ˜ แƒ˜แƒ’แƒ–แƒแƒ•แƒœแƒ”แƒ‘แƒ แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ”แƒ‘แƒ—แƒแƒœ, แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ—แƒแƒœ แƒ“แƒ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒ—แƒแƒœแƒ›แƒฎแƒšแƒ”แƒ‘แƒ˜ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒ›แƒ. แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ แƒ˜แƒฎแƒกแƒœแƒ”แƒ‘แƒ แƒ แƒแƒ’แƒแƒ แƒช แƒ•แƒ˜แƒ แƒขแƒฃแƒแƒšแƒฃแƒ แƒ˜ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒ˜ แƒแƒ“แƒ›แƒ˜แƒœแƒ˜แƒกแƒขแƒ แƒแƒขแƒแƒ แƒ˜แƒก แƒฃแƒคแƒšแƒ”แƒ‘แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”.

Gitlab-CI แƒแƒ˜แƒ แƒฉแƒ˜แƒ”แƒก CI/CD แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒแƒ“. แƒจแƒ”แƒ“แƒ”แƒ’แƒแƒ“ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒ˜แƒšแƒกแƒแƒ“แƒ”แƒœแƒ˜ แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒแƒ“แƒ:

แƒ’แƒแƒœแƒแƒ—แƒแƒ•แƒกแƒ”แƒ— แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ Docker Swarm-แƒ˜แƒ—
แƒกแƒขแƒ แƒฃแƒฅแƒขแƒฃแƒ แƒฃแƒšแƒแƒ“, gitlab-ci.yml แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒแƒ“แƒ

---
variables:
  # ะผะธะฝะธะผะฐะปัŒะฝะฐั ะฒะตั€ัะธั ะฆะŸะฃ ะฝะฐ ัะตั€ะฒะตั€ะฐั…, ะณะดะต ั€ะฐะทะฒะพั€ะฐั‡ะธะฒะฐะตั‚ัั ะบะปะฐัั‚ะตั€
  CMAKE_CPUTYPE: "westmere"

  DEBIAN: "MYREGISTRY:5000/debian:latest"

before_script:
  - eval $(ssh-agent -s)
  - ssh-add <(echo "$SSH_PRIVATE_KEY")
  - mkdir -p ~/.ssh && echo -e "Host *ntStrictHostKeyChecking nonn" > ~/.ssh/config

stages:
  - build
  - testing
  - deploy

debug.debian:
  stage: build
  image: $DEBIAN
  script:
    - cd builds/release && ./build.sh
    paths:
      - bin/
      - builds/release/bin/
    when: always
release.debian:
  stage: build
  image: $DEBIAN
  script:
    - cd builds/release && ./build.sh
    paths:
      - bin/
      - builds/release/bin/
    when: always

## testing stage
tests.codestyle:
  stage: testing
  image: $DEBIAN
  dependencies:
    - release.debian
  script:
    - /bin/bash run_tests.sh -t codestyle -b "${CI_COMMIT_REF_NAME}_codestyle"
tests.debug.debian:
  stage: testing
  image: $DEBIAN
  dependencies:
    - debug.debian
  script:
    - /bin/bash run_tests.sh -e codestyle/test_pylint.py -b "${CI_COMMIT_REF_NAME}_debian_debug"
  artifacts:
    paths:
      - run_tests/username/
    when: always
    expire_in: 1 week
tests.release.debian:
  stage: testing
  image: $DEBIAN
  dependencies:
    - release.debian
  script:
    - /bin/bash run_tests.sh -e codestyle/test_pylint.py -b "${CI_COMMIT_REF_NAME}_debian_release"
  artifacts:
    paths:
      - run_tests/username/
    when: always
    expire_in: 1 week

## staging stage
deploy_staging:
  stage: deploy
  environment: staging
  image: $DEBIAN
  dependencies:
    - release.debian
  script:
    - cd scripts/deploy/ &&
        python3 createconfig.py -s $CI_ENVIRONMENT_NAME &&
        /bin/bash install_venv.sh -d -r ../../requirements.txt &&
        python3 prepare_init.d.py &&
        python3 deploy.py -s $CI_ENVIRONMENT_NAME
  when: manual

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

แƒ›แƒแƒ แƒ—แƒแƒšแƒ˜แƒ แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒ”แƒ‘แƒจแƒ˜ แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒ”แƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒ—แƒแƒ•แƒ˜แƒกแƒ”แƒ‘แƒฃแƒ แƒแƒ“ แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒแƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ แƒ แƒ—แƒฅแƒ›แƒ แƒฃแƒœแƒ“แƒ แƒ›แƒแƒ—แƒ–แƒ” แƒแƒ  แƒ•แƒ˜แƒกแƒแƒฃแƒ‘แƒ แƒ”แƒ‘, แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒ›แƒแƒ—แƒ’แƒแƒœแƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒแƒก แƒ“แƒ˜แƒ“แƒ˜ แƒ“แƒ แƒ แƒ“แƒแƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒ“แƒ แƒ”แƒก แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒ›แƒ˜แƒ–แƒแƒœแƒ˜. แƒ›แƒ” แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ—แƒฅแƒ•แƒ”แƒœแƒก แƒงแƒฃแƒ แƒแƒ“แƒฆแƒ”แƒ‘แƒแƒก แƒ’แƒแƒ•แƒแƒ›แƒแƒฎแƒ•แƒ˜แƒšแƒ”แƒ‘ แƒ˜แƒ› แƒคแƒแƒฅแƒขแƒ–แƒ”, แƒ แƒแƒ› แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒก แƒ”แƒขแƒแƒžแƒ˜ แƒจแƒ”แƒ“แƒ’แƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ˜แƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜แƒก แƒ—แƒแƒœแƒ›แƒ˜แƒ›แƒ“แƒ”แƒ•แƒ แƒแƒ‘แƒ˜แƒกแƒ’แƒแƒœ:

  1. createconfig.py - แƒฅแƒ›แƒœแƒ˜แƒก settings.ini แƒคแƒแƒ˜แƒšแƒก แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ˜แƒก แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜แƒ— แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒ’แƒแƒ แƒ”แƒ›แƒแƒจแƒ˜ แƒจแƒ”แƒ›แƒ“แƒ’แƒแƒ›แƒ˜ แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก (แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ แƒ˜ แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒ, แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒ, แƒขแƒ”แƒกแƒขแƒ˜แƒ แƒ”แƒ‘แƒ, ...)
  2. install_venv.sh - แƒฅแƒ›แƒœแƒ˜แƒก แƒ•แƒ˜แƒ แƒขแƒฃแƒแƒšแƒฃแƒ  แƒ’แƒแƒ แƒ”แƒ›แƒแƒก py แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ™แƒแƒœแƒ™แƒ แƒ”แƒขแƒฃแƒš แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒจแƒ˜ แƒ“แƒ แƒแƒ™แƒแƒžแƒ˜แƒ แƒ”แƒ‘แƒก แƒ›แƒแƒก แƒ“แƒ˜แƒกแƒขแƒแƒœแƒชแƒ˜แƒฃแƒ  แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ”แƒ‘แƒ–แƒ”
  3. แƒ›แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒ_init.d.py โ€” แƒแƒ›แƒ–แƒแƒ“แƒ”แƒ‘แƒก start-stop แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒก แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒจแƒแƒ‘แƒšแƒแƒœแƒ–แƒ” แƒ“แƒแƒงแƒ แƒ“แƒœแƒแƒ‘แƒ˜แƒ—
  4. deploy.py - แƒ˜แƒจแƒšแƒ”แƒ‘แƒ แƒ“แƒ แƒ’แƒแƒœแƒแƒแƒฎแƒšแƒ”แƒ‘แƒก แƒแƒฎแƒแƒš แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒก

แฒ“แƒ แƒ แƒ’แƒแƒ•แƒ˜แƒ“แƒ. แƒ“แƒแƒ“แƒ’แƒ›แƒ˜แƒก แƒ”แƒขแƒแƒžแƒ˜ แƒจแƒ”แƒ˜แƒชแƒ•แƒแƒšแƒ แƒฌแƒ˜แƒœแƒแƒกแƒฌแƒแƒ แƒ˜ แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒ˜แƒ—แƒ แƒ“แƒ แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒ˜แƒ—. แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒžแƒ แƒแƒ“แƒฃแƒฅแƒขแƒ˜แƒก แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ แƒกแƒฎแƒ•แƒ แƒ“แƒ˜แƒกแƒขแƒ แƒ˜แƒ‘แƒฃแƒชแƒ˜แƒแƒ–แƒ” (CentOS). แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ™แƒ˜แƒ“แƒ”แƒ• 5 แƒซแƒšแƒ˜แƒ”แƒ แƒ˜ แƒคแƒ˜แƒ–แƒ˜แƒ™แƒฃแƒ แƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜ แƒ“แƒ แƒแƒ—แƒ”แƒฃแƒšแƒ˜ แƒ•แƒ˜แƒ แƒขแƒฃแƒแƒšแƒฃแƒ แƒ˜. แƒ“แƒ แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ“แƒ แƒขแƒ”แƒกแƒขแƒ”แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒฃแƒคแƒ แƒ แƒ“แƒ แƒฃแƒคแƒ แƒ แƒ แƒ—แƒฃแƒšแƒ˜ แƒ’แƒแƒฎแƒ“แƒ แƒ›แƒแƒ—แƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒขแƒ”แƒกแƒขแƒ˜แƒ แƒ”แƒ‘แƒ แƒกแƒแƒ›แƒฃแƒจแƒแƒ แƒ›แƒ“แƒ’แƒแƒ›แƒแƒ แƒ”แƒแƒ‘แƒแƒกแƒ—แƒแƒœ แƒ›แƒ”แƒข-แƒœแƒแƒ™แƒšแƒ”แƒ‘แƒแƒ“ แƒ›แƒ˜แƒแƒฎแƒšแƒแƒ”แƒ‘แƒฃแƒš แƒ’แƒแƒ แƒ”แƒ›แƒแƒจแƒ˜. แƒแƒ› แƒ“แƒ แƒแƒก แƒ’แƒแƒ˜แƒ แƒ™แƒ•แƒ, แƒ แƒแƒ› แƒ›แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ” แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒ˜แƒงแƒ ...

แƒœแƒแƒฌแƒ˜แƒšแƒ˜ II

แƒ’แƒแƒœแƒแƒ—แƒแƒ•แƒกแƒ”แƒ— แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ Docker Swarm-แƒ˜แƒ—

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

แƒ—แƒ”แƒแƒ แƒ˜แƒฃแƒšแƒแƒ“, แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒ“แƒ”แƒก แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒ˜ แƒ”แƒ แƒ—แƒ“แƒ แƒแƒฃแƒšแƒแƒ“: แƒ˜แƒ›แƒ“แƒ”แƒœแƒ˜, แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒช แƒแƒ แƒ˜แƒก แƒ“แƒแƒ•แƒแƒšแƒ”แƒ‘แƒ แƒ“แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒฃแƒš แƒ›แƒ“แƒ’แƒแƒ›แƒแƒ แƒ”แƒแƒ‘แƒแƒจแƒ˜ แƒแƒœ แƒ“แƒแƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒแƒ›แƒ“แƒ”. แƒฉแƒ•แƒ”แƒœแƒก แƒฎแƒ”แƒšแƒ— แƒแƒ แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒ•แƒแƒซแƒšแƒ”แƒ•แƒก แƒ’แƒแƒ•แƒฃแƒจแƒ•แƒแƒ— แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒ˜ แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒš แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ”. แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ แƒ“แƒแƒ“แƒ’แƒ›แƒ˜แƒก แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒ˜ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ˜แƒ–แƒแƒšแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ (แƒแƒ  แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ™แƒ•แƒ”แƒ—แƒ แƒžแƒแƒ แƒขแƒ”แƒ‘แƒจแƒ˜, แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒจแƒ˜ แƒ“แƒ แƒ.แƒจ.).

แƒฉแƒ•แƒ”แƒœแƒ˜ แƒงแƒ•แƒ”แƒšแƒแƒ–แƒ” แƒซแƒ•แƒ˜แƒ แƒคแƒแƒกแƒ˜ แƒ แƒ”แƒกแƒฃแƒ แƒกแƒ˜ แƒแƒ แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ“แƒ แƒ แƒ“แƒ แƒ‘แƒ”แƒ•แƒ แƒ˜ แƒแƒ  แƒ’แƒ•แƒฅแƒแƒœแƒ“แƒ.

แƒฃแƒคแƒ แƒ แƒกแƒฌแƒ แƒแƒคแƒ˜ แƒ“แƒแƒฌแƒงแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒฉแƒ•แƒ”แƒœ แƒแƒ•แƒ˜แƒ แƒฉแƒ˜แƒ”แƒ— Docker Swarm แƒ›แƒ˜แƒกแƒ˜ แƒกแƒ˜แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜แƒกแƒ แƒ“แƒ แƒแƒ แƒฅแƒ˜แƒขแƒ”แƒฅแƒขแƒฃแƒ แƒฃแƒšแƒ˜ แƒ›แƒแƒฅแƒœแƒ˜แƒšแƒแƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ. แƒžแƒ˜แƒ แƒ•แƒ”แƒšแƒ˜ แƒ แƒแƒช แƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒ”แƒ— แƒ˜แƒงแƒ แƒ›แƒ”แƒœแƒ”แƒฏแƒ”แƒ แƒ˜แƒก แƒ“แƒ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ™แƒ•แƒแƒœแƒซแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ แƒ“แƒ˜แƒกแƒขแƒแƒœแƒชแƒ˜แƒฃแƒ  แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ”แƒ‘แƒ–แƒ”:

$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
kilqc94pi2upzvabttikrfr5d     nop-test-1     Ready               Active                                  19.03.2
jilwe56pl2zvabupryuosdj78     nop-test-2     Ready               Active                                  19.03.2
j5a4yz1kr2xke6b1ohoqlnbq5 *   nop-test-3     Ready               Active              Leader              19.03.2

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒจแƒ”แƒฅแƒ›แƒ”แƒœแƒ˜แƒ— แƒฅแƒกแƒ”แƒšแƒ˜:


$ docker network create --driver overlay --subnet 10.10.10.0/24 nw_swarm

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, แƒฉแƒ•แƒ”แƒœ แƒ“แƒแƒ•แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ— Gitlab-CI แƒ“แƒ Swarm แƒ™แƒ•แƒแƒœแƒซแƒ”แƒ‘แƒ˜ CI-แƒ“แƒแƒœ แƒ™แƒ•แƒแƒœแƒซแƒ”แƒ‘แƒ˜แƒก แƒ“แƒ˜แƒกแƒขแƒแƒœแƒชแƒ˜แƒฃแƒ แƒ˜ แƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒก แƒ—แƒ•แƒแƒšแƒกแƒแƒ–แƒ แƒ˜แƒกแƒ˜แƒ—: แƒกแƒ”แƒ แƒ—แƒ˜แƒคแƒ˜แƒ™แƒแƒขแƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ, แƒกแƒแƒ˜แƒ“แƒฃแƒ›แƒšแƒ แƒชแƒ•แƒšแƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ“แƒ Docker แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜แƒก แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒกแƒแƒ™แƒแƒœแƒขแƒ แƒแƒšแƒ แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ–แƒ”. แƒ”แƒก แƒ”แƒ แƒ—แƒ˜ แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒ“แƒแƒ’แƒ•แƒ˜แƒ–แƒแƒ’แƒ แƒ‘แƒ”แƒ•แƒ แƒ˜ แƒ“แƒ แƒ.

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ“แƒแƒ•แƒแƒ›แƒแƒขแƒ”แƒ— แƒกแƒขแƒ”แƒ™แƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒกแƒ แƒ“แƒ แƒ’แƒแƒœแƒแƒ“แƒ’แƒฃแƒ แƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒ”แƒ‘แƒ˜ .gitlab-ci .yml-แƒก.

แƒ™แƒ˜แƒ“แƒ”แƒ• แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ•แƒแƒ™แƒแƒœแƒกแƒ˜แƒ แƒ“แƒแƒ”แƒ›แƒแƒขแƒ .gitlab-ci .yml

## staging stage
deploy_staging:
  stage: testing
  before_script:
    - echo "override global 'before_script'"
  image: "REGISTRY:5000/docker:latest"
  environment: staging
  dependencies: []
  variables:
    DOCKER_CERT_PATH: "/certs"
    DOCKER_HOST: tcp://10.50.173.107:2376
    DOCKER_TLS_VERIFY: 1
    CI_BIN_DEPENDENCIES_JOB: "release.centos.7"
  script:
    - mkdir -p $DOCKER_CERT_PATH
    - echo "$TLSCACERT" > $DOCKER_CERT_PATH/ca.pem
    - echo "$TLSCERT" > $DOCKER_CERT_PATH/cert.pem
    - echo "$TLSKEY" > $DOCKER_CERT_PATH/key.pem
    - docker stack deploy -c docker-compose.yml ${CI_ENVIRONMENT_NAME}_${CI_COMMIT_REF_NAME} --with-registry-auth
    - rm -rf $DOCKER_CERT_PATH
  when: manual

## stop staging stage
stop_staging:
  stage: testing
  before_script:
    - echo "override global 'before_script'"
  image: "REGISTRY:5000/docker:latest"
  environment: staging
  dependencies: []
  variables:
    DOCKER_CERT_PATH: "/certs"
    DOCKER_HOST: tcp://10.50.173.107:2376
    DOCKER_TLS_VERIFY: 1
  script:
    - mkdir -p $DOCKER_CERT_PATH
    - echo "$TLSCACERT" > $DOCKER_CERT_PATH/ca.pem
    - echo "$TLSCERT" > $DOCKER_CERT_PATH/cert.pem
    - echo "$TLSKEY" > $DOCKER_CERT_PATH/key.pem
    - docker stack rm ${CI_ENVIRONMENT_NAME}_${CI_COMMIT_REF_NAME}
    # TODO: need check that stopped
  when: manual

แƒ–แƒ”แƒ›แƒแƒ— แƒ›แƒแƒชแƒ”แƒ›แƒฃแƒšแƒ˜ แƒ™แƒแƒ“แƒ˜แƒก แƒคแƒ แƒแƒ’แƒ›แƒ”แƒœแƒขแƒ˜แƒ“แƒแƒœ แƒฎแƒ”แƒ“แƒแƒ•แƒ—, แƒ แƒแƒ› แƒแƒ แƒ˜ แƒฆแƒ˜แƒšแƒแƒ™แƒ˜ (deploy_staging, stop_staging) แƒ“แƒแƒ”แƒ›แƒแƒขแƒ Pipelines-แƒก, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒกแƒแƒญแƒ˜แƒ แƒแƒ”แƒ‘แƒ”แƒœ แƒฎแƒ”แƒšแƒ˜แƒ— แƒ›แƒแƒฅแƒ›แƒ”แƒ“แƒ”แƒ‘แƒแƒก.

แƒ’แƒแƒœแƒแƒ—แƒแƒ•แƒกแƒ”แƒ— แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜ Docker Swarm-แƒ˜แƒ—
แƒกแƒขแƒ”แƒ™แƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒ˜ แƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒ แƒคแƒ˜แƒšแƒ˜แƒแƒšแƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒก แƒ“แƒ แƒ”แƒก แƒฃแƒœแƒ˜แƒ™แƒแƒšแƒฃแƒ แƒแƒ‘แƒ แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก. แƒ“แƒแƒกแƒขแƒแƒจแƒ˜ แƒแƒ แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ”แƒ‘แƒ˜ แƒ˜แƒฆแƒ”แƒ‘แƒ”แƒœ แƒฃแƒœแƒ˜แƒ™แƒแƒšแƒฃแƒ  ip แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ”แƒ‘แƒก แƒ“แƒ แƒžแƒแƒ แƒขแƒ”แƒ‘แƒก, แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ”แƒ‘แƒก แƒ“แƒ แƒ.แƒจ. แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒ˜แƒ–แƒแƒšแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒ“แƒแƒกแƒขแƒแƒ“แƒแƒœ แƒกแƒขแƒ”แƒ™แƒแƒ›แƒ“แƒ” (แƒ แƒแƒ“แƒ’แƒแƒœ แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ˜ แƒงแƒ•แƒ”แƒšแƒ แƒกแƒขแƒ”แƒ™แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ”แƒ แƒ—แƒœแƒแƒ˜แƒ แƒ˜แƒ) - แƒ แƒแƒช แƒ’แƒ•แƒ˜แƒœแƒ“แƒแƒ“แƒ. แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ— แƒกแƒขแƒ”แƒ™แƒ˜แƒก (แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒก) แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— docker-compose.yml, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒฆแƒฌแƒ”แƒ แƒก แƒฉแƒ•แƒ”แƒœแƒก แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒก.

docker-compose.yml

---
version: '3'

services:
  userprop:
    image: redis:alpine
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:
  celery_bcd:
    image: redis:alpine
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

  schedulerdb:
    image: mariadb:latest
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      MYSQL_DATABASE: schedulerdb
      MYSQL_USER: ****
      MYSQL_PASSWORD: ****
    command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci', '--explicit_defaults_for_timestamp=1']
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

  celerydb:
    image: mariadb:latest
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      MYSQL_DATABASE: celerydb
      MYSQL_USER: ****
      MYSQL_PASSWORD: ****
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

  cluster:
    image: $CENTOS7
    environment:
      - CENTOS
      - CI_ENVIRONMENT_NAME
      - CI_API_V4_URL
      - CI_REPOSITORY_URL
      - CI_PROJECT_ID
      - CI_PROJECT_URL
      - CI_PROJECT_PATH
      - CI_PROJECT_NAME
      - CI_COMMIT_REF_NAME
      - CI_BIN_DEPENDENCIES_JOB
    command: >
      sudo -u myusername -H /bin/bash -c ". /etc/profile &&
        mkdir -p /storage1/$CI_COMMIT_REF_NAME/$CI_PROJECT_NAME &&
        cd /storage1/$CI_COMMIT_REF_NAME/$CI_PROJECT_NAME &&
            git clone -b $CI_COMMIT_REF_NAME $CI_REPOSITORY_URL . &&
            curl $CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=$CI_BIN_DEPENDENCIES_JOB -o artifacts.zip &&
            unzip artifacts.zip ;
        cd /storage1/$CI_COMMIT_REF_NAME/$CI_PROJECT_NAME/scripts/deploy/ &&
            python3 createconfig.py -s $CI_ENVIRONMENT_NAME &&
            /bin/bash install_venv.sh -d -r ../../requirements.txt &&
            python3 prepare_init.d.py &&
            python3 deploy.py -s $CI_ENVIRONMENT_NAME"
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    tty: true
    stdin_open: true
    networks:
      nw_swarm:

networks:
  nw_swarm:
    external: true

แƒแƒฅ แƒฎแƒ”แƒ“แƒแƒ•แƒ—, แƒ แƒแƒ› แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ”แƒ แƒ—แƒ˜ แƒฅแƒกแƒ”แƒšแƒ˜แƒ— (nw_swarm) แƒ“แƒ แƒฎแƒ”แƒšแƒ›แƒ˜แƒกแƒแƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒ แƒ”แƒ แƒ—แƒ›แƒแƒœแƒ”แƒ—แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ (แƒ แƒ”แƒ“แƒ˜แƒก, mysql-แƒ–แƒ” แƒ“แƒแƒคแƒฃแƒซแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜) แƒ’แƒแƒ›แƒแƒงแƒแƒคแƒ˜แƒšแƒ˜แƒ แƒกแƒแƒ‘แƒแƒŸแƒ แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒ”แƒ แƒ—แƒ แƒแƒฃแƒ–แƒ˜แƒ“แƒแƒœ (แƒ’แƒ”แƒ’แƒ›แƒ”แƒ‘แƒจแƒ˜ แƒ“แƒ แƒฉแƒ•แƒ”แƒฃแƒšแƒ”แƒ‘แƒ˜ แƒ˜แƒงแƒแƒคแƒ แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ”แƒ‘แƒแƒ“). แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒ˜แƒก แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒก แƒ”แƒขแƒแƒžแƒ˜ แƒฐแƒ’แƒแƒ•แƒก CMD-แƒ˜แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒแƒก แƒฉแƒ•แƒ”แƒœแƒก แƒ”แƒ แƒ— แƒ“แƒ˜แƒ“ แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒ˜แƒ แƒ”แƒ‘แƒฃแƒš แƒกแƒฃแƒ แƒแƒ—แƒ–แƒ” แƒ“แƒ, แƒ–แƒแƒ’แƒแƒ“แƒแƒ“, แƒžแƒ แƒแƒฅแƒขแƒ˜แƒ™แƒฃแƒšแƒแƒ“ แƒแƒ  แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ“แƒ”แƒ‘แƒ I แƒœแƒแƒฌแƒ˜แƒšแƒจแƒ˜ แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒกแƒ’แƒแƒœ. แƒ›แƒ” แƒฎแƒแƒ–แƒก แƒ•แƒฃแƒกแƒ•แƒแƒ› แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ”แƒ‘แƒ”แƒ‘แƒก:

  • แƒ’แƒ˜แƒขแƒ˜แƒก แƒ™แƒšแƒแƒœแƒ˜... - แƒ›แƒ˜แƒ˜แƒฆแƒ”แƒ— แƒ’แƒแƒœแƒกแƒแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒšแƒแƒ“ แƒกแƒแƒญแƒ˜แƒ แƒ แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜ (createconfig.py, install_venv.sh แƒ“แƒ แƒ.แƒจ.)
  • แƒ“แƒแƒฎแƒ•แƒ”แƒ•แƒ... && แƒ’แƒแƒฎแƒกแƒœแƒ... - แƒฉแƒแƒ›แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ— แƒ“แƒ แƒ’แƒแƒฎแƒกแƒ”แƒœแƒ˜แƒ— build artifacts (แƒจแƒ”แƒ“แƒ’แƒ”แƒœแƒ˜แƒšแƒ˜ แƒฃแƒขแƒ˜แƒšแƒ˜แƒขแƒ”แƒ‘แƒ˜)

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

.gitlab-ci.yml-แƒจแƒ˜, แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒฃแƒšแƒ˜ แƒกแƒขแƒ”แƒ™แƒ˜แƒก แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒฉแƒ•แƒ”แƒœ แƒ•แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ— แƒ‘แƒแƒšแƒแƒœแƒกแƒ”แƒ แƒ˜แƒก แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ˜แƒก แƒฎแƒแƒ–แƒก (แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฉแƒแƒ“แƒ”แƒœแƒ˜แƒก แƒ“แƒ แƒแƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ’แƒแƒœแƒแƒแƒฎแƒšแƒ”แƒ‘แƒก แƒ›แƒ˜แƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒแƒก (แƒฅแƒ›แƒœแƒ˜แƒก แƒแƒฎแƒแƒš nginx แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒก แƒจแƒแƒ‘แƒšแƒแƒœแƒ˜แƒก แƒ›แƒ˜แƒฎแƒ”แƒ“แƒ•แƒ˜แƒ—: /etc/nginx/conf. d/${CI_COMMIT_REF_NAME}.conf) - แƒ˜แƒฎแƒ˜แƒšแƒ”แƒ— docker-compose-nginx.yml แƒ™แƒแƒ“แƒ˜)

    - docker stack deploy -c docker-compose-nginx.yml ${CI_ENVIRONMENT_NAME} --with-registry-auth

docker-compose-nginx.yml

---
version: '3'

services:
  nginx:
    image: nginx:latest
    environment:
      CI_COMMIT_REF_NAME: ${CI_COMMIT_REF_NAME}
      NGINX_CONFIG: |-
            server {
                listen 8080;
                server_name staging_${CI_COMMIT_REF_NAME}_cluster.dev;

                location / {
                    proxy_pass http://staging_${CI_COMMIT_REF_NAME}_cluster:8080;
                }
            }
            server {
                listen 5555;
                server_name staging_${CI_COMMIT_REF_NAME}_cluster.dev;

                location / {
                    proxy_pass http://staging_${CI_COMMIT_REF_NAME}_cluster:5555;
                }
            }
    volumes:
      - /tmp/staging/nginx:/etc/nginx/conf.d
    command:
      /bin/bash -c "echo -e "$$NGINX_CONFIG" > /etc/nginx/conf.d/${CI_COMMIT_REF_NAME}.conf;
        nginx -g "daemon off;";
        /etc/init.d/nginx reload"
    ports:
      - 8080:8080
      - 5555:5555
      - 3000:3000
      - 443:443
      - 80:80
    deploy:
      replicas: 1
      placement:
        constraints: [node.id == kilqc94pi2upzvabttikrfr5d]
      restart_policy:
        condition: none
    networks:
      nw_swarm:

networks:
  nw_swarm:
    external: true

แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒฃแƒš แƒ™แƒแƒ›แƒžแƒ˜แƒฃแƒขแƒ”แƒ แƒ”แƒ‘แƒ–แƒ” แƒ’แƒแƒœแƒแƒแƒฎแƒšแƒ”แƒ— /etc/hosts; แƒ“แƒแƒฌแƒ”แƒ แƒ”แƒ— url nginx-แƒ–แƒ”:

10.50.173.106 staging_BRANCH-1831_cluster.dev

แƒแƒกแƒ” แƒ แƒแƒ›, แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ“แƒ แƒ˜แƒ–แƒแƒšแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ“แƒแƒ“แƒ’แƒ›แƒ˜แƒก แƒ™แƒšแƒแƒกแƒขแƒ”แƒ แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒœแƒšแƒแƒ’แƒ”แƒ‘แƒ แƒ“แƒ แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ”แƒ‘แƒก แƒแƒฎแƒšแƒ แƒจแƒ”แƒฃแƒซแƒšแƒ˜แƒแƒ— แƒ›แƒแƒ—แƒ˜ แƒ’แƒแƒจแƒ•แƒ”แƒ‘แƒ แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ แƒ˜ แƒ แƒแƒแƒ“แƒ”แƒœแƒแƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜แƒ แƒ›แƒแƒ—แƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒšแƒแƒ“.

แฒ›แƒแƒ›แƒแƒ•แƒšแƒ˜แƒก แƒ’แƒ”แƒ’แƒ›แƒ”แƒ‘แƒ˜:

  • แƒ’แƒแƒ›แƒแƒงแƒแƒ•แƒ˜แƒ— แƒฉแƒ•แƒ”แƒœแƒ˜ แƒ™แƒแƒ›แƒžแƒแƒœแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜, แƒ แƒแƒ’แƒแƒ แƒช แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ”แƒ‘แƒ˜
  • แƒแƒฅแƒ•แƒก แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒšแƒ˜ Dockerfile
  • แƒแƒ•แƒขแƒแƒ›แƒแƒขแƒฃแƒ แƒแƒ“ แƒแƒฆแƒ›แƒแƒแƒฉแƒ˜แƒœแƒแƒก แƒœแƒแƒ™แƒšแƒ”แƒ‘แƒแƒ“ แƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒฃแƒšแƒ˜ แƒ™แƒ•แƒแƒœแƒซแƒ”แƒ‘แƒ˜ แƒ“แƒแƒกแƒขแƒแƒจแƒ˜
  • แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒ”แƒ— แƒ™แƒ•แƒแƒœแƒซแƒ”แƒ‘แƒ˜ แƒกแƒแƒฎแƒ”แƒšแƒ˜แƒก แƒœแƒ˜แƒ›แƒฃแƒจแƒ˜แƒก แƒ›แƒ˜แƒฎแƒ”แƒ“แƒ•แƒ˜แƒ— (แƒ•แƒ˜แƒ“แƒ แƒ” แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ ID-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—)
  • แƒ“แƒแƒแƒ›แƒแƒขแƒ”แƒ— แƒจแƒ”แƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ, แƒ แƒแƒ› แƒ“แƒแƒกแƒขแƒ แƒ’แƒแƒœแƒแƒ“แƒ’แƒฃแƒ แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ
  • ...

แƒ’แƒแƒœแƒกแƒแƒ™แƒฃแƒ—แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒแƒ“แƒšแƒแƒ‘แƒ แƒ›แƒฃแƒฎแƒšแƒ˜.

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

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