เชฎเซ‡เช‚ เช…เชงเชฟเช•เซƒเชคเชคเชพ เช…เชจเซ‡ S3 เชธเชพเชฅเซ‡ เชฎเชพเชฐเซ€ PyPI เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€ เชฌเชจเชพเชตเซ€ เช›เซ‡. Nginx เชชเชฐ

เช† เชฒเซ‡เช–เชฎเชพเช‚ เชนเซเช‚ NJS เชธเชพเชฅเซ‡ เชฎเชพเชฐเซ‹ เช…เชจเซเชญเชต เชถเซ‡เชฐ เช•เชฐเชตเชพ เชฎเชพเช‚เช—เซ เช›เซเช‚, Nginx Inc เชฆเซเชตเชพเชฐเชพ เชตเชฟเช•เชธเชฟเชค Nginx เชฎเชพเชŸเซ‡ JavaScript เชฆเซเชญเชพเชทเชฟเชฏเชพ, เชตเชพเชธเซเชคเชตเชฟเช• เช‰เชฆเชพเชนเชฐเชฃเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชคเซ‡เชจเซ€ เชฎเซเช–เซเชฏ เช•เซเชทเชฎเชคเชพเช“เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ‡ เช›เซ‡. NJS เช JavaScript เชจเซ‹ เชธเชฌเชธเซ‡เชŸ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ Nginx เชจเซ€ เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพเชจเซ‡ เชตเชฟเชธเซเชคเชพเชฐเชตเชพ เชฆเซ‡ เช›เซ‡. เชชเซเชฐเชถเซเชจ เชฎเชพเชŸเซ‡ เชถเชพ เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฐเชพ เชชเซ‹เชคเชพเชจเชพ เชฆเซเชญเชพเชทเชฟเชฏเชพ??? เชฆเชฟเชฎเชฟเชคเซเชฐเซ€ เชตเซ‹เชฒเชฟเชจเซเชŸเชธเซ‡เชตเซ‡ เชตเชฟเช—เชคเชตเชพเชฐ เชœเชตเชพเชฌ เช†เชชเซเชฏเซ‹. เชŸเซ‚เช‚เช•เชฎเชพเช‚: NJS เช nginx-เชตเซ‡ เช›เซ‡, เช…เชจเซ‡ JavaScript เชตเชงเซ เชชเซเชฐเช—เชคเชฟเชถเซ€เชฒ เช›เซ‡, "เชฎเซ‚เชณ" เช…เชจเซ‡ GC เชตเชฟเชจเชพ, เชฒเซเช†เชฅเซ€ เชตเชฟเชชเชฐเซ€เชค.

เช˜เชฃเชพเช‚ เชธเชฎเชฏ เชชเชนเซ‡เชฒเชพโ€ฆ

