แƒ›แƒ” แƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒ” แƒฉแƒ”แƒ›แƒ˜ PyPI แƒกแƒแƒชแƒแƒ•แƒ˜ แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒ— แƒ“แƒ S3. Nginx-แƒ–แƒ”

แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ แƒ›แƒ˜แƒœแƒ“แƒ แƒ’แƒแƒ•แƒฃแƒ–แƒ˜แƒแƒ แƒ แƒฉแƒ”แƒ›แƒ˜ แƒ’แƒแƒ›แƒแƒชแƒ“แƒ˜แƒšแƒ”แƒ‘แƒ NJS-แƒก, JavaScript-แƒ˜แƒก แƒ—แƒแƒ แƒฏแƒ˜แƒ›แƒแƒœแƒก Nginx-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ Nginx Inc-แƒ˜แƒก แƒ›แƒ˜แƒ”แƒ  แƒ“แƒ แƒแƒฆแƒฌแƒ”แƒ แƒก แƒ›แƒ˜แƒก แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒ”แƒ‘แƒก แƒ แƒ”แƒแƒšแƒฃแƒ แƒ˜ แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—. NJS แƒแƒ แƒ˜แƒก JavaScript-แƒ˜แƒก แƒฅแƒ•แƒ”แƒฏแƒ’แƒฃแƒคแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒแƒคแƒแƒ แƒ—แƒแƒ•แƒแƒ— Nginx-แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒ. แƒ™แƒ˜แƒ—แƒฎแƒ•แƒแƒ–แƒ” แƒ แƒแƒขแƒแƒ› แƒจแƒ”แƒœแƒ˜ แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜ แƒ—แƒแƒ แƒฏแƒ˜แƒ›แƒแƒœแƒ˜??? แƒ“แƒ˜แƒ›แƒ˜แƒขแƒ แƒ˜ แƒ•แƒแƒšแƒ˜แƒœแƒชแƒ”แƒ•แƒ›แƒ แƒ“แƒ”แƒขแƒแƒšแƒฃแƒ แƒแƒ“ แƒฃแƒžแƒแƒกแƒฃแƒฎแƒ. แƒ›แƒแƒ™แƒšแƒ”แƒ“: NJS แƒแƒ แƒ˜แƒก nginx-way, แƒฎแƒแƒšแƒ JavaScript แƒฃแƒคแƒ แƒ แƒžแƒ แƒแƒ’แƒ แƒ”แƒกแƒฃแƒšแƒ˜, โ€žแƒ›แƒจแƒแƒ‘แƒšแƒ˜แƒฃแƒ แƒ˜โ€œ แƒ“แƒ GC-แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”, แƒšแƒฃแƒแƒกแƒ’แƒแƒœ แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ”แƒ‘แƒ˜แƒ—.

แฒ“แƒ˜แƒ“แƒ˜ แƒฎแƒœแƒ˜แƒก แƒฌแƒ˜แƒœโ€ฆ

แƒฉแƒ”แƒ›แƒก แƒ‘แƒแƒšแƒ แƒกแƒแƒ›แƒฃแƒจแƒแƒแƒ–แƒ” แƒ›แƒ” แƒ›แƒ”แƒ›แƒ™แƒ•แƒ˜แƒ“แƒ แƒ”แƒแƒ‘แƒ˜แƒ— แƒ›แƒ˜แƒ•แƒ˜แƒฆแƒ” แƒ’แƒ˜แƒขแƒšแƒแƒ‘แƒ˜ แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ แƒญแƒ แƒ”แƒšแƒ˜ CI/CD แƒ›แƒ˜แƒšแƒกแƒแƒ“แƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— แƒ“แƒแƒ™แƒ”แƒ -แƒ™แƒแƒ›แƒžแƒแƒ–แƒ˜แƒ—, แƒ“แƒ˜แƒœแƒ“แƒ˜แƒ— แƒ“แƒ แƒกแƒฎแƒ•แƒ แƒกแƒ˜แƒแƒ›แƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒ’แƒแƒ“แƒแƒ•แƒ˜แƒ“แƒ แƒ™แƒแƒœแƒ˜แƒ™แƒแƒก แƒ แƒ”แƒšแƒกแƒ”แƒ‘แƒ–แƒ”. แƒกแƒฃแƒ แƒแƒ—แƒ”แƒ‘แƒ˜, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒแƒ“แƒ แƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒแƒ“แƒ CI-แƒจแƒ˜, แƒ’แƒแƒ“แƒแƒ•แƒ˜แƒ“แƒ แƒ—แƒแƒ•แƒ“แƒแƒžแƒ˜แƒ แƒ•แƒ”แƒš แƒคแƒแƒ แƒ›แƒแƒจแƒ˜. แƒ˜แƒกแƒ˜แƒœแƒ˜ แƒ’แƒแƒ›แƒแƒ แƒ—แƒฃแƒšแƒแƒ“ แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ“แƒœแƒ”แƒœ แƒ˜แƒ› แƒ“แƒฆแƒ”แƒ›แƒ“แƒ”, แƒ แƒแƒ“แƒ”แƒกแƒแƒช แƒฉแƒ•แƒ”แƒœแƒ˜ gitlab IP แƒจแƒ”แƒ˜แƒชแƒ•แƒแƒšแƒ แƒ“แƒ CI แƒ’แƒแƒ’แƒ แƒแƒ“ แƒ’แƒแƒ“แƒแƒ˜แƒฅแƒชแƒ. แƒžแƒ แƒแƒ‘แƒšแƒ”แƒ›แƒ แƒ˜แƒก แƒ˜แƒงแƒ, แƒ แƒแƒ› แƒ”แƒ แƒ—-แƒ”แƒ แƒ— แƒ“แƒแƒ™แƒ”แƒ  แƒกแƒฃแƒ แƒแƒ—แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ›แƒแƒœแƒแƒฌแƒ˜แƒšแƒ”แƒแƒ‘แƒ“แƒ CI-แƒจแƒ˜, แƒ’แƒแƒแƒฉแƒœแƒ“แƒ git, แƒ แƒแƒ›แƒ”แƒšแƒ›แƒแƒช แƒ’แƒแƒ˜แƒงแƒ•แƒแƒœแƒ Python แƒ›แƒแƒ“แƒฃแƒšแƒ”แƒ‘แƒ˜ ssh-แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—. ssh-แƒกแƒ—แƒ•แƒ˜แƒก แƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— แƒžแƒ˜แƒ แƒแƒ“แƒ˜ แƒ’แƒแƒกแƒแƒฆแƒ”แƒ‘แƒ˜ แƒ“แƒ... แƒ”แƒก แƒ˜แƒงแƒ แƒกแƒฃแƒ แƒแƒ—แƒ–แƒ” แƒชแƒœแƒแƒ‘แƒ˜แƒšแƒ˜_แƒ›แƒแƒกแƒžแƒ˜แƒœแƒซแƒšแƒ”แƒ‘แƒ—แƒแƒœ แƒ”แƒ แƒ—แƒแƒ“. แƒ“แƒ แƒœแƒ”แƒ‘แƒ˜แƒกแƒ›แƒ˜แƒ”แƒ แƒ˜ CI แƒ•แƒ”แƒ  แƒ›แƒแƒฎแƒ”แƒ แƒฎแƒ“แƒ แƒ’แƒแƒกแƒแƒฆแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ“แƒแƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ˜แƒ— แƒ แƒ”แƒแƒšแƒฃแƒ  IP-แƒกแƒ แƒ“แƒ แƒชแƒœแƒแƒ‘แƒ˜แƒšแƒ˜_แƒ›แƒแƒกแƒžแƒ˜แƒœแƒซแƒšแƒ”แƒ‘แƒจแƒ˜ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒšแƒก แƒจแƒแƒ แƒ˜แƒก แƒจแƒ”แƒฃแƒกแƒแƒ‘แƒแƒ›แƒแƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ. แƒแƒฎแƒแƒšแƒ˜ แƒกแƒฃแƒ แƒแƒ—แƒ˜ แƒกแƒฌแƒ แƒแƒคแƒแƒ“ แƒจแƒ”แƒ˜แƒ™แƒ แƒ˜แƒ‘แƒ แƒแƒ แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜ Dockfiles-แƒ“แƒแƒœ แƒ“แƒ แƒ“แƒแƒ”แƒ›แƒแƒขแƒ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜ StrictHostKeyChecking no. แƒ›แƒแƒ’แƒ แƒแƒ› แƒชแƒฃแƒ“แƒ˜ แƒ’แƒ”แƒ›แƒ แƒ“แƒแƒ แƒฉแƒ แƒ“แƒ แƒ’แƒแƒฉแƒœแƒ“แƒ แƒกแƒฃแƒ แƒ•แƒ˜แƒšแƒ˜, แƒ’แƒแƒ“แƒแƒ”แƒขแƒแƒœแƒ แƒšแƒ˜แƒ‘แƒ”แƒ‘แƒ˜ แƒžแƒ˜แƒ แƒแƒ“ PyPI แƒกแƒแƒชแƒแƒ•แƒจแƒ˜. แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ˜แƒ—แƒ˜ แƒ‘แƒแƒœแƒฃแƒกแƒ˜, แƒžแƒ˜แƒ แƒแƒ“ PyPI-แƒ–แƒ” แƒ’แƒแƒ“แƒแƒกแƒ•แƒšแƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ˜แƒงแƒ แƒฃแƒคแƒ แƒ แƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ˜ แƒ›แƒ˜แƒšแƒกแƒแƒ“แƒ”แƒœแƒ˜ แƒ“แƒ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒœแƒแƒ แƒ›แƒแƒšแƒฃแƒ แƒ˜ แƒแƒฆแƒฌแƒ”แƒ แƒ.txt

