āφāĻŽāĻŋ āĻ…āύ⧁āĻŽā§‹āĻĻāύ āĻāĻŦāĻ‚ S3 āϏāĻš āφāĻŽāĻžāϰ āύāĻŋāϜāĻ¸ā§āĻŦ PyPI āϏāĻ‚āĻ—ā§āϰāĻšāĻ¸ā§āĻĨāϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĻ›āĻŋāĨ¤ Nginx-āĻ

āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧ⧇ āφāĻŽāĻŋ NJS-āĻāϰ āϏāĻžāĻĨ⧇ āφāĻŽāĻžāϰ āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰāϤ⧇ āϚāĻžāχ, Nginx Inc āĻĻā§āĻŦāĻžāϰāĻž āϤ⧈āϰāĻŋ Nginx-āĻāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻĻā§‹āĻ­āĻžāώ⧀, āĻāĻ•āϟāĻŋ āĻŦāĻžāĻ¸ā§āϤāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāϰ āĻĒā§āϰāϧāĻžāύ āĻ•ā§āώāĻŽāϤāĻžāϗ⧁āϞāĻŋ āĻŦāĻ°ā§āĻŖāύāĻž āĻ•āϰ⧇āĨ¤ NJS āĻšāϞ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āĻāĻ•āϟāĻŋ āωāĻĒāϏ⧇āϟ āϝāĻž āφāĻĒāύāĻžāϕ⧇ Nginx āĻāϰ āĻ•āĻžāĻ°ā§āϝāĻ•āĻžāϰāĻŋāϤāĻž āĻĒā§āϰāϏāĻžāϰāĻŋāϤ āĻ•āϰāϤ⧇ āĻĻ⧇āϝāĻŧāĨ¤ āĻĒā§āϰāĻļā§āύ āĻ•āϰāϤ⧇ āϕ⧇āύ āφāĻĒāύāĻžāϰ āύāĻŋāĻœā§‡āϰ āĻĻā§‹āĻ­āĻžāώ⧀??? āĻĻāĻŋāĻŽāĻŋāĻ¤ā§āϰāĻŋ āĻ­āϞāĻŋāĻ¨ā§āϟāϏ⧇āĻ­ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āωāĻ¤ā§āϤāϰ āĻĻāĻŋāϝāĻŧ⧇āϛ⧇āύāĨ¤ āϏāĻ‚āĻ•ā§āώ⧇āĻĒ⧇: NJS āĻšāϞ nginx-āĻ“āϝāĻŧ⧇, āĻāĻŦāĻ‚ JavaScript āφāϰāĻ“ āĻĒā§āϰāĻ—āϤāĻŋāĻļā§€āϞ, "āύ⧇āϟāĻŋāĻ­" āĻāĻŦāĻ‚ GC āĻ›āĻžāĻĄāĻŧāĻžāχ, Lua āĻĨ⧇āϕ⧇ āĻ­āĻŋāĻ¨ā§āύāĨ¤

āĻ…āύ⧇āĻ• āĻĻāĻŋāύ āφāϗ⧇â€Ļ