เชฎเชพเชฐเซ€ เช›เซ‡เชฒเซเชฒเซ€ เชจเซ‹เช•เชฐเซ€ เชชเชฐ, เชฎเชจเซ‡ เชกเซ‹เช•เชฐ-เช•เช‚เชชเซ‹เช, เชกเซ€เช‚เชก เช…เชจเซ‡ เช…เชจเซเชฏ เช†เชจเช‚เชฆ เชธเชพเชฅเซ‡ เชธเช‚เช–เซเชฏเชพเชฌเช‚เชง เชฎเซ‹เชŸเชฒเซ€ CI/CD เชชเชพเช‡เชชเชฒเชพเช‡เชจเซเชธ เชธเชพเชฅเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌ เชตเชพเชฐเชธเชพเชฎเชพเช‚ เชฎเชณเซ€ เชนเชคเซ€, เชœเซ‡ เช•เชจเชฟเช•เซ‹ เชฐเซ‡เชฒเซเชธเชฎเชพเช‚ เชŸเซเชฐเชพเชจเซเชธเชซเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชนเชคเซ€. CI เชฎเชพเช‚ เช…เช—เชพเช‰ เช‰เชชเชฏเซ‹เช—เชฎเชพเช‚ เชฒเซ‡เชตเชพเชคเซ€ เช›เชฌเซ€เช“ เชคเซ‡เชฎเชจเชพ เชฎเซ‚เชณ เชธเซเชตเชฐเซ‚เชชเชฎเชพเช‚ เช–เชธเซ‡เชกเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชนเชคเซ€. เชคเซ‡เช“ เชคเซ‡ เชฆเชฟเชตเชธ เชธเซเชงเซ€ เชฏเซ‹เช—เซเชฏ เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเชคเชพ เชนเชคเชพ เชœเซเชฏเชพเช‚ เชธเซเชงเซ€ เช…เชฎเชพเชฐเซเช‚ เช—เชฟเชŸเชฒเซ‡เชฌ IP เชฌเชฆเชฒเชพเชฏเซเช‚ เช…เชจเซ‡ CI เช•เซ‹เชณเชพเชฎเชพเช‚ เชซเซ‡เชฐเชตเชพเชˆ เช—เชฏเซเช‚. เชธเชฎเชธเซเชฏเชพ เช เชนเชคเซ€ เช•เซ‡ CI เชฎเชพเช‚ เชญเชพเช— เชฒเซ‡เชคเซ€ เชกเซ‹เช•เชฐ เช‡เชฎเซ‡เชœเชฎเชพเช‚เชจเซ€ เชเช• เชชเชพเชธเซ‡ git เชนเชคเซ€, เชœเซ‡ Python เชฎเซ‹เชกเซเชฏเซเชฒเซ‹เชจเซ‡ ssh เชฆเซเชตเชพเชฐเชพ เช–เซ‡เช‚เชšเซ‡ เช›เซ‡. ssh เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฐเซ‡ เช–เชพเชจเช—เซ€ เช•เซ€เชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เช…เชจเซ‡... เชคเซ‡ เชœเชพเชฃเซ€เชคเชพ_เชนเซ‹เชธเซเชŸเชจเซ€ เชธเชพเชฅเซ‡ เชˆเชฎเซ‡เชœเชฎเชพเช‚ เชนเชคเซ€. เช…เชจเซ‡ เชตเชพเชธเซเชคเชตเชฟเช• IP เช…เชจเซ‡ เชœเชพเชฃเซ€เชคเชพ_เชนเซ‹เชธเซเชŸเชฎเชพเช‚ เช‰เชฒเซเชฒเซ‡เช–เชฟเชค เชเช• เชตเชšเซเชšเซ‡ เชฎเซ‡เชณ เช–เชพเชคเซ€ เชจ เชนเซ‹เชตเชพเชจเซ‡ เช•เชพเชฐเชฃเซ‡ เช•เซ‹เชˆเชชเชฃ CI เชฎเซเช–เซเชฏ เชšเช•เชพเชธเชฃเซ€ เชญเซ‚เชฒ เชธเชพเชฅเซ‡ เชจเชฟเชทเซเชซเชณ เชฅเชฏเซเช‚. เชนเชพเชฒเชจเซ€ เชกเซ‹เช•เชซเชพเชˆเชฒเซเชธเชฎเชพเช‚เชฅเซ€ เชเช• เชจเชตเซ€ เชˆเชฎเซ‡เชœ เชเชกเชชเชฅเซ€ เชเชธเซ‡เชฎเซเชฌเชฒ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชนเชคเซ€ เช…เชจเซ‡ เชตเชฟเช•เชฒเซเชช เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เชนเชคเซ‹ StrictHostKeyChecking no. เชชเชฐเช‚เชคเซ เช–เชฐเชพเชฌ เชธเซเชตเชพเชฆ เชฐเชนเซเชฏเซ‹ เช…เชจเซ‡ เชฒเชฟเชฌเซเชธเชจเซ‡ เช–เชพเชจเช—เซ€ PyPI เชฐเชฟเชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚ เช–เชธเซ‡เชกเชตเชพเชจเซ€ เช‡เชšเซเช›เชพ เชนเชคเซ€. เชเช• เชตเชงเชพเชฐเชพเชจเซเช‚ เชฌเซ‹เชจเชธ, เช–เชพเชจเช—เซ€ PyPI เชชเชฐ เชธเซเชตเชฟเชš เช•เชฐเซเชฏเชพ เชชเช›เซ€, เชเช• เชธเชฐเชณ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เช…เชจเซ‡ เชœเชฐเซ‚เชฐเชฟเชฏเชพเชคเซ‹เชจเซเช‚ เชธเชพเชฎเชพเชจเซเชฏ เชตเชฐเซเชฃเชจ เชนเชคเซเช‚.txt

เชชเชธเช‚เชฆเช—เซ€ เชฅเชˆ เช—เชˆ เช›เซ‡, เชธเชœเซเชœเชจเซ‹!

เช…เชฎเซ‡ เชฌเชงเซเช‚ เช•เซเชฒเชพเช‰เชกเซเชธ เช…เชจเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธเชฎเชพเช‚ เชšเชฒเชพเชตเซ€เช เช›เซ€เช เช…เชจเซ‡ เช…เช‚เชคเซ‡ เช…เชฎเซ‡ เชเช• เชจเชพเชจเซ€ เชธเซ‡เชตเชพ เชฎเซ‡เชณเชตเชตเชพ เชฎเชพเช—เซ€เช เช›เซ€เช เชœเซ‡ เชฌเชพเชนเซเชฏ เชธเซเชŸเซ‹เชฐเซ‡เชœ เชธเชพเชฅเซ‡ เชธเซเชŸเซ‡เชŸเชฒเซ‡เชธ เช•เชจเซเชŸเซ‡เชจเชฐ เชนเชคเซเช‚. เช เซ€เช• เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เช…เชฎเซ‡ S3 เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช, เชคเซ‡เชจเซ‡ เชชเซเชฐเชพเชฅเชฎเชฟเช•เชคเชพ เช†เชชเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชนเชคเซ€. เช…เชจเซ‡, เชœเซ‹ เชถเช•เซเชฏ เชนเซ‹เชฏ เชคเซ‹, เช—เชฟเชŸเชฒเซ‡เชฌเชฎเชพเช‚ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เชธเชพเชฅเซ‡ (เชœเซ‹ เชœเชฐเซ‚เชฐเซ€ เชนเซ‹เชฏ เชคเซ‹ เชคเชฎเซ‡ เชคเซ‡เชจเซ‡ เชœเชพเชคเซ‡ เช‰เชฎเซ‡เชฐเซ€ เชถเช•เซ‹ เช›เซ‹).