แƒแƒ แƒฉแƒ”แƒ•แƒแƒœแƒ˜ แƒ’แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ, แƒ‘แƒแƒขแƒแƒœแƒ”แƒ‘แƒ!

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

แƒกแƒฌแƒ แƒแƒคแƒ›แƒ แƒซแƒ˜แƒ”แƒ‘แƒแƒ› แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜ แƒ’แƒแƒ›แƒแƒ˜แƒฆแƒ: s3pypi, pypicloud แƒ“แƒ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜ แƒขแƒฃแƒ แƒœแƒ˜แƒ™แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก html แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก โ€žแƒฎแƒ”แƒšแƒ˜แƒ—โ€œ แƒจแƒ”แƒฅแƒ›แƒœแƒ˜แƒ—. แƒ‘แƒแƒšแƒ แƒ•แƒแƒ แƒ˜แƒแƒœแƒขแƒ˜ แƒ—แƒแƒ•แƒ˜แƒกแƒ—แƒแƒ•แƒแƒ“ แƒ’แƒแƒฅแƒ แƒ.

s3pypi: แƒ”แƒก แƒแƒ แƒ˜แƒก แƒ™แƒšแƒ˜แƒžแƒ˜ S3 แƒฐแƒแƒกแƒขแƒ˜แƒœแƒ’แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒฉแƒ•แƒ”แƒœ แƒแƒ•แƒขแƒ•แƒ˜แƒ แƒ—แƒแƒ•แƒ— แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒก, แƒ•แƒแƒ’แƒ”แƒœแƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒ— html-แƒก แƒ“แƒ แƒ•แƒขแƒ•แƒ˜แƒ แƒ—แƒแƒ•แƒ— แƒ˜แƒ›แƒแƒ•แƒ” แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒจแƒ˜. แƒ’แƒแƒ›แƒแƒ“แƒ’แƒ”แƒ‘แƒ แƒกแƒแƒฎแƒšแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก.

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

แƒฃแƒคแƒ แƒ แƒกแƒ˜แƒฆแƒ แƒ›แƒ˜แƒกแƒ”แƒฃแƒšแƒ˜ แƒซแƒ˜แƒ”แƒ‘แƒแƒ› แƒ’แƒแƒ›แƒแƒ˜แƒฆแƒ แƒ›แƒแƒ“แƒฃแƒšแƒ˜ Nginx-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, ngx_aws_auth. แƒ›แƒ˜แƒกแƒ˜ แƒขแƒ”แƒกแƒขแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜ แƒ˜แƒงแƒ แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜ แƒœแƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ˜ XML, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ“แƒ S3 แƒ—แƒแƒ˜แƒ’แƒฃแƒšแƒ˜แƒก แƒจแƒ˜แƒ’แƒ—แƒแƒ•แƒกแƒก. แƒฉแƒฎแƒ แƒ”แƒ™แƒ˜แƒก แƒ“แƒ แƒแƒก แƒ‘แƒแƒšแƒ แƒฉแƒแƒ“แƒ”แƒœแƒ แƒ”แƒ แƒ—แƒ˜ แƒฌแƒšแƒ˜แƒก แƒฌแƒ˜แƒœ แƒ˜แƒงแƒ. แƒกแƒแƒชแƒแƒ•แƒ˜ แƒ›แƒ˜แƒขแƒแƒ•แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฉแƒแƒœแƒ“แƒ.

แƒฌแƒงแƒแƒ แƒแƒกแƒ—แƒแƒœ แƒ›แƒ˜แƒกแƒ•แƒšแƒ˜แƒ— แƒ“แƒ แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ˜แƒ— PEP-503 แƒ›แƒ˜แƒ•แƒฎแƒ•แƒ“แƒ˜, แƒ แƒแƒ› XML แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ“แƒแƒ˜แƒ–แƒแƒ แƒ“แƒแƒก HTML-แƒจแƒ˜ แƒ“แƒ แƒ’แƒแƒ“แƒแƒกแƒชแƒ”แƒก แƒžแƒ˜แƒžแƒก. Nginx-แƒ˜แƒกแƒ แƒ“แƒ S3-แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒชแƒแƒขแƒ แƒ›แƒ”แƒขแƒ˜ แƒ’แƒฃแƒ’แƒšแƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒจแƒ”แƒ•แƒฎแƒ•แƒ“แƒ˜ S3-แƒจแƒ˜ แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ JS-แƒจแƒ˜ Nginx-แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒแƒกแƒ” แƒ’แƒแƒ•แƒ˜แƒชแƒแƒœแƒ˜ NJS.