āφāĻŽāĻžāϰ āĻļ⧇āώ āϚāĻžāĻ•āϰāĻŋāϤ⧇, āφāĻŽāĻŋ āωāĻ¤ā§āϤāϰāĻžāϧāĻŋāĻ•āĻžāϰāϏ⧂āĻ¤ā§āϰ⧇ āĻ—āĻŋāϟāĻ˛ā§āϝāĻžāĻŦ āĻĒ⧇āϝāĻŧ⧇āĻ›āĻŋāϞāĻžāĻŽ āĻĄāĻ•āĻžāϰ-āĻ•āĻŽā§āĻĒā§‹āϜ, āĻĄāĻŋāĻ¨ā§āĻĄ āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āφāύāĻ¨ā§āĻĻ āϏāĻš āĻŦ⧇āĻļ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āĻŽā§‹āϟāϞāĻŋ āϏāĻŋāφāχ/āϏāĻŋāĻĄāĻŋ āĻĒāĻžāχāĻĒāϞāĻžāχāύ āϏāĻš, āϝ⧇āϗ⧁āϞāĻŋ āĻ•āĻžāύāĻŋāϕ⧋ āϰ⧇āϞ⧇ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰāĻŋāϤ āĻšāϝāĻŧ⧇āĻ›āĻŋāϞāĨ¤ āĻĒā§‚āĻ°ā§āĻŦ⧇ CI āϤ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻ›āĻŦāĻŋāϗ⧁āϞāĻŋāϕ⧇ āϤāĻžāĻĻ⧇āϰ āφāϏāϞ āφāĻ•āĻžāϰ⧇ āϏāϰāĻžāύ⧋ āĻšāϝāĻŧ⧇āĻ›āĻŋāϞāĨ¤ āϝ⧇āĻĻāĻŋāύ āφāĻŽāĻžāĻĻ⧇āϰ āĻ—āĻŋāϟāĻ˛ā§āϝāĻžāĻŦ āφāχāĻĒāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāĻŋāϤ āĻšāϝāĻŧ āĻāĻŦāĻ‚ āϏāĻŋāφāχ āϕ⧁āĻŽāĻĄāĻŧāĻžāϝāĻŧ āĻĒāϰāĻŋāĻŖāϤ āĻšāϝāĻŧ āϏ⧇āχ āĻĻāĻŋāύ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϤāĻžāϰāĻž āϏāĻ āĻŋāĻ•āĻ­āĻžāĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇āĻ›āĻŋāϞāĨ¤ āϏāĻŽāĻ¸ā§āϝāĻžāϟāĻŋ āĻ›āĻŋāϞ āϏāĻŋāφāχ-āϤ⧇ āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāĻŖāĻ•āĻžāϰ⧀ āĻĄāĻ•āĻžāϰ āχāĻŽā§‡āϜāϗ⧁āϞāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ āĻāĻ•āϟāĻŋāϤ⧇ āĻ—āĻŋāϟ āĻ›āĻŋāϞ, āϝāĻž ssh āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻĒāĻžāχāĻĨāύ āĻŽāĻĄāĻŋāωāϞ āĻŸā§‡āύ⧇āĻ›āĻŋāϞāĨ¤ ssh āĻāϰ āϜāĻ¨ā§āϝ āφāĻĒāύāĻžāϰ āĻāĻ•āϟāĻŋ āĻĒā§āϰāĻžāχāϭ⧇āϟ āϕ⧀ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻāĻŦāĻ‚... āĻāϟāĻŋ āĻĒāϰāĻŋāϚāĻŋāϤ_āĻšā§‹āĻ¸ā§āĻŸā§‡āϰ āϏāĻžāĻĨ⧇ āχāĻŽā§‡āĻœā§‡ āĻ›āĻŋāϞāĨ¤ āĻāĻŦāĻ‚ āφāϏāϞ āφāχāĻĒāĻŋ āĻāĻŦāĻ‚ āĻĒāϰāĻŋāϚāĻŋāϤ_āĻšā§‹āĻ¸ā§āĻŸā§‡ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻ•āϰāĻž āĻāĻ•āϟāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ āĻ…āĻŽāĻŋāϞ⧇āϰ āĻ•āĻžāϰāϪ⧇ āϝ⧇āϕ⧋āύ āϏāĻŋāφāχ āĻāĻ•āϟāĻŋ āĻŽā§‚āϞ āϝāĻžāϚāĻžāχāĻ•āϰāĻŖ āĻ¤ā§āϰ⧁āϟāĻŋāϰ āϏāĻžāĻĨ⧇ āĻŦā§āϝāĻ°ā§āĻĨ āĻšāϝāĻŧ⧇āϛ⧇āĨ¤ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻĄāĻ•āĻĢāĻžāχāϞāϏ āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āϚāĻŋāĻ¤ā§āϰ āĻĻā§āϰ⧁āϤ āĻāĻ•āĻ¤ā§āϰāĻŋāϤ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āĻ›āĻŋāϞ āĻāĻŦāĻ‚ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāϟāĻŋ āϝ⧋āĻ— āĻ•āϰāĻž āĻšāϝāĻŧ⧇āĻ›āĻŋāϞ StrictHostKeyChecking no. āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻ–āĻžāϰāĻžāĻĒ āĻ¸ā§āĻŦāĻžāĻĻ āĻĨ⧇āϕ⧇ āϝāĻžāϝāĻŧ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āĻŦā§āϝāĻ•ā§āϤāĻŋāĻ—āϤ PyPI āϏāĻ‚āĻ—ā§āϰāĻšāĻ¸ā§āĻĨāϞ⧇ libs āϏāϰāĻžāύ⧋āϰ āχāĻšā§āĻ›āĻž āĻ›āĻŋāϞāĨ¤ āĻāĻ•āϟāĻŋ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŦā§‹āύāĻžāϏ, āĻŦā§āϝāĻ•ā§āϤāĻŋāĻ—āϤ PyPI-āϤ⧇ āĻ¸ā§āϝ⧁āχāϚ āĻ•āϰāĻžāϰ āĻĒāϰ⧇, āĻāĻ•āϟāĻŋ āϏāĻšāϜ āĻĒāĻžāχāĻĒāϞāĻžāχāύ āĻāĻŦāĻ‚ requirements.txt-āĻāϰ āĻāĻ•āϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻŦāĻŋāĻŦāϰāĻŖ āĻ›āĻŋāϞ

āĻĒāĻ›āĻ¨ā§āĻĻ āĻšāϝāĻŧ⧇āϛ⧇, āĻ­āĻĻā§āϰāϞ⧋āĻ•!

āφāĻŽāϰāĻž āĻŽā§‡āϘ āĻāĻŦāĻ‚ āϕ⧁āĻŦāĻžāϰāύ⧇āĻŸā§‡ āϏāĻŦāĻ•āĻŋāϛ⧁ āϚāĻžāϞāĻžāχ, āĻāĻŦāĻ‚ āĻļ⧇āώ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āφāĻŽāϰāĻž āĻāĻ•āϟāĻŋ āϛ⧋āϟ āĻĒāϰāĻŋāώ⧇āĻŦāĻž āĻĒ⧇āϤ⧇ āĻšā§‡āϝāĻŧ⧇āĻ›āĻŋāϞāĻžāĻŽ āϝāĻž āĻŦāĻšāĻŋāϰāĻžāĻ—āϤ āĻ¸ā§āĻŸā§‹āϰ⧇āϜ āϏāĻš āĻāĻ•āϟāĻŋ āϰāĻžāĻˇā§āĻŸā§āϰāĻšā§€āύ āϧāĻžāϰāĻ• āĻ›āĻŋāϞāĨ¤ āĻ āĻŋāĻ• āφāϛ⧇, āϝ⧇āĻšā§‡āϤ⧁ āφāĻŽāϰāĻž S3 āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŋ, āϤāĻžāχ āĻāϟāĻŋāϕ⧇ āĻ…āĻ—ā§āϰāĻžāϧāĻŋāĻ•āĻžāϰ āĻĻ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧ⧇āĻ›āĻŋāϞāĨ¤ āĻāĻŦāĻ‚, āϝāĻĻāĻŋ āϏāĻŽā§āĻ­āĻŦ āĻšāϝāĻŧ, āĻ—āĻŋāϟāĻ˛ā§āϝāĻžāĻŦ⧇ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āϏāĻš (āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧇ āφāĻĒāύāĻŋ āύāĻŋāĻœā§‡āχ āĻāϟāĻŋ āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ)āĨ¤