เชเชกเชชเซ€ เชถเซ‹เชงเชฅเซ€ เช˜เชฃเชพ เชชเชฐเชฟเชฃเชพเชฎเซ‹ เชฎเชณเซเชฏเชพ: s3pypi, pypicloud เช…เชจเซ‡ เชธเชฒเช—เชฎ เชฎเชพเชŸเซ‡ html เชซเชพเช‡เชฒเซ‹เชจเซ€ "เชฎเซ‡เชจเซเชฏเซเช…เชฒ" เชฐเชšเชจเชพ เชธเชพเชฅเซ‡เชจเซ‹ เชตเชฟเช•เชฒเซเชช. เช›เซ‡เชฒเซเชฒเซ‹ เชตเชฟเช•เชฒเซเชช เชชเซ‹เชคเซ‡ เชœ เช…เชฆเซƒเชถเซเชฏ เชฅเชˆ เช—เชฏเซ‹.

s3pypi: S3 เชนเซ‹เชธเซเชŸเชฟเช‚เช—เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡เชจเซ€ เช† เช•เซเชฒเชฟ เช›เซ‡. เช…เชฎเซ‡ เชซเชพเช‡เชฒเซ‹ เช…เชชเชฒเซ‹เชก เช•เชฐเซ€เช เช›เซ€เช, html เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ€เช เช›เซ€เช เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชธเชฎเชพเชจ เชฌเช•เซ‡เชŸเชฎเชพเช‚ เช…เชชเชฒเซ‹เชก เช•เชฐเซ€เช เช›เซ€เช. เช˜เชฐ เชตเชชเชฐเชพเชถ เชฎเชพเชŸเซ‡ เชฏเซ‹เช—เซเชฏ.

pypicloud: เชคเซ‡ เชเช• เชฐเชธเชชเซเชฐเชฆ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชœเซ‡เชตเซเช‚ เชฒเชพเช—เชคเซเช‚ เชนเชคเซเช‚, เชชเชฐเช‚เชคเซ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ เชตเชพเช‚เชšเซเชฏเชพ เชชเช›เซ€ เชนเซเช‚ เชจเชฟเชฐเชพเชถ เชฅเชฏเซ‹. เชธเชพเชฐเชพ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ เช…เชจเซ‡ เชคเชฎเชพเชฐเซ€ เชœเชฐเซ‚เชฐเชฟเชฏเชพเชคเซ‹เชจเซ‡ เช…เชจเซเชฐเซ‚เชช เชตเชฟเชธเซเชคเชฐเชฃ เช•เชฐเชตเชพเชจเซ€ เช•เซเชทเชฎเชคเชพ เชนเซ‹เชตเชพ เช›เชคเชพเช‚, เชตเชพเชธเซเชคเชตเชฎเชพเช‚ เชคเซ‡ เชจเชฟเชฐเชฐเซเชฅเช• เช…เชจเซ‡ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชฟเชค เช•เชฐเชตเซเช‚ เชฎเซเชถเซเช•เซ‡เชฒ เชฌเชจเซเชฏเซเช‚. เชคเชฎเชพเชฐเชพ เช•เชพเชฐเซเชฏเซ‹เชจเซ‡ เช…เชจเซเชฐเซ‚เชช เช•เซ‹เชกเชจเซ‡ เชธเซเชงเชพเชฐเชตเชพเชฎเชพเช‚, เชคเซ‡ เชธเชฎเชฏเซ‡เชจเชพ เช…เช‚เชฆเชพเชœ เชฎเซเชœเชฌ, 3-5 เชฆเชฟเชตเชธเชจเซ‹ เชธเชฎเชฏ เชฒเชพเช—เชถเซ‡. เชธเซ‡เชตเชพเชจเซ‡ เชกเซ‡เชŸเชพเชฌเซ‡เชเชจเซ€ เชชเชฃ เชœเชฐเซ‚เชฐ เช›เซ‡. เช…เชฎเชจเซ‡ เชฌเซ€เชœเซเช‚ เช•เช‚เชˆ เชจ เชฎเชณเซ‡ เชคเซ‹ เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เช›เซ‹เชกเซ€ เชฆเซ€เชงเซเช‚.

เชตเชงเซ เชŠเช‚เชกเชพเชฃเชชเซ‚เชฐเซเชตเช•เชจเซ€ เชถเซ‹เชงเชฎเชพเช‚ Nginx, ngx_aws_auth เชฎเชพเชŸเซ‡ เชฎเซ‹เชกเซเชฏเซเชฒ เชฎเชณเซเชฏเซเช‚. เชคเซ‡เชจเชพ เชชเชฐเซ€เช•เซเชทเชฃเชจเซเช‚ เชชเชฐเชฟเชฃเชพเชฎ XML เชฌเซเชฐเชพเช‰เชเชฐเชฎเชพเช‚ เชชเซเชฐเชฆเชฐเซเชถเชฟเชค เชฅเชฏเซเช‚ เชนเชคเซเช‚, เชœเซ‡ S3 เชฌเช•เซ‡เชŸเชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€ เชฆเชฐเซเชถเชพเชตเซ‡ เช›เซ‡. เชถเซ‹เชง เชธเชฎเชฏเซ‡ เช›เซ‡เชฒเซเชฒเซ€ เช•เชฎเชฟเชŸ เชเช• เชตเชฐเซเชท เชชเชนเซ‡เชฒเชพ เชนเชคเซ€. เชญเช‚เชกเชพเชฐ เชคเซเชฏเชœเซ€ เช—เชฏเซ‡เชฒเซ‹ เชฆเซ‡เช–เชพเชคเซ‹ เชนเชคเซ‹.