แƒแƒ› แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜แƒก แƒกแƒแƒคแƒฃแƒซแƒ•แƒ”แƒšแƒ–แƒ”, แƒ”แƒ แƒ—แƒ˜ แƒกแƒแƒแƒ—แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒฉแƒ”แƒ›แƒก แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜ แƒ•แƒœแƒแƒฎแƒ” แƒ˜แƒ’แƒ˜แƒ•แƒ” XML, แƒ แƒแƒ’แƒแƒ แƒช ngx_aws_auth แƒ›แƒแƒ“แƒฃแƒšแƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒแƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒฃแƒ™แƒ•แƒ” แƒ“แƒแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜ แƒ˜แƒงแƒ JS-แƒจแƒ˜.

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

TL;DR 2 แƒ“แƒฆแƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, PyPi-แƒก แƒกแƒแƒขแƒ”แƒกแƒขแƒ แƒ•แƒ”แƒ แƒกแƒ˜แƒ แƒฃแƒ™แƒ•แƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒแƒ“แƒ CI-แƒจแƒ˜.

แƒ แƒแƒ’แƒแƒ  แƒ›แƒฃแƒจแƒแƒแƒ‘แƒก แƒ˜แƒ’แƒ˜?

แƒ›แƒแƒ“แƒฃแƒšแƒ˜ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒฃแƒšแƒ˜แƒ Nginx-แƒจแƒ˜ ngx_http_js_module, แƒฉแƒแƒ แƒ—แƒฃแƒšแƒ˜แƒ แƒ“แƒแƒ™แƒ”แƒ แƒ˜แƒก แƒแƒคแƒ˜แƒชแƒ˜แƒแƒšแƒฃแƒ  แƒกแƒฃแƒ แƒแƒ—แƒจแƒ˜. แƒฉแƒ•แƒ”แƒœ แƒ˜แƒ›แƒžแƒแƒ แƒขแƒ˜แƒ แƒ”แƒ‘แƒก แƒฉแƒ•แƒ”แƒœแƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒก แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒ˜แƒ•แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— js_importNginx แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒแƒ›แƒ“แƒ”. แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒก แƒ”แƒฌแƒแƒ“แƒ”แƒ‘แƒ แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒ˜แƒ•แƒ js_content. แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒ˜แƒ•แƒ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒชแƒ•แƒšแƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒกแƒแƒงแƒ”แƒœแƒ”แƒ‘แƒšแƒแƒ“ js_set, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒแƒ“ แƒ˜แƒฆแƒ”แƒ‘แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒจแƒ˜ แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒš แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒก. แƒ›แƒแƒ’แƒ แƒแƒ› แƒฉแƒ•แƒ”แƒœ แƒจแƒ”แƒ’แƒ•แƒ˜แƒซแƒšแƒ˜แƒ แƒจแƒ”แƒ•แƒแƒกแƒ แƒฃแƒšแƒแƒ— แƒฅแƒ•แƒ”แƒ›แƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ”แƒ‘แƒ˜ NJS-แƒจแƒ˜ แƒ›แƒฎแƒแƒšแƒแƒ“ Nginx-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒแƒ แƒ XMLHttpRequest-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—. แƒแƒ›แƒ˜แƒกแƒแƒ—แƒ•แƒ˜แƒก แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒ˜ แƒ›แƒ“แƒ”แƒ‘แƒแƒ แƒ”แƒแƒ‘แƒ แƒฃแƒœแƒ“แƒ แƒ“แƒแƒ”แƒ›แƒแƒขแƒแƒก Nginx-แƒ˜แƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒแƒก. แƒ“แƒ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ›แƒ แƒฃแƒœแƒ“แƒ แƒแƒฆแƒฌแƒ”แƒ แƒแƒก แƒฅแƒ•แƒ”แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒแƒ› แƒ›แƒ“แƒ”แƒ‘แƒแƒ แƒ”แƒแƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. Nginx แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ˜แƒ“แƒแƒœ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒ–แƒ” แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒกแƒแƒฎแƒ”แƒšแƒ˜ แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ”แƒฅแƒกแƒžแƒแƒ แƒขแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ—แƒแƒ•แƒแƒ“ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒจแƒ˜ export default.

nginx.conf