āĻāĻ•āϟāĻŋ āĻĻā§āϰ⧁āϤ āĻ…āύ⧁āϏāĻ¨ā§āϧāĻžāύ āĻŦ⧇āĻļ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āĻĢāϞāĻžāĻĢāϞ āĻĻāĻŋāϝāĻŧ⧇āϛ⧇: s3pypi, pypicloud āĻāĻŦāĻ‚ āĻļāĻžāϞāĻ—āĻŽā§‡āϰ āϜāĻ¨ā§āϝ html āĻĢāĻžāχāϞ āϤ⧈āϰāĻŋāϰ "āĻŽā§āϝāĻžāύ⧁āϝāĻŧāĻžāϞ" āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āϏāĻšāĨ¤ āĻļ⧇āώ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāϟāĻŋ āύāĻŋāĻœā§‡āχ āĻ…āĻĻ⧃āĻļā§āϝ āĻšāϝāĻŧ⧇ āϗ⧇āϛ⧇āĨ¤

s3pypi: āĻāϟāĻŋ S3 āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ cli. āφāĻŽāϰāĻž āĻĢāĻžāχāϞ āφāĻĒāϞ⧋āĻĄ āĻ•āϰāĻŋ, āĻāχāϚāϟāĻŋāĻāĻŽāĻāϞ āϤ⧈āϰāĻŋ āĻ•āϰāĻŋ āĻāĻŦāĻ‚ āĻāĻ•āχ āĻŦāĻžāϞāϤāĻŋāϤ⧇ āφāĻĒāϞ⧋āĻĄ āĻ•āϰāĻŋāĨ¤ āĻŦāĻžāĻĄāĻŧāĻŋāϤ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āϜāĻ¨ā§āϝ āωāĻĒāϝ⧁āĻ•ā§āϤāĨ¤

āĻĒāĻžāχāĻĒāĻŋāĻ•ā§āϞāĻžāωāĻĄ: āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āφāĻ•āĻ°ā§āώāĻŖā§€āϝāĻŧ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇āϰ āĻŽāϤ⧋ āĻŽāύ⧇ āĻšāϝāĻŧ⧇āĻ›āĻŋāϞ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻĒāĻĄāĻŧāĻžāϰ āĻĒāϰ⧇ āφāĻŽāĻŋ āĻšāϤāĻžāĻļ āĻšāϝāĻŧ⧇āĻ›āĻŋāĨ¤ āĻ­āĻžāϞ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻ…āύ⧁āϏāĻžāϰ⧇ āĻĒā§āϰāϏāĻžāϰāĻŋāϤ āĻ•āϰāĻžāϰ āĻ•ā§āώāĻŽāϤāĻž āĻĨāĻžāĻ•āĻž āϏāĻ¤ā§āĻ¤ā§āĻŦ⧇āĻ“, āĻŦāĻžāĻ¸ā§āϤāĻŦ⧇ āĻāϟāĻŋ āĻ…āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āĻāĻŦāĻ‚ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ āĻ•āϰāĻž āĻ•āĻ āĻŋāύ āĻšāϝāĻŧ⧇ āωāϠ⧇āϛ⧇āĨ¤ āϏ⧇āχ āϏāĻŽāϝāĻŧ⧇āϰ āĻ…āύ⧁āĻŽāĻžāύ āĻ…āύ⧁āϝāĻžāϝāĻŧā§€ āφāĻĒāύāĻžāϰ āĻ•āĻžāĻœā§‡āϰ āϜāĻ¨ā§āϝ āϕ⧋āĻĄāϟāĻŋ āϏāĻ‚āĻļā§‹āϧāύ āĻ•āϰāϤ⧇ 3-5 āĻĻāĻŋāύ āϏāĻŽāϝāĻŧ āϞāĻžāĻ—āϤāĨ¤ āĻĒāϰāĻŋāώ⧇āĻŦāĻžāϟāĻŋāϰāĻ“ āĻāĻ•āϟāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒā§āϰāϝāĻŧā§‹āϜāύāĨ¤ āφāĻŽāϰāĻž āĻ…āĻ¨ā§āϝ āĻ•āĻŋāϛ⧁ āύāĻž āĻĒāĻžāĻ“āϝāĻŧāĻžāϝāĻŧ āĻāϟāĻŋ āϛ⧇āĻĄāĻŧ⧇ āĻĻāĻŋāϝāĻŧ⧇āĻ›āĻŋāĨ¤