เชธเซเชคเซเชฐเซ‹เชค เชชเชฐ เชœเชˆเชจเซ‡ เชตเชพเช‚เชšเชตเซเช‚ เชชเซ€เชˆเชชเซ€ -503 เชฎเชจเซ‡ เชธเชฎเชœเชพเชฏเซเช‚ เช•เซ‡ XML เชจเซ‡ เชซเซเชฒเชพเชฏ เชชเชฐ HTML เชฎเชพเช‚ เชฐเซ‚เชชเชพเช‚เชคเชฐเชฟเชค เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡ เช…เชจเซ‡ pip เชจเซ‡ เช†เชชเซ€ เชถเช•เชพเชฏ เช›เซ‡. Nginx เช…เชจเซ‡ S3 เชตเชฟเชถเซ‡ เชฅเซ‹เชกเซเช‚ เชตเชงเซ เช—เซ‚เช—เชฒเชฟเช‚เช— เช•เชฐเซเชฏเชพ เชชเช›เซ€, เชฎเชจเซ‡ Nginx เชฎเชพเชŸเซ‡ JS เชฎเชพเช‚ เชฒเช–เซ‡เชฒเชพ S3 เชฎเชพเช‚ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃเชจเซเช‚ เช‰เชฆเชพเชนเชฐเชฃ เชฎเชณเซเชฏเซเช‚. เช† เชฐเซ€เชคเซ‡ เชนเซเช‚ NJS เชจเซ‡ เชฎเชณเซเชฏเซ‹.

เช† เช‰เชฆเชพเชนเชฐเชฃเชจเซ‡ เช†เชงเชพเชฐ เชคเชฐเซ€เช•เซ‡ เชฒเซ‡เชคเชพ, เชเช• เช•เชฒเชพเช• เชชเช›เซ€ เชฎเซ‡เช‚ เชฎเชพเชฐเชพ เชฌเซเชฐเชพเช‰เชเชฐเชฎเชพเช‚ ngx_aws_auth เชฎเซ‹เชกเซเชฏเซเชฒเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เชธเชฎเชพเชจ XML เชœเซ‹เชฏเซเช‚, เชชเชฐเช‚เชคเซ เชฌเชงเซเช‚ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ JS เชฎเชพเช‚ เชฒเช–เซ‡เชฒเซเช‚ เชนเชคเซเช‚.