load_module modules/ngx_http_js_module.so;
http {
  js_import   imported_name  from script.js;

server {
  listen 8080;
  ...
  location = /sub-query {
    internal;

    proxy_pass http://upstream;
  }

  location / {
    js_content imported_name.request;
  }
}

script.js

function request(r) {
  function call_back(resp) {
    // handler's code
    r.return(resp.status, resp.responseBody);
  }

  r.subrequest('/sub-query', { method: r.method }, call_back);
}

export default {request}

แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒกแƒแƒก http://localhost:8080/ แƒจแƒ”แƒ•แƒ“แƒ˜แƒ•แƒแƒ แƒ— location /แƒ แƒแƒ›แƒ”แƒšแƒจแƒ˜แƒช แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒ˜แƒ•แƒ js_content แƒ˜แƒซแƒแƒฎแƒ”แƒ‘แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒก request แƒแƒฆแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ แƒฉแƒ•แƒ”แƒœแƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒจแƒ˜ script.js. แƒ—แƒแƒ•แƒ˜แƒก แƒ›แƒฎแƒ แƒ˜แƒ•, แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒจแƒ˜ request แƒ™แƒ”แƒ—แƒ“แƒ”แƒ‘แƒ แƒฅแƒ•แƒ”แƒ›แƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒ location = /sub-query, แƒแƒ แƒ’แƒฃแƒ›แƒ”แƒœแƒขแƒ˜แƒ“แƒแƒœ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒ”แƒ—แƒแƒ“แƒ˜แƒ— (แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ” แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒจแƒ˜ GET). (r)แƒแƒ› แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒ˜แƒกแƒแƒก แƒ˜แƒ แƒ˜แƒ‘แƒแƒ“ แƒ’แƒแƒ•แƒ˜แƒ“แƒ. แƒฅแƒ•แƒ”แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒžแƒแƒกแƒฃแƒฎแƒ˜ แƒ“แƒแƒ›แƒฃแƒจแƒแƒ•แƒ“แƒ”แƒ‘แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒจแƒ˜ call_back.

แƒ•แƒชแƒ“แƒ˜แƒšแƒแƒ‘ S3-แƒก

แƒžแƒ˜แƒ แƒแƒ“แƒ˜ S3 แƒกแƒแƒชแƒแƒ•แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒ’แƒแƒกแƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒšแƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ:

ACCESS_KEY

SECRET_KEY

S3_BUCKET

แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ http แƒ›แƒ”แƒ—แƒแƒ“แƒ˜แƒ“แƒแƒœ, แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ” แƒ—แƒแƒ แƒ˜แƒฆแƒ˜/แƒ“แƒ แƒ, S3_NAME แƒ“แƒ URI, แƒฌแƒแƒ แƒ›แƒแƒ˜แƒฅแƒ›แƒœแƒ”แƒ‘แƒ แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒขแƒ˜แƒžแƒ˜แƒก แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒฎแƒ”แƒšแƒ›แƒแƒฌแƒ”แƒ แƒ˜แƒšแƒ˜แƒ (HMAC_SHA1) SECRET_KEY-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—. แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜ แƒแƒ แƒ˜แƒก แƒฎแƒแƒ–แƒ˜ แƒ›แƒกแƒ’แƒแƒ•แƒกแƒ˜ AWS $ACCESS_KEY:$HASH, แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒš แƒ˜แƒฅแƒœแƒแƒก แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒกแƒแƒ—แƒแƒฃแƒ แƒจแƒ˜. แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒ—แƒแƒ แƒ˜แƒฆแƒ˜/แƒ“แƒ แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ˜แƒงแƒ แƒฌแƒ˜แƒœแƒ แƒ”แƒขแƒแƒžแƒ–แƒ” แƒกแƒขแƒ แƒ˜แƒฅแƒแƒœแƒ˜แƒก แƒ’แƒ”แƒœแƒ”แƒ แƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒฃแƒœแƒ“แƒ แƒ“แƒแƒ”แƒ›แƒแƒขแƒแƒก แƒกแƒแƒ—แƒแƒฃแƒ แƒก X-amz-date. แƒ™แƒแƒ“แƒจแƒ˜ แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒ:

nginx.conf

load_module modules/ngx_http_js_module.so;
http {
  js_import   s3      from     s3.js;

  js_set      $s3_datetime     s3.date_now;
  js_set      $s3_auth         s3.s3_sign;

server {
  listen 8080;
  ...
  location ~* /s3-query/(?<s3_path>.*) {
    internal;

    proxy_set_header    X-amz-date     $s3_datetime;
    proxy_set_header    Authorization  $s3_auth;

    proxy_pass          $s3_endpoint/$s3_path;
  }

  location ~ "^/(?<prefix>[w-]*)[/]?(?<postfix>[w-.]*)$" {
    js_content s3.request;
  }
}

s3.js(AWS Sign v2 แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ˜, แƒจแƒ”แƒ˜แƒชแƒ•แƒแƒšแƒ แƒ›แƒแƒซแƒ•แƒ”แƒšแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒกแƒขแƒแƒขแƒฃแƒกแƒ˜แƒ—)

var crypt = require('crypto');

var s3_bucket = process.env.S3_BUCKET;
var s3_access_key = process.env.S3_ACCESS_KEY;
var s3_secret_key = process.env.S3_SECRET_KEY;
var _datetime = new Date().toISOString().replace(/[:-]|.d{3}/g, '');

function date_now() {
  return _datetime
}

function s3_sign(r) {
  var s2s = r.method + 'nnnn';

  s2s += `x-amz-date:${date_now()}n`;
  s2s += '/' + s3_bucket;
  s2s += r.uri.endsWith('/') ? '/' : r.variables.s3_path;

  return `AWS ${s3_access_key}:${crypt.createHmac('sha1', s3_secret_key).update(s2s).digest('base64')}`;
}

function request(r) {
  var v = r.variables;

  function call_back(resp) {
    r.return(resp.status, resp.responseBody);
  }

  var _subrequest_uri = r.uri;
  if (r.uri === '/') {
    // root
    _subrequest_uri = '/?delimiter=/';

  } else if (v.prefix !== '' && v.postfix === '') {
    // directory
    var slash = v.prefix.endsWith('/') ? '' : '/';
    _subrequest_uri = '/?prefix=' + v.prefix + slash;
  }

  r.subrequest(`/s3-query${_subrequest_uri}`, { method: r.method }, call_back);
}

export default {request, s3_sign, date_now}

แƒชแƒแƒขแƒ แƒแƒฎแƒกแƒœแƒ แƒ˜แƒ›แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ _subrequest_uri: แƒ”แƒก แƒแƒ แƒ˜แƒก แƒชแƒ•แƒšแƒแƒ“แƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช, แƒกแƒแƒฌแƒงแƒ˜แƒกแƒ˜ แƒฃแƒ แƒ˜แƒ“แƒแƒœ แƒ’แƒแƒ›แƒแƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ”, แƒฅแƒ›แƒœแƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒก S3-แƒ–แƒ”. แƒ—แƒฃ แƒ—แƒฅแƒ•แƒ”แƒœ แƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— "root"-แƒ˜แƒก แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ, แƒ›แƒแƒจแƒ˜แƒœ แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒฅแƒ›แƒœแƒแƒ— uri แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ›แƒ˜แƒฃแƒ—แƒ˜แƒ—แƒ”แƒ‘แƒก แƒ“แƒ”แƒšแƒ˜แƒ›แƒ˜แƒขแƒ”แƒ แƒ–แƒ”. delimiter, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ“แƒแƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒงแƒ•แƒ”แƒšแƒ CommonPrefixes xml แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒแƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ”แƒกแƒแƒ‘แƒแƒ›แƒ”แƒ‘แƒ แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒ”แƒ‘แƒก (PyPI-แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒงแƒ•แƒ”แƒšแƒ แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒกแƒ˜แƒแƒก). แƒ—แƒฃ แƒ—แƒฅแƒ•แƒ”แƒœ แƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— แƒจแƒ˜แƒ’แƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ˜แƒก แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒ แƒ™แƒแƒœแƒ™แƒ แƒ”แƒขแƒฃแƒš แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒจแƒ˜ (แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒงแƒ•แƒ”แƒšแƒ แƒ•แƒ”แƒ แƒกแƒ˜แƒ˜แƒก แƒกแƒ˜แƒ), แƒ›แƒแƒจแƒ˜แƒœ uri แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒฃแƒœแƒ“แƒ แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒ“แƒ”แƒก แƒžแƒ แƒ”แƒคแƒ˜แƒฅแƒกแƒ˜แƒก แƒ•แƒ”แƒšแƒก แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ˜แƒก (แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก) แƒกแƒแƒฎแƒ”แƒšแƒฌแƒแƒ“แƒ”แƒ‘แƒ˜แƒ—, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒฃแƒชแƒ˜แƒšแƒ”แƒ‘แƒšแƒแƒ“ แƒ›แƒ—แƒแƒ•แƒ แƒ“แƒ”แƒ‘แƒ แƒฎแƒแƒ–แƒ”แƒ‘แƒ˜แƒ— /. แƒฌแƒ˜แƒœแƒแƒแƒฆแƒ›แƒ“แƒ”แƒ’ แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜, แƒจแƒ”แƒฏแƒแƒฎแƒ”แƒ‘แƒ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒจแƒ˜ แƒจแƒ˜แƒ’แƒ—แƒแƒ•แƒกแƒ˜แƒก แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒกแƒแƒก. แƒแƒ แƒ˜แƒก แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ”แƒ‘แƒ˜ aiohttp-แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒ“แƒ aiohttp-แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜ แƒ“แƒ แƒ—แƒฃ แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒ’แƒแƒœแƒกแƒแƒ–แƒฆแƒ•แƒ แƒแƒ•แƒก /?prefix=aiohttp-request, แƒ›แƒแƒจแƒ˜แƒœ แƒžแƒแƒกแƒฃแƒฎแƒ˜ แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒแƒ แƒ˜แƒ•แƒ” แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ˜แƒก แƒจแƒ˜แƒœแƒแƒแƒ แƒกแƒก. แƒ—แƒฃ แƒ‘แƒแƒšแƒแƒจแƒ˜ แƒแƒ แƒ˜แƒก แƒฎแƒแƒ–แƒ’แƒแƒกแƒ›แƒ, /?prefix=aiohttp-request/, แƒ›แƒแƒจแƒ˜แƒœ แƒžแƒแƒกแƒฃแƒฎแƒ˜ แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒกแƒแƒญแƒ˜แƒ แƒ แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒก. แƒ“แƒ แƒ—แƒฃ แƒ›แƒแƒ•แƒ˜แƒ—แƒฎแƒแƒ•แƒ— แƒคแƒแƒ˜แƒšแƒก, แƒ›แƒแƒจแƒ˜แƒœ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฃแƒ แƒ˜ แƒแƒ  แƒฃแƒœแƒ“แƒ แƒ’แƒแƒœแƒกแƒฎแƒ•แƒแƒ•แƒ“แƒ”แƒ‘แƒแƒ“แƒ”แƒก แƒแƒ แƒ˜แƒ’แƒ˜แƒœแƒแƒšแƒ˜แƒกแƒ’แƒแƒœ.

แƒจแƒ”แƒ˜แƒœแƒแƒฎแƒ”แƒ— แƒ“แƒ แƒ’แƒแƒ“แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ”แƒ— Nginx. แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜ แƒฉแƒ•แƒ”แƒœ แƒ•แƒฌแƒ”แƒ แƒ— แƒฉแƒ•แƒ”แƒœแƒ˜ Nginx-แƒ˜แƒก แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒก, แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒ˜ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ XML, แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“:

แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Name>myback-space</Name>
  <Prefix></Prefix>
  <Marker></Marker>
  <MaxKeys>10000</MaxKeys>
  <Delimiter>/</Delimiter>
  <IsTruncated>false</IsTruncated>
  <CommonPrefixes>
    <Prefix>new/</Prefix>
  </CommonPrefixes>
  <CommonPrefixes>
    <Prefix>old/</Prefix>
  </CommonPrefixes>
</ListBucketResult>

แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ˜แƒ“แƒแƒœ แƒ“แƒแƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒ˜ CommonPrefixes.

แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜ แƒฉแƒ•แƒ”แƒœแƒก แƒ›แƒ˜แƒกแƒแƒ›แƒแƒ แƒ—แƒ–แƒ” แƒกแƒแƒญแƒ˜แƒ แƒ แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒแƒกแƒ”แƒ•แƒ” แƒ›แƒ˜แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒ›แƒ˜แƒก แƒจแƒ˜แƒ’แƒ—แƒแƒ•แƒกแƒก XML แƒกแƒแƒฎแƒ˜แƒ—:

แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒแƒ แƒ˜แƒแƒจแƒ˜

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Name> myback-space</Name>
  <Prefix>old/</Prefix>
  <Marker></Marker>
  <MaxKeys>10000</MaxKeys>
  <Delimiter></Delimiter>
  <IsTruncated>false</IsTruncated>
  <Contents>
    <Key>old/giphy.mp4</Key>
    <LastModified>2020-08-21T20:27:46.000Z</LastModified>
    <ETag>&#34;00000000000000000000000000000000-1&#34;</ETag>
    <Size>1350084</Size>
    <Owner>
      <ID>02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4</ID>
      <DisplayName></DisplayName>
    </Owner>
    <StorageClass>STANDARD</StorageClass>
  </Contents>
  <Contents>
    <Key>old/hsd-k8s.jpg</Key>
    <LastModified>2020-08-31T16:40:01.000Z</LastModified>
    <ETag>&#34;b2d76df4aeb4493c5456366748218093&#34;</ETag>
    <Size>93183</Size>
    <Owner>
      <ID>02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4</ID>
      <DisplayName></DisplayName>
    </Owner>
    <StorageClass>STANDARD</StorageClass>
  </Contents>
</ListBucketResult>

แƒคแƒแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒกแƒ˜แƒ˜แƒ“แƒแƒœ แƒฉแƒ•แƒ”แƒœ แƒแƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒ”แƒ‘แƒก Key.

แƒ แƒฉแƒ”แƒ‘แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ XML-แƒ˜แƒก แƒ’แƒแƒแƒœแƒแƒšแƒ˜แƒ–แƒ”แƒ‘แƒ แƒ“แƒ HTML แƒกแƒแƒฎแƒ˜แƒ— แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ, แƒ›แƒแƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, แƒ แƒแƒช แƒฏแƒ”แƒ  Content-Type แƒกแƒแƒ—แƒแƒฃแƒ แƒ˜ แƒขแƒ”แƒฅแƒกแƒขแƒ˜แƒ—/html-แƒ˜แƒ— แƒจแƒ”แƒ˜แƒชแƒ•แƒแƒšแƒ.

function request(r) {
  var v = r.variables;

  function call_back(resp) {
    var body = resp.responseBody;

    if (r.method !== 'PUT' && resp.status < 400 && v.postfix === '') {
      r.headersOut['Content-Type'] = "text/html; charset=utf-8";
      body = toHTML(body);
    }

    r.return(resp.status, body);
  }
  
  var _subrequest_uri = r.uri;
  ...
}

function toHTML(xml_str) {
  var keysMap = {
    'CommonPrefixes': 'Prefix',
    'Contents': 'Key',
  };

  var pattern = `<k>(?<v>.*?)</k>`;
  var out = [];

  for(var group_key in keysMap) {
    var reS;
    var reGroup = new RegExp(pattern.replace(/k/g, group_key), 'g');

    while(reS = reGroup.exec(xml_str)) {
      var data = new RegExp(pattern.replace(/k/g, keysMap[group_key]), 'g');
      var reValue = data.exec(reS);
      var a_text = '';

      if (group_key === 'CommonPrefixes') {
        a_text = reValue.groups.v.replace(///g, '');
      } else {
        a_text = reValue.groups.v.split('/').slice(-1);
      }

      out.push(`<a href="/ka/${reValue.groups.v}">${a_text}</a>`);
    }
  }

  return '<html><body>n' + out.join('</br>n') + 'n</html></body>'
}

PyPI-แƒก แƒ›แƒชแƒ“แƒ”แƒšแƒแƒ‘แƒ

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

# ะกะพะทะดะฐะตะผ ะดะปั ั‚ะตัั‚ะพะฒ ะฝะพะฒะพะต ะพะบั€ัƒะถะตะฝะธะต
python3 -m venv venv
. ./venv/bin/activate

# ะกะบะฐั‡ะธะฒะฐะตะผ ั€ะฐะฑะพั‡ะธะต ะฟะฐะบะตั‚ั‹.
pip download aiohttp

# ะ—ะฐะณั€ัƒะถะฐะตะผ ะฒ ะฟั€ะธะฒะฐั‚ะฝัƒัŽ ั€ะตะฟัƒ
for wheel in *.whl; do curl -T $wheel http://localhost:8080/${wheel%%-*}/$wheel; done

rm -f *.whl

# ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ะธะท ะฟั€ะธะฒะฐั‚ะฝะพะน ั€ะตะฟั‹
pip install aiohttp -i http://localhost:8080

แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒ›แƒ”แƒแƒ แƒ”แƒ‘แƒ— แƒฉแƒ•แƒ”แƒœแƒ˜ แƒšแƒ˜แƒ‘แƒ˜แƒ—.

# ะกะพะทะดะฐะตะผ ะดะปั ั‚ะตัั‚ะพะฒ ะฝะพะฒะพะต ะพะบั€ัƒะถะตะฝะธะต
python3 -m venv venv
. ./venv/bin/activate

pip install setuptools wheel
python setup.py bdist_wheel
for wheel in dist/*.whl; do curl -T $wheel http://localhost:8080/${wheel%%-*}/$wheel; done

pip install our_pkg --extra-index-url http://localhost:8080

CI-แƒจแƒ˜ แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒจแƒ”แƒฅแƒ›แƒœแƒ แƒ“แƒ แƒฉแƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒ:

pip install setuptools wheel
python setup.py bdist_wheel

curl -sSfT dist/*.whl -u "gitlab-ci-token:${CI_JOB_TOKEN}" "https://pypi.our-domain.com/${CI_PROJECT_NAME}"

แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ

Gitlab-แƒจแƒ˜ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ JWT-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ’แƒแƒ แƒ” แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ”แƒ‘แƒ˜แƒก แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก/แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. Nginx-แƒจแƒ˜ auth_request แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒ˜แƒ•แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒ’แƒแƒ“แƒแƒ•แƒ˜แƒงแƒ•แƒแƒœแƒ— แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒก แƒฅแƒ•แƒ”แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒ–แƒ”, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ›แƒแƒซแƒแƒฎแƒ”แƒ‘แƒแƒก แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒจแƒ˜. แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜ แƒ™แƒ˜แƒ“แƒ”แƒ• แƒ”แƒ แƒ— แƒฅแƒ•แƒ”แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒแƒก แƒ’แƒแƒฃแƒ™แƒ”แƒ—แƒ”แƒ‘แƒก Gitlab url-แƒก แƒ“แƒ แƒ—แƒฃ แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒก แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜ แƒกแƒฌแƒแƒ แƒแƒ“ แƒ˜แƒงแƒ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒšแƒ˜, แƒ›แƒแƒจแƒ˜แƒœ Gitlab แƒ“แƒแƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก แƒ™แƒแƒ“แƒก 200 แƒ“แƒ แƒœแƒ”แƒ‘แƒแƒ“แƒแƒ แƒ—แƒฃแƒšแƒ˜ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ/แƒฉแƒแƒ›แƒแƒขแƒ•แƒ˜แƒ แƒ—แƒ•แƒ. แƒ แƒแƒขแƒแƒ› แƒแƒ  แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— แƒ”แƒ แƒ—แƒ˜ แƒฅแƒ•แƒ”แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ แƒ“แƒ แƒ“แƒแƒฃแƒงแƒแƒ•แƒœแƒ”แƒ‘แƒšแƒ˜แƒ• แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒแƒ— แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜ Gitlab-แƒจแƒ˜? แƒ˜แƒ›แƒ˜แƒก แƒ’แƒแƒ›แƒ, แƒ แƒแƒ› แƒ›แƒแƒจแƒ˜แƒœ แƒฉแƒ•แƒ”แƒœ แƒ›แƒแƒ’แƒ•แƒ˜แƒฌแƒ”แƒ•แƒก Nginx-แƒ˜แƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ˜แƒก แƒคแƒแƒ˜แƒšแƒ˜แƒก แƒ แƒ”แƒ“แƒแƒฅแƒขแƒ˜แƒ แƒ”แƒ‘แƒ แƒงแƒแƒ•แƒ”แƒš แƒฏแƒ”แƒ แƒ–แƒ”, แƒ แƒแƒชแƒ แƒ แƒแƒ˜แƒ›แƒ” แƒชแƒ•แƒšแƒ˜แƒšแƒ”แƒ‘แƒแƒก แƒจแƒ”แƒ•แƒ˜แƒขแƒแƒœแƒ— แƒแƒ•แƒขแƒแƒ แƒ˜แƒ–แƒแƒชแƒ˜แƒแƒจแƒ˜ แƒ“แƒ แƒ”แƒก แƒกแƒแƒ™แƒ›แƒแƒแƒ“ แƒ“แƒแƒ›แƒฆแƒšแƒ”แƒšแƒ˜ แƒแƒ›แƒแƒชแƒแƒœแƒแƒ. แƒแƒกแƒ”แƒ•แƒ”, แƒ—แƒฃ Kubernetes แƒ˜แƒงแƒ”แƒœแƒ”แƒ‘แƒก แƒ›แƒฎแƒแƒšแƒแƒ“ แƒฌแƒแƒกแƒแƒ™แƒ˜แƒ—แƒฎแƒแƒ“ root แƒคแƒแƒ˜แƒšแƒฃแƒ แƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒžแƒแƒšแƒ˜แƒขแƒ˜แƒ™แƒแƒก, แƒ›แƒแƒจแƒ˜แƒœ แƒ”แƒก แƒ™แƒ˜แƒ“แƒ”แƒ• แƒฃแƒคแƒ แƒ แƒ›แƒ”แƒข แƒกแƒ˜แƒ แƒ—แƒฃแƒšแƒ”แƒก แƒ›แƒแƒขแƒ”แƒ‘แƒก nginx.conf-แƒ˜แƒก แƒฉแƒแƒœแƒแƒชแƒ•แƒšแƒ”แƒ‘แƒ˜แƒกแƒแƒก configmap-แƒ˜แƒ—. แƒ“แƒ แƒแƒ‘แƒกแƒแƒšแƒฃแƒขแƒฃแƒ แƒแƒ“ แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜ แƒฎแƒ“แƒ”แƒ‘แƒ Nginx-แƒ˜แƒก แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒ configmap-แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—, แƒ˜แƒ›แƒแƒ•แƒ“แƒ แƒแƒฃแƒšแƒแƒ“, แƒžแƒแƒšแƒ˜แƒขแƒ˜แƒ™แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒกแƒแƒก, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒ™แƒ แƒซแƒแƒšแƒแƒ•แƒก แƒขแƒแƒ›แƒ”แƒ‘แƒ˜แƒก (pvc) แƒ“แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒฌแƒแƒ™แƒ˜แƒ—แƒฎแƒ•แƒแƒ“แƒ˜ root แƒคแƒแƒ˜แƒšแƒฃแƒ แƒ˜ แƒกแƒ˜แƒกแƒขแƒ”แƒ›แƒ˜แƒก แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒแƒก (แƒ”แƒก แƒแƒกแƒ”แƒ•แƒ” แƒฎแƒ“แƒ”แƒ‘แƒ).

NJS แƒจแƒฃแƒแƒšแƒ”แƒ“แƒฃแƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ—, แƒฉแƒ•แƒ”แƒœ แƒ•แƒ˜แƒฆแƒ”แƒ‘แƒ— แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒšแƒแƒ‘แƒแƒก แƒจแƒ”แƒ•แƒชแƒ•แƒแƒšแƒแƒ— แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒžแƒแƒ แƒแƒ›แƒ”แƒขแƒ แƒ”แƒ‘แƒ˜ nginx แƒ™แƒแƒœแƒคแƒ˜แƒ’แƒฃแƒ แƒแƒชแƒ˜แƒแƒจแƒ˜ แƒ’แƒแƒ แƒ”แƒ›แƒแƒก แƒชแƒ•แƒšแƒแƒ“แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒ— แƒ“แƒ แƒ’แƒแƒ•แƒแƒ™แƒ”แƒ—แƒแƒ— แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒจแƒ”แƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒจแƒ˜ (แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, แƒแƒ แƒแƒกแƒฌแƒแƒ แƒแƒ“ แƒ›แƒ˜แƒ—แƒ˜แƒ—แƒ”แƒ‘แƒฃแƒšแƒ˜ URL).

nginx.conf

location = /auth-provider {
  internal;

  proxy_pass $auth_url;
}

location = /auth {
  internal;

  proxy_set_header Content-Length "";
  proxy_pass_request_body off;
  js_content auth.auth;
}

location ~ "^/(?<prefix>[w-]*)[/]?(?<postfix>[w-.]*)$" {
  auth_request /auth;

  js_content s3.request;
}

s3.js

var env = process.env;
var env_bool = new RegExp(/[Tt]rue|[Yy]es|[Oo]n|[TtYy]|1/);
var auth_disabled  = env_bool.test(env.DISABLE_AUTH);
var gitlab_url = env.AUTH_URL;

function url() {
  return `${gitlab_url}/jwt/auth?service=container_registry`
}

function auth(r) {
  if (auth_disabled) {
    r.return(202, '{"auth": "disabled"}');
    return null
  }

  r.subrequest('/auth-provider',
                {method: 'GET', body: ''},
                function(res) {
                  r.return(res.status, "");
                });
}

export default {auth, url}

แƒ“แƒ˜แƒ“แƒ˜ แƒแƒšแƒ‘แƒแƒ—แƒแƒ‘แƒ˜แƒ— แƒฉแƒœแƒ“แƒ”แƒ‘แƒ แƒ™แƒ˜แƒ—แƒฎแƒ•แƒ: -แƒ แƒแƒขแƒแƒ› แƒแƒ  แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— แƒ›แƒ–แƒ แƒ›แƒแƒ“แƒฃแƒšแƒ”แƒ‘แƒ˜? แƒ˜แƒฅ แƒฃแƒ™แƒ•แƒ” แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒ’แƒแƒ™แƒ”แƒ—แƒ“แƒ! แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒแƒ“, var AWS = แƒ›แƒแƒ˜แƒ—แƒฎแƒแƒ•แƒก ('aws-sdk') แƒ“แƒ แƒแƒ  แƒแƒ แƒ˜แƒก แƒกแƒแƒญแƒ˜แƒ แƒ โ€žแƒ•แƒ”แƒšแƒแƒกแƒ˜แƒžแƒ”แƒ“แƒ˜แƒกโ€œ แƒ“แƒแƒฌแƒ”แƒ แƒ S3 แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ˜แƒ—!

แƒ›แƒแƒ“แƒ˜แƒ— แƒ’แƒแƒ“แƒแƒ•แƒ˜แƒ“แƒ”แƒ— แƒ›แƒ˜แƒœแƒฃแƒกแƒ”แƒ‘แƒ–แƒ”

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

แƒจแƒ”แƒ™แƒฃแƒ›แƒจแƒ•แƒ แƒแƒกแƒ”แƒ•แƒ” แƒฃแƒœแƒ“แƒ แƒ˜แƒงแƒแƒก แƒ’แƒแƒ›แƒแƒ แƒ—แƒฃแƒšแƒ˜ Nginx-แƒ˜แƒก แƒ›แƒ˜แƒ›แƒ“แƒ˜แƒœแƒแƒ แƒ” แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก gzip off;

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

แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒแƒก แƒ“แƒ˜แƒ“แƒ˜ แƒ“แƒ แƒ แƒกแƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒ“แƒ แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ error.log-แƒจแƒ˜ โ€žแƒ‘แƒ”แƒญแƒ“แƒ•แƒ˜แƒกโ€œ แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ—. แƒ“แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒŸแƒฃแƒ แƒœแƒแƒšแƒ˜แƒก แƒ“แƒแƒœแƒ˜แƒก แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ˜แƒก, แƒ’แƒแƒคแƒ แƒ—แƒฎแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒแƒœ แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ˜แƒก แƒ›แƒ˜แƒฎแƒ”แƒ“แƒ•แƒ˜แƒ—, แƒจแƒ”แƒกแƒแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— 3 แƒ›แƒ”แƒ—แƒแƒ“แƒ˜, แƒจแƒ”แƒกแƒแƒ‘แƒแƒ›แƒ˜แƒกแƒแƒ“, r.log, r.warn, r.error. แƒ•แƒชแƒ“แƒ˜แƒšแƒแƒ‘ แƒ–แƒแƒ’แƒ˜แƒ”แƒ แƒ—แƒ˜ แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒแƒก Chrome (v8) แƒแƒœ njs แƒ™แƒแƒœแƒกแƒแƒšแƒ˜แƒก แƒฎแƒ”แƒšแƒกแƒแƒฌแƒงแƒแƒจแƒ˜, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ˜แƒฅ แƒงแƒ•แƒ”แƒšแƒแƒคแƒ แƒ˜แƒก แƒจแƒ”แƒ›แƒแƒฌแƒ›แƒ”แƒ‘แƒ แƒแƒ  แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ. แƒ™แƒแƒ“แƒ˜แƒก แƒ’แƒแƒ›แƒแƒ แƒ—แƒ•แƒ˜แƒกแƒแƒก, แƒแƒœแƒฃ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒฃแƒ แƒ˜ แƒขแƒ”แƒกแƒขแƒ˜แƒ แƒ”แƒ‘แƒ˜แƒกแƒแƒก, แƒ˜แƒกแƒขแƒแƒ แƒ˜แƒ แƒแƒกแƒ” แƒ’แƒแƒ›แƒแƒ˜แƒงแƒฃแƒ แƒ”แƒ‘แƒ:

docker-compose restart nginx
curl localhost:8080/
docker-compose logs --tail 10 nginx

แƒ“แƒ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒ˜แƒงแƒแƒก แƒแƒกแƒแƒ‘แƒ˜แƒ— แƒแƒกแƒ”แƒ—แƒ˜ แƒ—แƒแƒœแƒ›แƒ˜แƒ›แƒ“แƒ”แƒ•แƒ แƒแƒ‘แƒ.

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

ES6-แƒ˜แƒก แƒกแƒ แƒฃแƒšแƒ˜ แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ แƒแƒ  แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก.

แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ แƒกแƒฎแƒ•แƒ แƒฎแƒแƒ แƒ•แƒ”แƒ–แƒ”แƒ‘แƒ˜แƒช แƒ˜แƒงแƒแƒก, แƒ›แƒแƒ’แƒ แƒแƒ› แƒกแƒฎแƒ•แƒ แƒแƒ แƒแƒคแƒ”แƒ แƒ˜ แƒจแƒ”แƒ›แƒฎแƒ•แƒ”แƒ“แƒ แƒ˜แƒ. แƒ’แƒแƒแƒ–แƒ˜แƒแƒ แƒ”แƒ— แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ, แƒ—แƒฃ แƒ’แƒแƒฅแƒ•แƒ— NJS-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒฃแƒแƒ แƒงแƒแƒคแƒ˜แƒ—แƒ˜ แƒ’แƒแƒ›แƒแƒชแƒ“แƒ˜แƒšแƒ”แƒ‘แƒ.

แƒ“แƒแƒกแƒ™แƒ•แƒœแƒ

NJS แƒแƒ แƒ˜แƒก แƒ›แƒกแƒฃแƒ‘แƒฃแƒฅแƒ˜ แƒฆแƒ˜แƒ แƒ™แƒแƒ“แƒ˜แƒก แƒ—แƒแƒ แƒฏแƒ˜แƒ›แƒแƒœแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒœแƒแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒแƒ— แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ JavaScript แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ”แƒ‘แƒ˜ Nginx-แƒจแƒ˜. แƒ›แƒ˜แƒกแƒ˜ แƒ’แƒแƒœแƒ•แƒ˜แƒ—แƒแƒ แƒ”แƒ‘แƒ˜แƒก แƒ“แƒ แƒแƒก แƒ“แƒ˜แƒ“แƒ˜ แƒงแƒฃแƒ แƒแƒ“แƒฆแƒ”แƒ‘แƒ แƒ“แƒแƒ”แƒ—แƒ›แƒ แƒจแƒ”แƒกแƒ แƒฃแƒšแƒ”แƒ‘แƒแƒก. แƒ แƒ แƒ—แƒฅแƒ›แƒ แƒฃแƒœแƒ“แƒ, แƒฏแƒ”แƒ  แƒ™แƒ˜แƒ“แƒ”แƒ• แƒ‘แƒ”แƒ•แƒ แƒ˜ แƒแƒ™แƒšแƒ˜แƒ, แƒ›แƒแƒ’แƒ แƒแƒ› แƒžแƒ แƒแƒ”แƒฅแƒขแƒก แƒ›แƒชแƒ˜แƒ แƒ” แƒ’แƒฃแƒœแƒ“แƒ˜ แƒแƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒก แƒ“แƒ แƒแƒฅแƒขแƒ˜แƒฃแƒ แƒแƒ“ แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ”แƒœ แƒแƒฎแƒแƒš แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒก แƒ“แƒ แƒแƒกแƒฌแƒแƒ แƒ”แƒ‘แƒ”แƒœ แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ”แƒ‘แƒก. แƒ•แƒ˜แƒ›แƒ”แƒ“แƒแƒ•แƒœแƒ”แƒ‘, แƒ แƒแƒ› แƒแƒ“แƒ”แƒกแƒ›แƒ” NJS แƒ›แƒแƒ’แƒชแƒ”แƒ›แƒ— แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ“แƒแƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒแƒ— แƒ’แƒแƒ แƒ” แƒ›แƒแƒ“แƒฃแƒšแƒ”แƒ‘แƒ˜, แƒ แƒแƒช Nginx-แƒ˜แƒก แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒแƒœแƒ˜แƒ แƒ”แƒ‘แƒแƒก แƒ—แƒ˜แƒ—แƒฅแƒ›แƒ˜แƒก แƒจแƒ”แƒฃแƒ–แƒฆแƒฃแƒ“แƒแƒ•แƒ˜ แƒ’แƒแƒฎแƒ“แƒ˜แƒก. แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒ แƒกแƒ”แƒ‘แƒแƒ‘แƒก NGINX Plus แƒ“แƒ, แƒกแƒแƒ•แƒแƒ แƒแƒฃแƒ“แƒแƒ“, แƒแƒ  แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒคแƒฃแƒœแƒฅแƒชแƒ˜แƒ”แƒ‘แƒ˜!

แƒกแƒแƒชแƒแƒ•แƒ˜ แƒกแƒขแƒแƒขแƒ˜แƒ˜แƒก แƒกแƒ แƒฃแƒšแƒ˜ แƒ™แƒแƒ“แƒ˜แƒ—

njs-pypi AWS Sign v4 แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ˜แƒ—

ngx_http_js_module แƒ›แƒแƒ“แƒฃแƒšแƒ˜แƒก แƒ“แƒ˜แƒ แƒ”แƒฅแƒขแƒ˜แƒ•แƒ”แƒ‘แƒ˜แƒก แƒแƒฆแƒฌแƒ”แƒ แƒ

แƒแƒคแƒ˜แƒชแƒ˜แƒแƒšแƒฃแƒ แƒ˜ NJS แƒกแƒแƒชแƒแƒ•แƒ˜ ะธ แƒ“แƒแƒ™แƒฃแƒ›แƒ”แƒœแƒขแƒแƒชแƒ˜แƒ

NJS-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ›แƒแƒ’แƒแƒšแƒ˜แƒ—แƒ”แƒ‘แƒ˜ แƒ“แƒ˜แƒ›แƒ˜แƒขแƒ แƒ˜ แƒ•แƒแƒšแƒ˜แƒœแƒชแƒ”แƒ•แƒ˜แƒกแƒ’แƒแƒœ

njs - แƒ›แƒจแƒแƒ‘แƒšแƒ˜แƒฃแƒ แƒ˜ JavaScript แƒกแƒ™แƒ แƒ˜แƒžแƒขแƒ˜แƒ แƒ”แƒ‘แƒ nginx-แƒจแƒ˜ / แƒ“แƒ˜แƒ›แƒ˜แƒขแƒ แƒ˜ แƒ•แƒแƒšแƒœแƒ˜แƒ”แƒ•แƒ˜แƒก แƒ’แƒแƒ›แƒแƒกแƒ•แƒšแƒ Saint HighLoad++ 2019 แƒฌแƒ”แƒšแƒก

NJS แƒฌแƒแƒ แƒ›แƒแƒ”แƒ‘แƒแƒจแƒ˜ / แƒ•แƒแƒกแƒ˜แƒšแƒ˜ แƒกแƒแƒจแƒœแƒ˜แƒ™แƒแƒ•แƒ˜แƒก แƒ’แƒแƒ›แƒแƒกแƒ•แƒšแƒ HighLoad++ 2019-แƒ–แƒ”

REST แƒ›แƒแƒ—แƒฎแƒแƒ•แƒœแƒ”แƒ‘แƒ˜แƒก แƒฎแƒ”แƒšแƒ›แƒแƒฌแƒ”แƒ แƒ แƒ“แƒ แƒแƒ•แƒ—แƒ”แƒœแƒขแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ AWS-แƒจแƒ˜

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