āφāϰāĻ“ āĻ—āĻ­ā§€āϰ āĻ…āύ⧁āϏāĻ¨ā§āϧāĻžāύ⧇ Nginx, ngx_aws_auth-āĻāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āĻŽāĻĄāĻŋāωāϞ āĻĒāĻžāĻ“āϝāĻŧāĻž āϗ⧇āϛ⧇āĨ¤ āϤāĻžāϰ āĻĒāϰ⧀āĻ•ā§āώāĻžāϰ āĻĢāϞāĻžāĻĢāϞ āĻŦā§āϰāĻžāωāϜāĻžāϰ⧇ āĻĒā§āϰāĻĻāĻ°ā§āĻļāĻŋāϤ XML āĻ›āĻŋāϞ, āϝāĻž S3 āĻŦāĻžāϞāϤāĻŋāϰ āĻŦāĻŋāώāϝāĻŧāĻŦāĻ¸ā§āϤ⧁ āĻĻ⧇āĻ–āĻžāϝāĻŧāĨ¤ āĻ…āύ⧁āϏāĻ¨ā§āϧāĻžāύ⧇āϰ āϏāĻŽāϝāĻŧ āĻļ⧇āώ āĻĒā§āϰāϤāĻŋāĻļā§āϰ⧁āϤāĻŋāϟāĻŋ āĻ›āĻŋāϞ āĻāĻ• āĻŦāĻ›āϰ āφāϗ⧇āĨ¤ āĻ­āĻžāĻ¨ā§āĻĄāĻžāϰāϟāĻŋ āĻĒāϰāĻŋāĻ¤ā§āϝāĻ•ā§āϤ āĻĻ⧇āĻ–āĻžāĻšā§āĻ›āĻŋāϞāĨ¤

āĻ‰ā§ŽāϏ⧇ āĻ—āĻŋāϝāĻŧ⧇ āĻĒāĻĄāĻŧ⧇ āĻĒāĻŋāχāĻĒāĻŋ -ā§§ āφāĻŽāĻŋ āĻŦ⧁āĻāϤ⧇ āĻĒ⧇āϰ⧇āĻ›āĻŋ āϝ⧇ āĻāĻ•ā§āϏāĻāĻŽāĻāϞ āĻĢā§āϞāĻžāχāϤ⧇ āĻāχāϚāϟāĻŋāĻāĻŽāĻāϞ-āĻ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰāĻŋāϤ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āĻāĻŦāĻ‚ āĻĒāĻŋāĻĒ-āĻ āĻĻ⧇āĻ“āϝāĻŧāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ Nginx āĻāĻŦāĻ‚ S3 āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āĻ•āĻŋāϛ⧁ āϗ⧁āĻ—āϞ āĻ•āϰāĻžāϰ āĻĒāϰ⧇, āφāĻŽāĻŋ Nginx-āĻāϰ āϜāĻ¨ā§āϝ JS-āĻ āϞ⧇āĻ–āĻž S3-āϤ⧇ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāϪ⧇āϰ āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ āĻĒ⧇āϝāĻŧ⧇āĻ›āĻŋāĨ¤ āĻāĻ­āĻžāĻŦ⧇āχ āφāĻŽāĻŋ āĻāύāĻœā§‡āĻāϏ⧇āϰ āϏāĻžāĻĨ⧇ āĻĻ⧇āĻ–āĻž āĻ•āϰ⧇āĻ›āĻŋāĨ¤

āĻāχ āωāĻĻāĻžāĻšāϰāĻŖāϟāĻŋāϕ⧇ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻšāĻŋāϏāĻžāĻŦ⧇ āĻ—ā§āϰāĻšāĻŖ āĻ•āϰ⧇, āĻāĻ• āϘāĻ¨ā§āϟāĻž āĻĒāϰ⧇ āφāĻŽāĻŋ āφāĻŽāĻžāϰ āĻŦā§āϰāĻžāωāϜāĻžāϰ⧇ ngx_aws_auth āĻŽāĻĄāĻŋāωāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻāĻ•āχ XML āĻĻ⧇āϖ⧇āĻ›āĻŋ, āϤāĻŦ⧇ āϏāĻŦāĻ•āĻŋāϛ⧁ āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇ JS-āĻ āϞ⧇āĻ–āĻž āĻ›āĻŋāϞāĨ¤

āφāĻŽāĻŋ āϏāĻ¤ā§āϝāĻŋāχ nginx āϏāĻŽāĻžāϧāĻžāύ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰ⧇āĻ›āĻŋāĨ¤ āĻĒā§āϰāĻĨāĻŽāϤ, āĻ­āĻžāϞ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻāĻŦāĻ‚ āĻ…āύ⧇āĻ• āωāĻĻāĻžāĻšāϰāĻŖ, āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧāϤ, āφāĻŽāϰāĻž āĻĢāĻžāχāϞāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāϜ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ (āĻŦāĻžāĻ•ā§āϏ⧇āϰ āĻŦāĻžāχāϰ⧇) Nginx-āĻāϰ āϏāĻŽāĻ¸ā§āϤ āϜāĻŋāύāĻŋāϏāĻĒāĻ¤ā§āϰ āĻĒāĻžāχ, āϤ⧃āϤ⧀āϝāĻŧāϤ, āϝ⧇ āϕ⧇āω Nginx-āĻāϰ āϜāĻ¨ā§āϝ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰāϗ⧁āϞāĻŋ āϕ⧀āĻ­āĻžāĻŦ⧇ āϞāĻŋāĻ–āϤ⧇ āĻšāϝāĻŧ āϤāĻž āϜāĻžāύ⧇ āϤāĻžāϰāĻž āϕ⧀ āϕ⧀ āϤāĻž āĻŦ⧁āĻāϤ⧇ āϏāĻ•ā§āώāĻŽ āĻšāĻŦ⧇āĨ¤ āĻĒāĻžāχāĻĨāύ āĻŦāĻž āĻ—ā§‹ (āϝāĻĻāĻŋ āĻ¸ā§āĻ•ā§āĻ°ā§āϝāĻžāϚ āĻĨ⧇āϕ⧇ āϞ⧇āĻ–āĻž āĻšāϝāĻŧ) āĻāϰ āϤ⧁āϞāύāĻžāϝāĻŧ āĻŽāĻŋāύāĻŋāĻŽāĻžāϞāĻŋāϜāĻŽ āφāĻŽāĻžāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āĻĒā§āϞāĻžāϏ, āύ⧇āĻ•ā§āϏāĻžāϏ⧇āϰ āĻ•āĻĨāĻž āωāĻ˛ā§āϞ⧇āĻ– āύāĻž āĻ•āϰ⧇āĨ¤