เชฎเชจเซ‡ เช–เชฐเซ‡เช–เชฐ nginx เชธเซ‹เชฒเซเชฏเซเชถเชจ เช—เชฎเซเชฏเซเช‚. เชชเซเชฐเชฅเชฎ, เชธเชพเชฐเชพ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ‹ เช…เชจเซ‡ เช˜เชฃเชพ เช‰เชฆเชพเชนเชฐเชฃเซ‹, เชฌเซ€เชœเซเช‚, เช…เชฎเชจเซ‡ เชซเชพเช‡เชฒเซ‹ (เชฌเซ‰เช•เซเชธเชจเซ€ เชฌเชนเชพเชฐ) เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ 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, เชšเซ‹เช•เซเช•เชธ เชชเซเชฐเช•เชพเชฐเชจเซ€ เชธเซเชŸเซเชฐเชฟเช‚เช— เชœเชจเชฐเซ‡เชŸ เชฅเชพเชฏ เช›เซ‡, เชœเซ‡ SECRET_KEY เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ (HMAC_SHA1) เชนเชธเซเชคเชพเช•เซเชทเชฐเชฟเชค เชฅเชพเชฏ เช›เซ‡. เช†เช—เชณ เชเช• เชฒเซ€เชŸเซ€ เชœเซ‡เชตเซ€ เช›เซ‡ 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 เชธเชพเช‡เชจ 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: เช† เชเช• เชšเชฒ เช›เซ‡ เชœเซ‡, เชชเซเชฐเชพเชฐเช‚เชญเชฟเช• uri เชชเชฐ เช†เชงเชพเชฐ เชฐเชพเช–เซ€เชจเซ‡, S3 เชจเซ‡ เชตเชฟเชจเช‚เชคเซ€ เช•เชฐเซ‡ เช›เซ‡. เชœเซ‹ เชคเชฎเชพเชฐเซ‡ "เชฐเซเชŸ" เชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€ เชฎเซ‡เชณเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเชพเชฐเซ‡ เชธเซ€เชฎเชพเช‚เช•เชจ เชฆเชฐเซเชถเชพเชตเชคเซ€ uri เชตเชฟเชจเช‚เชคเซ€ เชฌเชจเชพเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. delimiter, เชœเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เช“ (PyPI เชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เชฌเชงเชพ เชชเซ‡เช•เซ‡เชœเซ‹เชจเซ€ เชธเซ‚เชšเชฟ) เชจเซ‡ เช…เชจเซเชฐเซ‚เชช, เชคเชฎเชพเชฎ CommonPrefixes xml เช˜เชŸเช•เซ‹เชจเซ€ เชธเซ‚เชšเชฟ เชชเชฐเชค เช•เชฐเชถเซ‡. เชœเซ‹ เชคเชฎเชพเชฐเซ‡ เชšเซ‹เช•เซเช•เชธ เชจเชฟเชฐเซเชฆเซ‡เชถเชฟเช•เชพเชฎเชพเช‚ เชธเชฎเชพเชตเชฟเชทเซเชŸเซ‹เชจเซ€ เชธเซ‚เชšเชฟ เชฎเซ‡เชณเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ (เชฌเชงเชพ เชชเซ‡เช•เซ‡เชœ เชธเช‚เชธเซเช•เชฐเชฃเซ‹เชจเซ€ เชธเซ‚เชšเชฟ), เชคเซ‹ เชชเช›เซ€ uri เชตเชฟเชจเช‚เชคเซ€เชฎเชพเช‚ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ (เชชเซ‡เช•เซ‡เชœ) เชจเชพ เชจเชพเชฎ เชธเชพเชฅเซ‡เชจเซ‹ เช‰เชชเชธเชฐเซเช— เชซเซ€เชฒเซเชก เชนเซ‹เชตเซ‹ เช†เชตเชถเซเชฏเช• เช›เซ‡ เชœเซ‡ เชธเซเชฒเซ‡เชถ / เชธเชพเชฅเซ‡ เชธเชฎเชพเชชเซเชค เชฅเชพเชฏ เช›เซ‡. เชจเชนเชฟเช‚เชคเชฐ, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เชจเชพ เชธเชฎเชพเชตเชฟเชทเซเชŸเซ‹เชจเซ€ เชตเชฟเชจเช‚เชคเซ€ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เช…เชฅเชกเชพเชฎเชฃ เชถเช•เซเชฏ เช›เซ‡. เชคเซเชฏเชพเช‚ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เช“ aiohttp-request เช…เชจเซ‡ aiohttp-เชตเชฟเชจเช‚เชคเซ€ เช›เซ‡ เช…เชจเซ‡ เชœเซ‹ เชตเชฟเชจเช‚เชคเซ€ เชธเซเชชเชทเซเชŸ เช•เชฐเซ‡ เช›เซ‡ /?prefix=aiohttp-request, เชชเช›เซ€ เชชเซเชฐเชคเชฟเชญเชพเชตเชฎเชพเช‚ เชฌเช‚เชจเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เช“เชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€ เชนเชถเซ‡. เชœเซ‹ เช…เช‚เชคเซ‡ เชธเซเชฒเซ‡เชถ เชนเซ‹เชฏ, /?prefix=aiohttp-request/, เชชเช›เซ€ เชชเซเชฐเชคเชฟเชญเชพเชตเชฎเชพเช‚ เชฎเชพเชคเซเชฐ เชœเชฐเซ‚เชฐเซ€ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชนเชถเซ‡. เช…เชจเซ‡ เชœเซ‹ เช†เชชเชฃเซ‡ เชซเชพเช‡เชฒเชจเซ€ เชตเชฟเชจเช‚เชคเซ€ เช•เชฐเซ€เช, เชคเซ‹ เชชเชฐเชฟเชฃเชพเชฎเซ€ uri เชฎเซ‚เชณเชฅเซ€ เช…เชฒเช— เชจ เชนเซ‹เชตเซ€ เชœเซ‹เชˆเช.

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 เชคเชฐเซ€เช•เซ‡ เชฎเซ‹เช•เชฒเชตเชพเชจเซเช‚ เช›เซ‡, เชชเซเชฐเชฅเชฎ เชธเชพเชฎเช—เซเชฐเซ€-เชชเซเชฐเช•เชพเชฐ เชนเซ‡เชกเชฐเชจเซ‡ เชŸเซ‡เช•เซเชธเซเชŸ/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="/gu/${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 เชชเชฐเชค เช•เชฐเชถเซ‡ เช…เชจเซ‡ เชชเซ‡เช•เซ‡เชœเชจเซ‡ เช…เชชเชฒเซ‹เชก/เชกเชพเช‰เชจเชฒเซ‹เชก เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชถเชพ เชฎเชพเชŸเซ‡ เชเช• เชธเชฌเช•เซเชตเซ‡เชฐเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชจ เช•เชฐเซ‹ เช…เชจเซ‡ เชคเชฐเชค เชœ เช—เชฟเชŸเชฒเซ‡เชฌเชจเซ‡ เชกเซ‡เชŸเชพ เชฎเซ‹เช•เชฒเซ‹? เช•เชพเชฐเชฃ เช•เซ‡ เชชเช›เซ€ เช†เชชเชฃเซ‡ เชœเซเชฏเชพเชฐเซ‡ เชชเชฃ เช…เชงเชฟเช•เซƒเชคเชคเชพเชฎเชพเช‚ เช•เซ‹เชˆเชชเชฃ เชซเซ‡เชฐเชซเชพเชฐ เช•เชฐเซ€เช เชคเซเชฏเชพเชฐเซ‡ Nginx เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจ เชซเชพเช‡เชฒเชจเซ‡ เชธเช‚เชชเชพเชฆเชฟเชค เช•เชฐเชตเซ€ เชชเชกเชถเซ‡, เช…เชจเซ‡ เช† เชเช• เช–เซ‚เชฌ เชœ เช•เช‚เชŸเชพเชณเชพเชœเชจเช• เช•เชพเชฐเซเชฏ เช›เซ‡. เช‰เชชเชฐเชพเช‚เชค, เชœเซ‹ Kubernetes เชฎเชพเชคเซเชฐ-เชตเชพเช‚เชšเซ€ เชถเช•เชพเชฏ เชคเซ‡เชตเซ€ เชฐเซ‚เชŸ เชซเชพเช‡เชฒเชธเชฟเชธเซเชŸเชฎ เชจเซ€เชคเชฟเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡, เชคเซ‹ nginx.conf เชจเซ‡ configmap เชฆเซเชตเชพเชฐเชพ เชฌเชฆเชฒเชคเซ€ เชตเช–เชคเซ‡ เช† เชตเชงเซ เชœเชŸเชฟเชฒเชคเชพ เช‰เชฎเซ‡เชฐเซ‡ เช›เซ‡. เช…เชจเซ‡ configmap เชฆเซเชตเชพเชฐเชพ Nginx เชจเซ‡ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชฟเชค เช•เชฐเชตเซเช‚ เชเช•เชฆเชฎ เช…เชถเช•เซเชฏ เชฌเชจเซ€ เชœเชพเชฏ เช›เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชเช•เชธเชพเชฅเซ‡ เชชเซ‹เชฒเชฟเชธเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เชœเซ‡ เชตเซ‹เชฒเซเชฏเซเชฎเซเชธ (pvc) เช…เชจเซ‡ เชซเช•เซเชค เชตเชพเช‚เชšเชตเชพ เชฎเชพเชŸเซ‡เชจเชพ เชฐเซ‚เชŸ เชซเชพเช‡เชฒเชธเชฟเชธเซเชŸเชฎเชจเชพ เชœเซ‹เชกเชพเชฃเชจเซ‡ เชชเซเชฐเชคเชฟเชฌเช‚เชงเชฟเชค เช•เชฐเซ‡ เช›เซ‡ (เช† เชชเชฃ เชฅเชพเชฏ เช›เซ‡).

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 = require('aws-sdk') เช…เชจเซ‡ S3 เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เชธเชพเชฅเซ‡ "เชธเชพเชฏเช•เชฒ" เชฒเช–เชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€!

เชšเชพเชฒเซ‹ เชตเชฟเชชเช•เซเชท เชคเชฐเชซ เช†เช—เชณ เชตเชงเซ€เช

เชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡, เชฌเชพเชนเซเชฏ JS เชฎเซ‹เชกเซเชฏเซเชฒเซ‹เชจเซ‡ เช†เชฏเชพเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช…เชธเชฎเชฐเซเชฅเชคเชพ เชเช• เช…เชชเซเชฐเชฟเชฏ, เชชเชฐเช‚เชคเซ เช…เชชเซ‡เช•เซเชทเชฟเชค เชฒเช•เซเชทเชฃ เชฌเชจเซ€ เช—เชฏเซเช‚. เช‰เชชเชฐเชจเชพ เช‰เชฆเชพเชนเชฐเชฃเชฎเชพเช‚ เชตเชฐเซเชฃเชตเซ‡เชฒ, เชœเชฐเซ‚เชฐเซ€ ('เช•เซเชฐเชฟเชชเซเชŸเซ‹') เช›เซ‡ เชฌเชฟเชฒเซเชก-เช‡เชจ เชฎเซ‹เชกเซเชฏเซเชฒเซ‹ เช…เชจเซ‡ เชคเซ‡เชฎเชจเชพ เชฎเชพเชŸเซ‡ เชฎเชพเชคเซเชฐ เช•เชพเชฎเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เชธเซเช•เซเชฐเชฟเชชเซเชŸเชฎเชพเช‚เชฅเซ€ เช•เซ‹เชกเชจเซ‹ เชซเชฐเซ€เชฅเซ€ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ€ เช•เซ‹เชˆ เชฐเซ€เชค เชชเชฃ เชจเชฅเซ€ เช…เชจเซ‡ เชคเชฎเชพเชฐเซ‡ เชคเซ‡เชจเซ‡ เช…เชฒเช—-เช…เชฒเช— เชซเชพเช‡เชฒเซ‹เชฎเชพเช‚ เช•เซ‰เชชเชฟ เช•เชฐเซ€เชจเซ‡ เชชเซ‡เชธเซเชŸ เช•เชฐเชตเซ€ เชชเชกเชถเซ‡. เชนเซเช‚ เช†เชถเชพ เชฐเชพเช–เซเช‚ เช›เซเช‚ เช•เซ‡ เช•เซ‹เชˆ เชฆเชฟเชตเชธ เช† เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพ เช…เชฎเชฒเชฎเชพเช‚ เช†เชตเชถเซ‡.

Nginx เชฎเชพเช‚ เชตเชฐเซเชคเชฎเชพเชจ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชฎเชพเชŸเซ‡ เช•เชฎเซเชชเซเชฐเซ‡เชถเชจ เชชเชฃ เช…เช•เซเชทเชฎ เชนเซ‹เชตเซเช‚ เช†เชตเชถเซเชฏเช• เช›เซ‡ gzip off;

เช•เชพเชฐเชฃ เช•เซ‡ NJS เชฎเชพเช‚ เช•เซ‹เชˆ gzip เชฎเซ‹เชกเซเชฏเซเชฒ เชจเชฅเซ€ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเชตเซเช‚ เช…เชถเช•เซเชฏ เช›เซ‡; เชคเซ‡เชฅเซ€, เชธเช‚เช•เซเชšเชฟเชค เชกเซ‡เชŸเชพ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพเชจเซ€ เช•เซ‹เชˆ เชฐเซ€เชค เชจเชฅเซ€. เชธเชพเชšเซเช‚, เช† เช•เซ‡เชธ เชฎเชพเชŸเซ‡ เช† เช–เชฐเซ‡เช–เชฐ เชฎเชพเชˆเชจเชธ เชจเชฅเซ€. เชคเซเชฏเชพเช‚ เช˜เชฃเชพ เชฌเชงเชพ เชŸเซ‡เช•เซเชธเซเชŸ เชจเชฅเซ€, เช…เชจเซ‡ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เชซเชพเช‡เชฒเซ‹ เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เชธเช‚เช•เซเชšเชฟเชค เช›เซ‡ เช…เชจเซ‡ เชตเชงเชพเชฐเชพเชจเชพ เช•เชฎเซเชชเซเชฐเซ‡เชถเชจ เชคเซ‡เชฎเชจเซ‡ เชตเชงเซ เชฎเชฆเชฆ เช•เชฐเชถเซ‡ เชจเชนเซ€เช‚. เช‰เชชเชฐเชพเช‚เชค, เช† เชเชตเซ€ เชฒเซ‹เชก เช•เชฐเซ‡เชฒเซ€ เช…เชฅเชตเชพ เชœเชŸเชฟเชฒ เชธเซ‡เชตเชพ เชจเชฅเซ€ เช•เซ‡ เชคเชฎเชพเชฐเซ‡ เชธเชพเชฎเช—เซเชฐเซ€เชจเซ‡ เชฅเซ‹เชกเชพ เชฎเชฟเชฒเชฟเชธเซ‡เช•เชจเซเชกเซเชธ เชเชกเชชเชฅเซ€ เชชเชนเซ‹เช‚เชšเชพเชกเชตเชพเชจเซ€ เชšเชฟเช‚เชคเชพ เช•เชฐเชตเซ€ เชชเชกเซ‡.