TL;DR 2 āĻĻāĻŋāύ āĻĒāϰ, PyPi-āĻāϰ āĻĒāϰ⧀āĻ•ā§āώāĻžāĻŽā§‚āϞāĻ• āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϟāĻŋ āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇āχ CI-āϤ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇āĨ¤

āĻāϟāĻž āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇?

āĻŽāĻĄāĻŋāωāϞāϟāĻŋ Nginx āĻ āϞ⧋āĻĄ āĻ•āϰāĻž āĻšāϝāĻŧ ngx_http_js_module, āĻ…āĻĢāĻŋāϏāĻŋāϝāĻŧāĻžāϞ āĻĄāĻ•āĻžāϰ āχāĻŽā§‡āϜ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ. āφāĻŽāϰāĻž āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āφāĻŽāĻĻāĻžāύāĻŋ āĻ•āϰāĻŋ js_importNginx āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύ⧇āĨ¤ āĻĢāĻžāĻ‚āĻļāύ āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻĻā§āĻŦāĻžāϰāĻž āĻŦāϞāĻž āĻšāϝāĻŧ js_content. āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻžāϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āϏ⧇āϟ āĻ•āϰāϤ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧ js_set, āϝāĻž āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡ āĻŦāĻ°ā§āĻŖāĻŋāϤ āĻĢāĻžāĻ‚āĻļāύāϟāĻŋāϕ⧇ āĻāĻ•āϟāĻŋ āϝ⧁āĻ•ā§āϤāĻŋ āĻšāĻŋāϏāĻžāĻŦ⧇ āύ⧇āϝāĻŧ⧎ āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻŽāϰāĻž āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ Nginx āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ NJS-āĻ āϏāĻžāĻŦāϕ⧁āϝāĻŧ⧇āϰāĻŋ āϚāĻžāϞāĻžāϤ⧇ āĻĒāĻžāϰāĻŋ, āϕ⧋āύ⧋ XMLHttpRequest āύāϝāĻŧāĨ¤ āĻāϟāĻŋ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ, āϏāĻ‚āĻļā§āϞāĻŋāĻˇā§āϟ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύāϟāĻŋ Nginx āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύ⧇ āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āĻāĻŦāĻ‚ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻāχ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύ⧇āϰ āĻāĻ•āϟāĻŋ subrequest āĻŦāĻ°ā§āĻŖāύāĻž āĻ•āϰāĻž āφāĻŦāĻļā§āϝāĻ•. 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 āĻāĻ•āϟāĻŋ subquery āĻ•āϰāĻž āĻšāϝāĻŧ 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, āϝāĻž āϏāĻ•āϞ āĻ•āĻŽāύāĻĒā§āϰāĻŋāĻĢāĻŋāĻ•ā§āϏ xml āωāĻĒāĻžāĻĻāĻžāύāϗ⧁āϞāĻŋāϰ āĻāĻ•āϟāĻŋ āϤāĻžāϞāĻŋāĻ•āĻž āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰāĻŦ⧇, āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇ āϏāĻŽā§āĻĒāĻ°ā§āĻ•āĻŋāϤ (PyPI āĻāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇, āϏāĻŽāĻ¸ā§āϤ āĻĒā§āϝāĻžāϕ⧇āĻœā§‡āϰ āĻāĻ•āϟāĻŋ āϤāĻžāϞāĻŋāĻ•āĻž)āĨ¤ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇ āĻŦāĻŋāώāϝāĻŧāĻŦāĻ¸ā§āϤ⧁āϰ āĻāĻ•āϟāĻŋ āϤāĻžāϞāĻŋāĻ•āĻž āĻĒ⧇āϤ⧇ āϚāĻžāύ (āϏāĻŽāĻ¸ā§āϤ āĻĒā§āϝāĻžāϕ⧇āϜ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āĻāĻ•āϟāĻŋ āϤāĻžāϞāĻŋāĻ•āĻž), āϤāĻžāĻšāϞ⧇ uri āĻ…āύ⧁āϰ⧋āϧ⧇ āĻ…āĻŦāĻļā§āϝāχ āĻāĻ•āϟāĻŋ āĻĒā§āϰāĻŋāĻĢāĻŋāĻ•ā§āϏ āĻ•ā§āώ⧇āĻ¤ā§āϰ āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇ āϝāĻžāϰ āύāĻžāĻŽ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋ (āĻĒā§āϝāĻžāϕ⧇āϜ) āĻ…āĻ—āĻ¤ā§āϝāĻž āĻāĻ•āϟāĻŋ āĻ¸ā§āĻ˛ā§āϝāĻžāĻļ / āĻĻāĻŋāϝāĻŧ⧇ āĻļ⧇āώ āĻšāĻŦ⧇āĨ¤ āĻ…āĻ¨ā§āϝāĻĨāĻžāϝāĻŧ, āĻāĻ•āϟāĻŋ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϰ āĻŦāĻŋāώāϝāĻŧāĻŦāĻ¸ā§āϤ⧁ āĻ…āύ⧁āϰ⧋āϧ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āϏāĻ‚āϘāĻ°ā§āώ āϏāĻŽā§āĻ­āĻŦ, āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒāĨ¤ aiohttp-request āĻāĻŦāĻ‚ 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 āĻšāĻŋāϏāĻžāĻŦ⧇ āĻĒāĻžāĻ āĻžāύ⧋, āĻĒā§āϰāĻĨāĻŽā§‡ āĻŸā§‡āĻ•ā§āϏāϟ/āĻāχāϚāϟāĻŋāĻāĻŽāĻāϞ āĻĻāĻŋāϝāĻŧ⧇ āĻŦāĻŋāώāϝāĻŧāĻŦāĻ¸ā§āϤ⧁-āĻĒā§āϰāĻ•āĻžāϰ āĻļāĻŋāϰ⧋āύāĻžāĻŽ āĻĒā§āϰāϤāĻŋāĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻžāĨ¤

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="/bn/${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