เชธเซเช•เซเชฐเชฟเชชเซเชŸเชจเซ‡ เชกเซ€เชฌเช— เช•เชฐเชตเชพเชฎเชพเช‚ เชฒเชพเช‚เชฌเซ‹ เชธเชฎเชฏ เชฒเชพเช—เซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡ เชซเช•เซเชค error.log เชฎเชพเช‚ "เชชเซเชฐเชฟเชจเซเชŸเซเชธ" เชฆเซเชตเชพเชฐเชพ เชœ เชถเช•เซเชฏ เช›เซ‡. เชธเซ‡เชŸ เชฒเซ‰เช—เชฟเช‚เช— เชฒเซ‡เชตเชฒเชจเซ€ เชฎเชพเชนเชฟเชคเซ€, เชšเซ‡เชคเชตเชฃเซ€ เช…เชฅเชตเชพ เชญเซ‚เชฒเชจเชพ เช†เชงเชพเชฐเซ‡, เช…เชจเซเช•เซเชฐเชฎเซ‡ r.log, r.warn, r.errorเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเซ‹ เชถเช•เซเชฏ เช›เซ‡. เชนเซเช‚ Chrome (v3) เช…เชฅเชตเชพ njs เช•เชจเซเชธเซ‹เชฒ เชŸเซ‚เชฒเชฎเชพเช‚ เช•เซ‡เชŸเชฒเซ€เช• เชธเซเช•เซเชฐเชฟเชชเซเชŸเซเชธเชจเซ‡ เชกเซ€เชฌเช— เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซเช‚ เช›เซเช‚, เชชเชฐเช‚เชคเซ เชคเซเชฏเชพเช‚ เชฌเชงเซเช‚ เชœ เชคเชชเชพเชธเซ€ เชถเช•เชพเชคเซเช‚ เชจเชฅเซ€. เช•เซ‹เชก เชกเซ€เชฌเช— เช•เชฐเชคเซ€ เชตเช–เชคเซ‡, เช‰เชฐเซเชซเซ‡ เช•เชพเชฐเซเชฏเชพเชคเซเชฎเช• เชชเชฐเซ€เช•เซเชทเชฃ, เช‡เชคเชฟเชนเชพเชธ เช•เช‚เชˆเช• เช†เชจเชพ เชœเซ‡เชตเซ‹ เชฆเซ‡เช–เชพเชฏ เช›เซ‡:

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

เช…เชจเซ‡ เช†เชตเชพ เชธเซ‡เช‚เช•เชกเซ‹ เชธเชฟเช•เซเชตเชจเซเชธ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡.

เชคเซ‡เชฎเชจเชพ เชฎเชพเชŸเซ‡ เชธเชฌเช•เซเชตเซ‡เชฐเซ€เช เช…เชจเซ‡ เชตเซ‡เชฐเชฟเชฏเซ‡เชฌเชฒเซเชธเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เซ‹เชก เชฒเช–เชตเชพเชฅเซ€ เช—เซ‚เช‚เชšเชตเชฃเชญเชฐเซ€ เช—เซ‚เช‚เชšเชฎเชพเช‚ เชซเซ‡เชฐเชตเชพเชฏ เช›เซ‡. เช•เซ‡เชŸเชฒเซ€เช•เชตเชพเชฐ เชคเชฎเซ‡ เชคเชฎเชพเชฐเชพ เช•เซ‹เชกเชจเซ€ เช•เซเชฐเชฟเชฏเชพเช“เชจเซ‹ เช•เซเชฐเชฎ เชถเซ‹เชงเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เชจเซ‡ เชตเชฟเชตเชฟเชง IDE เชตเชฟเชจเซเชกเซ‹เชจเซ€ เช†เชธเชชเชพเชธ เชฆเซ‹เชกเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ‹ เช›เซ‹. เชคเซ‡ เชฎเซเชถเซเช•เซ‡เชฒ เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เช•เซ‡เชŸเชฒเซ€เช•เชตเชพเชฐ เชคเซ‡ เช–เซ‚เชฌ เชœ เชนเซ‡เชฐเชพเชจ เช•เชฐเซ‡ เช›เซ‡.

ES6 เชฎเชพเชŸเซ‡ เช•เซ‹เชˆ เชธเช‚เชชเซ‚เชฐเซเชฃ เชธเชฎเชฐเซเชฅเชจ เชจเชฅเซ€.