āφāĻŽāϰāĻž āφāĻŽāĻžāĻĻ⧇āϰ libs āϏāĻ™ā§āϗ⧇ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ.

# ХОСдаĐĩĐŧ Đ´ĐģŅ Ņ‚ĐĩŅŅ‚ĐžĐ˛ ĐŊОвОĐĩ ĐžĐēŅ€ŅƒĐļĐĩĐŊиĐĩ
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}"

āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ

āĻ—āĻŋāϟāĻ˛ā§āϝāĻžāĻŦ⧇ āĻŦāĻšāĻŋāϰāĻžāĻ—āϤ āĻĒāϰāĻŋāώ⧇āĻŦāĻžāϗ⧁āϞāĻŋāϰ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ/āĻ…āύ⧁āĻŽā§‹āĻĻāύ⧇āϰ āϜāĻ¨ā§āϝ JWT āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϏāĻŽā§āĻ­āĻŦāĨ¤ Nginx-āĻ auth_request āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻŋāĻ•āĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇, āφāĻŽāϰāĻž āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻĄā§‡āϟāĻžāϕ⧇ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡ āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ āĻ•āϞ āϏāĻŽā§āĻŦāϞāĻŋāϤ āϏāĻžāĻŦāϰāĻŋāϕ⧋āϝāĻŧ⧇āĻ¸ā§āĻŸā§‡ āĻĒ⧁āύāσāύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰāĻŦāĨ¤ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟāϟāĻŋ āĻ—āĻŋāϟāĻ˛ā§āϝāĻžāĻŦ āχāωāφāϰāĻāϞ⧇ āφāϰ⧇āĻ•āϟāĻŋ āϏāĻžāĻŦ-āϰāĻŋāϕ⧋āϝāĻŧ⧇āĻ¸ā§āϟ āĻ•āϰāĻŦ⧇ āĻāĻŦāĻ‚ āϝāĻĻāĻŋ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ āĻĄā§‡āϟāĻž āϏāĻ āĻŋāĻ•āĻ­āĻžāĻŦ⧇ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āĻ•āϰāĻž āĻšāϝāĻŧ, āϤāĻžāĻšāϞ⧇ āĻ—āĻŋāϟāĻ˛ā§āϝāĻžāĻŦ āϕ⧋āĻĄ 200 āĻĢ⧇āϰāϤ āĻĻ⧇āĻŦ⧇ āĻāĻŦāĻ‚ āĻĒā§āϝāĻžāϕ⧇āϜ āφāĻĒāϞ⧋āĻĄ/āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āĻ“āϝāĻŧāĻž āĻšāĻŦ⧇āĨ¤ āϕ⧇āύ āĻāĻ•āϟāĻŋ āϏāĻžāĻŦāϕ⧋āϝāĻŧ⧇āϰāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦ⧇āύ āύāĻž āĻāĻŦāĻ‚ āĻ…āĻŦāĻŋāϞāĻŽā§āĻŦ⧇ āĻ—āĻŋāϟāĻ˛ā§āϝāĻžāĻŦ⧇ āĻĄā§‡āϟāĻž āĻĒāĻžāĻ āĻžāĻŦ⧇āύ? āĻ•āĻžāϰāĻŖ āϤāĻžāϰāĻĒāϰ āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻ…āύ⧁āĻŽā§‹āĻĻāύ⧇ āϕ⧋āύ⧋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āφāĻŽāĻžāĻĻ⧇āϰ Nginx āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ⧇āĻļāύ āĻĢāĻžāχāϞāϟāĻŋ āϏāĻŽā§āĻĒāĻžāĻĻāύāĻž āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āĻāĻŦāĻ‚ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻŦāϰāĻ‚ āĻ•ā§āϞāĻžāĻ¨ā§āϤāĻŋāĻ•āϰ āĻ•āĻžāϜāĨ¤ āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“, āϝāĻĻāĻŋ Kubernetes āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻĒāĻ āύāϝ⧋āĻ—ā§āϝ āϰ⧁āϟ āĻĢāĻžāχāϞ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āύ⧀āϤāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇, āϤāĻžāĻšāϞ⧇ configmap-āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ nginx.conf āĻĒā§āϰāϤāĻŋāĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻāϟāĻŋ āφāϰāĻ“ āϜāϟāĻŋāϞāϤāĻž āϝ⧋āĻ— āĻ•āϰ⧇āĨ¤ āĻāĻŦāĻ‚ āĻāĻ•āχ āϏāĻžāĻĨ⧇ āĻ­āϞāĻŋāωāĻŽ (āĻĒāĻŋāĻ­āĻŋāϏāĻŋ) āĻāĻŦāĻ‚ āĻĒāĻ āύāϝ⧋āĻ—ā§āϝ āϰ⧁āϟ āĻĢāĻžāχāϞ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡āϰ āϏāĻ‚āϝ⧋āĻ— āύāĻŋāώāĻŋāĻĻā§āϧ āĻ•āϰāĻžāϰ āύ⧀āϤāĻŋāϗ⧁āϞāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻ•āύāĻĢāĻŋāĻ—āĻžāϰāĻŽā§āϝāĻžāĻĒ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ Nginx āĻ•āύāĻĢāĻŋāĻ—āĻžāϰ āĻ•āϰāĻž āĻāϕ⧇āĻŦāĻžāϰ⧇āχ āĻ…āϏāĻŽā§āĻ­āĻŦ āĻšāϝāĻŧ⧇ āĻĒāĻĄāĻŧ⧇ (āĻāϟāĻŋāĻ“ āϘāĻŸā§‡)āĨ¤

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 3āϟāĻŋ āĻĒāĻĻā§āϧāϤāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϏāĻŽā§āĻ­āĻŦāĨ¤ āφāĻŽāĻŋ Chrome (v8) āĻŦāĻž njs āĻ•āύāϏ⧋āϞ āϟ⧁āϞ⧇ āĻ•āĻŋāϛ⧁ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻĄāĻŋāĻŦāĻžāĻ— āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻŋ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏ⧇āĻ–āĻžāύ⧇ āϏāĻŦāĻ•āĻŋāϛ⧁ āĻšā§‡āĻ• āĻ•āϰāĻž āϝāĻžāϝāĻŧ āύāĻžāĨ¤ āϕ⧋āĻĄ āĻĄāĻŋāĻŦāĻžāĻ— āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ, āĻ“āϰāĻĢ⧇ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ⧀ āĻĒāϰ⧀āĻ•ā§āώāĻž, āχāϤāĻŋāĻšāĻžāϏ āĻāϰāĻ•āĻŽ āĻ•āĻŋāϛ⧁ āĻĻ⧇āĻ–āĻžāϝāĻŧ:

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

āĻāĻŦāĻ‚ āĻāϰāĻ•āĻŽ āĻļāϤ āĻļāϤ āĻ•ā§āϰāĻŽ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤

āϤāĻžāĻĻ⧇āϰ āϜāĻ¨ā§āϝ āϏāĻžāĻŦāϕ⧋āϝāĻŧāĻžāϰāĻŋ āĻāĻŦāĻ‚ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϕ⧋āĻĄ āϞ⧇āĻ–āĻž āĻāĻ•āϟāĻŋ āϜāϟāĻŋāϞ āϜāϟ āĻĒāĻžāĻ˛ā§āĻŸā§‡ āϝāĻžāϝāĻŧāĨ¤ āĻ•āĻ–āύāĻ“ āĻ•āĻ–āύāĻ“ āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āϕ⧋āĻĄā§‡āϰ āĻ•ā§āϰāĻŋāϝāĻŧāĻžāϗ⧁āϞāĻŋāϰ āĻ•ā§āϰāĻŽ āĻŦ⧇āϰ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ IDE āωāχāĻ¨ā§āĻĄā§‹āϰ āϚāĻžāϰāĻĒāĻžāĻļ⧇ āϛ⧁āϟāϤ⧇ āĻļ⧁āϰ⧁ āĻ•āϰ⧇āύāĨ¤ āĻāϟāĻŋ āĻ•āĻ āĻŋāύ āύāϝāĻŧ, āϤāĻŦ⧇ āĻ•āĻ–āύāĻ“ āĻ•āĻ–āύāĻ“ āĻāϟāĻŋ āϖ⧁āĻŦ āĻŦāĻŋāϰāĻ•ā§āϤāĻŋāĻ•āϰāĨ¤

ES6 āĻāϰ āϜāĻ¨ā§āϝ āϕ⧋āύ āĻĒā§‚āĻ°ā§āĻŖ āϏāĻŽāĻ°ā§āĻĨāύ āύ⧇āχāĨ¤

āĻ…āĻ¨ā§āϝ āĻ•āĻŋāϛ⧁ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇, āϤāĻŦ⧇ āφāĻŽāĻŋ āĻ…āĻ¨ā§āϝ āĻ•āĻŋāϛ⧁āϰ āϏāĻŽā§āĻŽā§āĻ–ā§€āύ āĻšāχāύāĻŋāĨ¤ NJS āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āφāĻĒāύāĻžāϰ āύ⧇āϤāĻŋāĻŦāĻžāϚāĻ• āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž āĻĨāĻžāĻ•āϞ⧇ āϤāĻĨā§āϝ āĻļ⧇āϝāĻŧāĻžāϰ āĻ•āϰ⧁āύāĨ¤

āωāĻĒāϏāĻ‚āĻšāĻžāϰ