เช•เซ‡เชŸเชฒเซ€เช• เช…เชจเซเชฏ เช–เชพเชฎเซ€เช“ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชฎเชจเซ‡ เชฌเซ€เชœเซเช‚ เช•เช‚เชˆเชชเชฃ เชฎเชณเซเชฏเซเช‚ เชจเชฅเซ€. เชœเซ‹ เชคเชฎเชจเซ‡ NJS เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ‹ เชจเช•เชพเชฐเชพเชคเซเชฎเช• เช…เชจเซเชญเชต เชนเซ‹เชฏ เชคเซ‹ เชฎเชพเชนเชฟเชคเซ€ เชถเซ‡เชฐ เช•เชฐเซ‹.

เชจเชฟเชทเซเช•เชฐเซเชท

NJS เช เชนเชณเชตเชพ เชตเชœเชจเชจเชพ เช“เชชเชจ-เชธเซ‹เชฐเซเชธ เชฆเซเชญเชพเชทเชฟเชฏเชพ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ Nginx เชฎเชพเช‚ เชตเชฟเชตเชฟเชง JavaScript เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ‹ เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. เชคเซ‡เชจเชพ เชตเชฟเช•เชพเชธ เชฆเชฐเชฎเชฟเชฏเชพเชจ, เชชเซเชฐเชฆเชฐเซเชถเชจ เชชเชฐ เช–เซ‚เชฌ เชงเซเชฏเชพเชจ เช†เชชเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเชคเซเช‚. เช…เชฒเชฌเชคเซเชค, เชนเชœเซ€ เชชเชฃ เช˜เชฃเซเช‚ เช–เซ‚เชŸเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชเช• เชจเชพเชจเซ€ เชŸเซ€เชฎ เชฆเซเชตเชพเชฐเชพ เชตเชฟเช•เชธเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชฐเชนเซเชฏเซ‹ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เช“ เชธเช•เซเชฐเชฟเชฏเชชเชฃเซ‡ เชจเชตเซ€ เชธเซเชตเชฟเชงเชพเช“ เช‰เชฎเซ‡เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ‡ เช…เชจเซ‡ เชญเซ‚เชฒเซ‹เชจเซ‡ เช เซ€เช• เช•เชฐเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ‡. เชนเซเช‚ เช†เชถเชพ เชฐเชพเช–เซเช‚ เช›เซเช‚ เช•เซ‡ เช•เซ‹เชˆ เชฆเชฟเชตเชธ NJS เชคเชฎเชจเซ‡ เชฌเชพเชนเซเชฏ เชฎเซ‹เชกเซเชฏเซเชฒเซ‹เชจเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชถเซ‡, เชœเซ‡ Nginx เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพเชจเซ‡ เชฒเช—เชญเช— เช…เชฎเชฐเซเชฏเชพเชฆเชฟเชค เชฌเชจเชพเชตเชถเซ‡. เชชเชฐเช‚เชคเซ เชคเซเชฏเชพเช‚ เชเชจเชœเซ€เช†เชˆเชเชจเชเช•เซเชธ เชชเซเชฒเชธ เช›เซ‡ เช…เชจเซ‡ เชธเช‚เชญเชตเชคเชƒ เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เชธเซเชตเชฟเชงเชพเช“ เชนเชถเซ‡ เชจเชนเซ€เช‚!

เชฒเซ‡เช– เชฎเชพเชŸเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เช•เซ‹เชก เชธเชพเชฅเซ‡ เชญเช‚เชกเชพเชฐ

AWS เชธเชพเช‡เชจ v4 เชธเชชเซ‹เชฐเซเชŸ เชธเชพเชฅเซ‡ njs-pypi

ngx_http_js_module เชฎเซ‹เชกเซเชฏเซเชฒเชจเชพ เชจเชฟเชฐเซเชฆเซ‡เชถเซ‹เชจเซเช‚ เชตเชฐเซเชฃเชจ

เชธเชคเซเชคเชพเชตเชพเชฐ NJS เชญเช‚เชกเชพเชฐ ะธ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ

เชฆเชฟเชฎเชฟเชคเซเชฐเซ€ เชตเซ‹เชฒเชฟเชจเซเชŸเชธเซ‡เชต เชคเชฐเชซเชฅเซ€ NJS เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเชพ เช‰เชฆเชพเชนเชฐเชฃเซ‹

njs - nginx เชฎเชพเช‚ เชฎเซ‚เชณ JavaScript เชธเซเช•เซเชฐเชฟเชชเซเชŸเซ€เช‚เช— / เชธเซ‡เชจเซเชŸ เชนเชพเช‡เชฒเซ‹เชก++ 2019 เช–เชพเชคเซ‡ เชฆเชฟเชฎเชฟเชคเซเชฐเซ€ เชตเซ‹เชฒเซเชจเซ€เชต เชฆเซเชตเชพเชฐเชพ เชตเช•เซเชคเชตเซเชฏ

เช‰เชคเซเชชเชพเชฆเชจเชฎเชพเช‚ NJS / HighLoad++ 2019 เชชเชฐ เชตเซ‡เชธเชฟเชฒเซ€ เชธเซ‹เชถเซเชจเชฟเช•เซ‹เชต เชฆเซเชตเชพเชฐเชพ เชตเช•เซเชคเชตเซเชฏ

AWS เชฎเชพเช‚ REST เชตเชฟเชจเช‚เชคเซ€เช“ เชชเชฐ เชนเชธเซเชคเชพเช•เซเชทเชฐ เช…เชจเซ‡ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ

เชธเซ‹เชฐเซเชธ: www.habr.com