NJS āĻšāϞ āĻāĻ•āϟāĻŋ āϞāĻžāχāϟāĻ“āϝāĻŧ⧇āϟ āĻ“āĻĒ⧇āύ āϏ⧋āĻ°ā§āϏ āχāĻ¨ā§āϟāĻžāϰāĻĒā§āϰ⧇āϟāĻžāϰ āϝāĻž āφāĻĒāύāĻžāϕ⧇ Nginx-āĻ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύ āĻ•āϰāϤ⧇ āĻĻ⧇āϝāĻŧāĨ¤ āĻāϰ āĻŦāĻŋāĻ•āĻžāĻļ⧇āϰ āϏāĻŽāϝāĻŧ, āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāĻ¨ā§āϏ⧇āϰ āĻĻāĻŋāϕ⧇ āĻĻ⧁āĻ°ā§āĻĻāĻžāĻ¨ā§āϤ āĻŽāύ⧋āϝ⧋āĻ— āĻĻ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧ⧇āĻ›āĻŋāϞāĨ¤ āĻ…āĻŦāĻļā§āϝāχ, āĻāĻ–āύāĻ“ āĻ…āύ⧇āĻ• āĻ•āĻŋāϛ⧁ āĻ…āύ⧁āĻĒāĻ¸ā§āĻĨāĻŋāϤ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒāϟāĻŋ āĻāĻ•āϟāĻŋ āϛ⧋āϟ āĻĻāϞ āĻĻā§āĻŦāĻžāϰāĻž āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻšāĻšā§āϛ⧇ āĻāĻŦāĻ‚ āϤāĻžāϰāĻž āϏāĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ āύāϤ⧁āύ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϝ⧋āĻ— āĻ•āϰāϛ⧇ āĻāĻŦāĻ‚ āĻŦāĻžāĻ—āϗ⧁āϞāĻŋ āĻ āĻŋāĻ• āĻ•āϰāϛ⧇⧎ āφāĻŽāĻŋ āφāĻļāĻž āĻ•āϰāĻŋ āϝ⧇ āĻāĻ•āĻĻāĻŋāύ NJS āφāĻĒāύāĻžāϕ⧇ āĻŦāĻžāĻšā§āϝāĻŋāĻ• āĻŽāĻĄāĻŋāωāϞāϗ⧁āϞāĻŋāϕ⧇ āϏāĻ‚āϝ⧁āĻ•ā§āϤ āĻ•āϰāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āĻŦ⧇, āϝāĻž Nginx āĻ•āĻžāĻ°ā§āϝāĻ•āĻžāϰāĻŋāϤāĻžāϕ⧇ āĻĒā§āϰāĻžāϝāĻŧ āϏ⧀āĻŽāĻžāĻšā§€āύ āĻ•āϰ⧇ āϤ⧁āϞāĻŦ⧇āĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ NGINX āĻĒā§āϞāĻžāϏ āφāϛ⧇ āĻāĻŦāĻ‚ āϖ⧁āĻŦ āϏāĻŽā§āĻ­āĻŦāϤ āϕ⧋āύ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āĻĨāĻžāĻ•āĻŦ⧇ āύāĻž!

āύāĻŋāĻŦāĻ¨ā§āϧ⧇āϰ āϜāĻ¨ā§āϝ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āϕ⧋āĻĄ āϏāĻš āϏāĻ‚āĻ—ā§āϰāĻšāĻ¸ā§āĻĨāϞ

AWS āϏāĻžāχāύ v4 āϏāĻŽāĻ°ā§āĻĨāύ āϏāĻš njs-pypi

ngx_http_js_module āĻŽāĻĄāĻŋāωāϞ⧇āϰ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻžāĻŦāϞ⧀āϰ āĻŦāĻ°ā§āĻŖāύāĻž

āĻ…āĻĢāĻŋāϏāĻŋāϝāĻŧāĻžāϞ NJS āϏāĻ‚āĻ—ā§āϰāĻšāĻ¸ā§āĻĨāϞ и āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ

āĻĻāĻŋāĻŽāĻŋāĻ¤ā§āϰāĻŋ Volintsev āĻĨ⧇āϕ⧇ NJS āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āωāĻĻāĻžāĻšāϰāĻŖ

njs - nginx-āĻ āύ⧇āϟāĻŋāĻ­ āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟāĻŋāĻ‚ / āϏ⧇āĻ¨ā§āϟ āĻšāĻžāχāϞ⧋āĻĄ++ 2019-āĻ āĻĻāĻŋāĻŽāĻŋāĻ¤ā§āϰāĻŋ āĻ­āϞāύāĻŋāϭ⧇āϰ āĻŦāĻ•ā§āϤ⧃āϤāĻž

āĻ‰ā§ŽāĻĒāĻžāĻĻāύ⧇ NJS / HighLoad++ 2019 āĻ āĻ­ā§āϝāĻžāϏāĻŋāϞāĻŋ āϏ⧋āĻļāύāĻŋāĻ•āϭ⧇āϰ āĻŦāĻ•ā§āϤ⧃āϤāĻž

AWS-āĻ REST āĻ…āύ⧁āϰ⧋āϧ āĻ¸ā§āĻŦāĻžāĻ•ā§āώāϰ āĻ“ āĻĒā§āϰāĻŽāĻžāĻŖā§€āĻ•āϰāĻŖ

āωāĻ¤ā§āϏ: www.habr.com

DDoS āϏ⧁āϰāĻ•ā§āώāĻž, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ āϏāĻš āϏāĻžāχāϟāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ đŸ”Ĩ DDoS āϏ⧁āϰāĻ•ā§āώāĻž āϏāĻš āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻ“āϝāĻŧ⧇āĻŦāϏāĻžāχāϟ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ | ProHoster