рдпрд╛ рд▓реЗрдЦрд╛рдд рдореА NJS рд╕рд╣ рдорд╛рдЭрд╛ рдЕрдиреБрднрд╡ рд╕рд╛рдорд╛рдпрд┐рдХ рдХрд░реВ рдЗрдЪреНрдЫрд┐рддреЛ, Nginx Inc рдиреЗ рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реЗрд▓реНрдпрд╛ Nginx рд╕рд╛рдареА JavaScript рджреБрднрд╛рд╖реА, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрджрд╛рд╣рд░рдг рд╡рд╛рдкрд░реВрди рддреНрдпрд╛рдЪреНрдпрд╛ рдореБрдЦреНрдп рдХреНрд╖рдорддрд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдХрд░рддреЛ. NJS рд╣рд╛ JavaScript рдЪрд╛ рдЙрдкрд╕рдВрдЪ рдЖрд╣реЗ рдЬреЛ рддреБрдореНрд╣рд╛рд▓рд╛ Nginx рдЪреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд╛рдврд╡рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЛ. рдкреНрд░рд╢реНрдирд╛рд▓рд╛
рдлрд╛рд░ рдкреВрд░реНрд╡реАтАж
рдорд╛рдЭреНрдпрд╛ рд╢реЗрд╡рдЯрдЪреНрдпрд╛ рдиреЛрдХрд░реАрд╡рд░, рдорд▓рд╛ рдбреЙрдХрд░-рдХрдВрдкреЛрдЬ, рдбрд┐рдВрдб рдЖрдгрд┐ рдЗрддрд░ рдЖрдирдВрджрд╛рдВрд╕рд╣ рдЕрдиреЗрдХ рдореЛрдЯрд▓реА рд╕реАрдЖрдп/рд╕реАрдбреА рдкрд╛рдЗрдкрд▓рд╛рдЗрдирд╕рд╣ рдЧрд┐рдЯрд▓реЕрдмрдЪрд╛ рд╡рд╛рд░рд╕рд╛ рдорд┐рд│рд╛рд▓рд╛, рдЬреНрдпрд╛ рдХрд╛рдирд┐рдХреЛ рд░реЗрд▓рдордзреНрдпреЗ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХреЗрд▓реНрдпрд╛ рдЧреЗрд▓реНрдпрд╛. рдкреВрд░реНрд╡реА CI рдордзреНрдпреЗ рд╡рд╛рдкрд░рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддрд┐рдорд╛ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рдореВрд│ рд╕реНрд╡рд░реВрдкрд╛рдд рд╣рд▓рд╡рд┐рдгреНрдпрд╛рдд рдЖрд▓реНрдпрд╛ рд╣реЛрддреНрдпрд╛. рдЖрдордЪрд╛ рдЧрд┐рдЯрд▓реЕрдм рдЖрдпрдкреА рдмрджрд▓рд▓рд╛ рдЖрдгрд┐ рд╕реАрдЖрдп рднреЛрдкрд│реНрдпрд╛рдд рдмрджрд▓рд▓рд╛ рддреНрдпрд╛ рджрд┐рд╡рд╕рд╛рдкрд░реНрдпрдВрдд рддреНрдпрд╛рдВрдиреА рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд╛рдо рдХреЗрд▓реЗ. рд╕рдорд╕реНрдпрд╛ рдЕрд╢реА рд╣реЛрддреА рдХреА рд╕реАрдЖрдпрдордзреНрдпреЗ рд╕рд╣рднрд╛рдЧреА рдЭрд╛рд▓реЗрд▓реНрдпрд╛ рдбреЙрдХрд░ рдкреНрд░рддрд┐рдорд╛рдВрдкреИрдХреА рдПрдХ рдЧрд┐рдЯ рд╣реЛрддреА, рдЬреА ssh рджреНрд╡рд╛рд░реЗ рдкрд╛рдпрдерди рдореЙрдбреНрдпреВрд▓реНрд╕ рдЦреЗрдЪрддреЗ. ssh рд╕рд╛рдареА рддреБрдореНрд╣рд╛рд▓рд╛ рдЦрд╛рдЬрдЧреА рдХреА рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЖрдгрд┐... рддреА рдЬреНрдЮрд╛рдд_рд╣реЛрд╕реНрдЯреНрд╕рд╕рд╣ рдЗрдореЗрдЬрдордзреНрдпреЗ рд╣реЛрддреА. рдЖрдгрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ IP рдЖрдгрд┐ рдЬреНрдЮрд╛рдд_рд╣реЛрд╕реНрдЯреНрд╕рдордзреНрдпреЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдПрдХрд╛рдордзреНрдпреЗ рдЬреБрд│рдд рдирд╕рд▓реНрдпрд╛рдореБрд│реЗ рдХреЛрдгрддреЗрд╣реА CI рдореБрдЦреНрдп рд╕рддреНрдпрд╛рдкрди рддреНрд░реБрдЯреАрд╕рд╣ рдЕрдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓реЗ. рд╡рд┐рджреНрдпрдорд╛рди рдбреЙрдХрдлрд╛рдИрд▓реНрд╕рдордзреВрди рдПрдХ рдирд╡реАрди рдкреНрд░рддрд┐рдорд╛ рджреНрд░реБрддрдкрдгреЗ рдПрдХрддреНрд░ рдХреЗрд▓реА рдЧреЗрд▓реА рдЖрдгрд┐ рдкрд░реНрдпрд╛рдп рдЬреЛрдбрд▓рд╛ рдЧреЗрд▓рд╛ StrictHostKeyChecking no
. рдкрдг рд╡рд╛рдИрдЯ рдЪрд╡ рдХрд╛рдпрдо рд░рд╛рд╣рд┐рд▓реА рдЖрдгрд┐ libs рдЦрд╛рдЬрдЧреА PyPI рднрд╛рдВрдбрд╛рд░рд╛рдд рд╣рд▓рд╡рдгреНрдпрд╛рдЪреА рдЗрдЪреНрдЫрд╛ рд╣реЛрддреА. рдЦрд╛рдЬрдЧреА PyPI рд╡рд░ рд╕реНрд╡рд┐рдЪ рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдмреЛрдирд╕, рдПрдХ рд╕реЛрдкреА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЖрдгрд┐ рдЖрд╡рд╢реНрдпрдХрддрд╛рдВрдЪреЗ рд╕рд╛рдорд╛рдиреНрдп рд╡рд░реНрдгрди рд╣реЛрддреЗ.txt
рдирд┐рд╡рдб рдЭрд╛рд▓реА рдЖрд╣реЗ, рд╕рдЬреНрдЬрдирд╛рдВрдиреЛ!
рдЖрдореНрд╣реА рдХреНрд▓рд╛рдЙрдбреНрд╕ рдЖрдгрд┐ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдордзреНрдпреЗ рд╕рд░реНрд╡рдХрд╛рд╣реА рдЪрд╛рд▓рд╡рддреЛ рдЖрдгрд┐ рд╢реЗрд╡рдЯреА рдЖрдореНрд╣рд╛рд▓рд╛ рдПрдХ рдЫреЛрдЯреА рд╕реЗрд╡рд╛ рдорд┐рд│рд╡рд╛рдпрдЪреА рд╣реЛрддреА рдЬреА рдмрд╛рд╣реНрдп рд╕реНрдЯреЛрд░реЗрдЬрд╕рд╣ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдХрдВрдЯреЗрдирд░ рд╣реЛрддреА. рдмрд░рдВ, рдЖрдореНрд╣реА S3 рд╡рд╛рдкрд░рдд рдЕрд╕рд▓реНрдпрд╛рдиреЗ, рддреНрдпрд╛рд▓рд╛ рдкреНрд░рд╛рдзрд╛рдиреНрдп рджрд┐рд▓реЗ рдЧреЗрд▓реЗ. рдЖрдгрд┐, рд╢рдХреНрдп рдЕрд╕рд▓реНрдпрд╛рд╕, gitlab рдордзреНрдпреЗ рдкреНрд░рдорд╛рдгреАрдХрд░рдгрд╛рд╕рд╣ (рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реНрдпрд╛рд╕ рдЖрдкрдг рддреЗ рд╕реНрд╡рддрдГ рдЬреЛрдбреВ рд╢рдХрддрд╛).
рджреНрд░реБрдд рд╢реЛрдзрд╛рдореБрд│реЗ рдЕрдиреЗрдХ рдкрд░рд┐рдгрд╛рдо рдорд┐рд│рд╛рд▓реЗ: s3pypi, pypicloud рдЖрдгрд┐ рд╕рд▓рдЧрдорд╕рд╛рдареА html рдлрд╛рдЗрд▓реНрд╕рдЪреНрдпрд╛ "рдореЕрдиреНрдпреБрдЕрд▓" рдирд┐рд░реНрдорд┐рддреАрд╕рд╣ рдкрд░реНрдпрд╛рдп. рд╢реЗрд╡рдЯрдЪрд╛ рдкрд░реНрдпрд╛рдп рд╕реНрд╡рддрдГрдЪ рдЧрд╛рдпрдм рдЭрд╛рд▓рд╛.
s3pypi: S3 рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╣реА рдХреНрд▓реА рдЖрд╣реЗ. рдЖрдореНрд╣реА рдлрд╛рдЗрд▓реНрд╕ рдЕрдкрд▓реЛрдб рдХрд░рддреЛ, html рдЬрдирд░реЗрдЯ рдХрд░рддреЛ рдЖрдгрд┐ рддреНрдпрд╛рдЪ рдмрдХреЗрдЯрдордзреНрдпреЗ рдЕрдкрд▓реЛрдб рдХрд░рддреЛ. рдШрд░рдЧреБрддреА рд╡рд╛рдкрд░рд╛рд╕рд╛рдареА рдпреЛрдЧреНрдп.
pypicloud: рд╣рд╛ рдПрдХ рдордиреЛрд░рдВрдЬрдХ рдкреНрд░рдХрд▓реНрдк рдЕрд╕рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ рд╡рд╛рдЯрд▓реЗ, рдкрд░рдВрддреБ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг рд╡рд╛рдЪрд▓реНрдпрд╛рдирдВрддрд░ рдореА рдирд┐рд░рд╛рд╢ рдЭрд╛рд▓реЛ. рдЪрд╛рдВрдЧрд▓реЗ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг рдЖрдгрд┐ рдЖрдкрд▓реНрдпрд╛ рдЧрд░рдЬреЗрдиреБрд╕рд╛рд░ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреА рдХреНрд╖рдорддрд╛ рдЕрд╕реВрдирд╣реА, рдкреНрд░рддреНрдпрдХреНрд╖рд╛рдд рддреЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЖрдгрд┐ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреЗ рдХрдареАрдг рдЕрд╕рд▓реНрдпрд╛рдЪреЗ рджрд┐рд╕реВрди рдЖрд▓реЗ. рддреНрдпрд╛рд╡реЗрд│рдЪреНрдпрд╛ рдЕрдВрджрд╛рдЬрд╛рдиреБрд╕рд╛рд░, рддреБрдордЪреНрдпрд╛ рдХрд╛рд░реНрдпрд╛рдВрд╕рд╛рдареА рдХреЛрдб рджреБрд░реБрд╕реНрдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рей-рел рджрд┐рд╡рд╕ рд▓рд╛рдЧрд▓реЗ рдЕрд╕рддреЗ. рд╕реЗрд╡реЗрд▓рд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рджреЗрдЦреАрд▓ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдЖрдореНрд╣рд╛рд▓рд╛ рджреБрд╕рд░реЗ рдХрд╛рд╣реА рд╕рд╛рдкрдбрд▓реЗ рдирд╛рд╣реА рддрд░ рдЖрдореНрд╣реА рддреЗ рд╕реЛрдбрд▓реЗ.
рдЕрдзрд┐рдХ рд╕рдЦреЛрд▓ рд╢реЛрдзрд╛рдореБрд│реЗ Nginx, ngx_aws_auth рд╕рд╛рдареА рдореЙрдбреНрдпреВрд▓ рдорд┐рд│рд╛рд▓реЗ. рддреНрдпрд╛рдЪреНрдпрд╛ рдЪрд╛рдЪрдгреАрдЪрд╛ рдкрд░рд┐рдгрд╛рдо рдмреНрд░рд╛рдЙрдЭрд░рдордзреНрдпреЗ XML рдкреНрд░рджрд░реНрд╢рд┐рдд рдЭрд╛рд▓рд╛, рдЬреНрдпрд╛рдиреЗ S3 рдмрдХреЗрдЯрдордзреАрд▓ рд╕рд╛рдордЧреНрд░реА рджрд░реНрд╢рд╡рд┐рд▓реА. рд╢реЛрдзрд╛рдЪреНрдпрд╛ рд╡реЗрд│реА рд╢реЗрд╡рдЯрдЪреА рдХрдорд┐рдЯ рдПрдХ рд╡рд░реНрд╖рд╛рдкреВрд░реНрд╡реАрдЪреА рд╣реЛрддреА. рднрд╛рдВрдбрд╛рд░ рднрдиреНрдирд╛рдЯ рджрд┐рд╕рдд рд╣реЛрддреЗ.
рд╕реНрд░реЛрддрд╛рд╡рд░ рдЬрд╛рдКрди рд╡рд╛рдЪреВрди
рд╣реЗ рдЙрджрд╛рд╣рд░рдг рдЖрдзрд╛рд░ рдореНрд╣рдгреВрди рдШреЗрддрд▓реНрдпрд╛рд╕, рдПрдХрд╛ рддрд╛рд╕рд╛рдирдВрддрд░ рдореА рдорд╛рдЭреНрдпрд╛ рдмреНрд░рд╛рдЙрдЭрд░рдордзреНрдпреЗ ngx_aws_auth рдореЙрдбреНрдпреВрд▓ рд╡рд╛рдкрд░рддрд╛рдирд╛ рд╕рдорд╛рди XML рдкрд╛рд╣рд┐рд▓реЗ, рдкрд░рдВрддреБ рд╕рд░реНрд╡рдХрд╛рд╣реА рдЬреЗрдПрд╕рдордзреНрдпреЗ рдЖрдзреАрдЪ рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рд╣реЛрддреЗ.
рдорд▓рд╛ nginx рд╕реЛрд▓реНрдпреВрд╢рди рдЦрд░реЛрдЦрд░ рдЖрд╡рдбрд▓реЗ. рдкреНрд░рдердо, рдЪрд╛рдВрдЧрд▓реЗ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг рдЖрдгрд┐ рдмрд░реАрдЪ рдЙрджрд╛рд╣рд░рдгреЗ, рджреБрд╕рд░реЗ рдореНрд╣рдгрдЬреЗ, рдЖрдореНрд╣рд╛рд▓рд╛ рдлрд╛рдпрд▓реАрдВрд╕рд╣ (рдмреЙрдХреНрд╕рдЪреНрдпрд╛ рдмрд╛рд╣реЗрд░) рдХрд╛рдо рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА Nginx рдЪреНрдпрд╛ рд╕рд░реНрд╡ рд╡рд╕реНрддреВ рдорд┐рд│рддрд╛рдд, рддрд┐рд╕рд░реЗ рдореНрд╣рдгрдЬреЗ, Nginx рд╕рд╛рдареА рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдХрд╕реЗ рд▓рд┐рд╣рд╛рдпрдЪреЗ рд╣реЗ рдорд╛рд╣рд┐рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдХреЛрдгрд╛рд▓рд╛рд╣реА рдХрд╛рдп рдЖрд╣реЗ рддреЗ рд╕рдордЬрдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рдЕрд╕реЗрд▓. рдорд┐рдирд┐рдорд▓рд┐рдЭрдо рджреЗрдЦреАрд▓ рдорд╛рдЭреНрдпрд╛рд╕рд╛рдареА рдПрдХ рдкреНрд▓рд╕ рдЖрд╣реЗ, рдкрд╛рдпрдерди рдХрд┐рдВрд╡рд╛ рдЧреЛ (рдЬрд░ рд╕реБрд░рд╡рд╛рддреАрдкрд╛рд╕реВрди рд▓рд┐рд╣рд┐рд▓реЗ рдЕрд╕рд▓реНрдпрд╛рд╕), рдиреЗрдХреНрд╕рд╕рдЪрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реВ рдирдХрд╛.
TL;DR 2 рджрд┐рд╡рд╕рд╛рдВрдирдВрддрд░, PyPi рдЪреА рдЪрд╛рдЪрдгреА рдЖрд╡реГрддреНрддреА рдЖрдзреАрдЪ CI рдордзреНрдпреЗ рд╡рд╛рдкрд░рд▓реА рдЧреЗрд▓реА рд╣реЛрддреА.
рддреЗ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ?
рдореЙрдбреНрдпреВрд▓ Nginx рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓реЗ рдЖрд╣реЗ ngx_http_js_module
, рдЕрдзрд┐рдХреГрдд рдбреЙрдХрд░ рдкреНрд░рддрд┐рдореЗрдордзреНрдпреЗ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ. рдЖрдореНрд╣реА рдирд┐рд░реНрджреЗрд╢ рд╡рд╛рдкрд░реВрди рдЖрдордЪреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЖрдпрд╛рдд рдХрд░рддреЛ js_import
Nginx рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдордзреНрдпреЗ. рдлрдВрдХреНрд╢рдирд▓рд╛ рдирд┐рд░реНрджреЗрд╢рд╛рджреНрд╡рд╛рд░реЗ рдХреЙрд▓ рдХреЗрд▓реЗ рдЬрд╛рддреЗ 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
, рдЬреЗ рд╕рд░реНрд╡ CommonPrefixes xml рдШрдЯрдХрд╛рдВрдЪреА рд╕реВрдЪреА рдкрд░рдд рдХрд░реЗрд▓, рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдВрд╢реА рд╕рдВрдмрдВрдзрд┐рдд (PyPI рдЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, рд╕рд░реНрд╡ рдкреЕрдХреЗрдЬреЗрд╕рдЪреА рд╕реВрдЪреА). рддреБрдореНрд╣рд╛рд▓рд╛ рдПрдЦрд╛рджреНрдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрдд (рд╕рд░реНрд╡ рдкреЕрдХреЗрдЬ рдЖрд╡реГрддреНрддреНрдпрд╛рдВрдЪреА рд╕реВрдЪреА) рд╕рд╛рдордЧреНрд░реАрдЪреА рд╕реВрдЪреА рдорд┐рд│рд╡рд╛рдпрдЪреА рдЕрд╕рд▓реНрдпрд╛рд╕, uri рд╡рд┐рдирдВрддреАрдордзреНрдпреЗ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ (рдкреЕрдХреЗрдЬ) рдЪреНрдпрд╛ рдирд╛рд╡рд╛рд╕рд╣ рдПрдХ рдЙрдкрд╕рд░реНрдЧ рдлреАрд▓реНрдб рдЕрд╕рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЬреЗ рд╕реНрд▓реЕрд╢ / рдиреЗ рд╕рдорд╛рдкреНрдд рд╣реЛрдИрд▓. рдЕрдиреНрдпрдерд╛, рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрддреАрд▓ рд╕рд╛рдордЧреНрд░реАрдЪреА рд╡рд┐рдирдВрддреА рдХрд░рддрд╛рдирд╛ рдЯрдХреНрдХрд░ рд╢рдХреНрдп рдЖрд╣реЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде. aiohttp-request рдЖрдгрд┐ aiohttp-requests рдЖрдгрд┐ рд╡рд┐рдирдВрддреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реНрдпрд╛рд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЖрд╣реЗрдд /?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>"00000000000000000000000000000000-1"</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>"b2d76df4aeb4493c5456366748218093"</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="/mr/${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}"
рдкреНрд░рдорд╛рдгреАрдХрд░рдг
Gitlab рдордзреНрдпреЗ рдмрд╛рд╣реНрдп рд╕реЗрд╡рд╛рдВрдЪреНрдпрд╛ рдкреНрд░рдорд╛рдгреАрдХрд░рдг/рдЕрдзрд┐рдХреГрддреАрдХрд░рдгрд╛рд╕рд╛рдареА JWT рд╡рд╛рдкрд░рдгреЗ рд╢рдХреНрдп рдЖрд╣реЗ. Nginx рдордзреАрд▓ auth_request рдирд┐рд░реНрджреЗрд╢ рд╡рд╛рдкрд░реВрди, рдЖрдореНрд╣реА рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдбреЗрдЯрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯрдордзреАрд▓ рдлрдВрдХреНрд╢рди рдХреЙрд▓ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╕рдмрд░рд┐рдХреНрд╡реЗрд╕реНрдЯрд╡рд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реВ. рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЧрд┐рдЯрд▓реЕрдм url рд▓рд╛ рдЖрдгрдЦреА рдПрдХ рд╕рдмрд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдХрд░реЗрд▓ рдЖрдгрд┐ рдЬрд░ рдСрдереЗрдВрдЯрд┐рдХреЗрд╢рди рдбреЗрдЯрд╛ рдпреЛрдЧреНрдпрд░рд┐рддреНрдпрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓рд╛ рдЕрд╕реЗрд▓, рддрд░ Gitlab рдХреЛрдб 200 рдкрд░рдд рдХрд░реЗрд▓ рдЖрдгрд┐ рдкреЕрдХреЗрдЬ рдЕрдкрд▓реЛрдб/рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рдЕрд╕реЗрд▓. рдПрдХ рд╕рдмрдХреНрд╡реЗрд░реА рдХрд╛ рд╡рд╛рдкрд░рдд рдирд╛рд╣реА рдЖрдгрд┐ рд▓рдЧреЗрдЪ рдбреЗрдЯрд╛ Gitlab рд▓рд╛ рдкрд╛рдард╡рд╛рдпрдЪрд╛? рдХрд╛рд░рдг рдордЧ рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдЖрдореНрд╣реА рдЕрдзрд┐рдХреГрддрддреЗрдордзреНрдпреЗ рдХреЛрдгрддреЗрд╣реА рдмрджрд▓ рдХреЗрд▓реНрдпрд╛рд╡рд░ рдЖрдореНрд╣рд╛рд▓рд╛ Nginx рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рд╛рд╡реА рд▓рд╛рдЧреЗрд▓ рдЖрдгрд┐ рд╣реЗ рдЦреВрдк рддреНрд░рд╛рд╕рджрд╛рдпрдХ рдХрд╛рдо рдЖрд╣реЗ. рддрд╕реЗрдЪ, рдЬрд░ Kubernetes рдХреЗрд╡рд│-рд╡рд╛рдЪрдиреАрдп рд░реВрдЯ рдлрд╛рдЗрд▓рд╕рд┐рд╕реНрдЯрдо рдзреЛрд░рдг рд╡рд╛рдкрд░рдд рдЕрд╕реЗрд▓, рддрд░ configmap рджреНрд╡рд╛рд░реЗ nginx.conf рдмрджрд▓рддрд╛рдирд╛ рд╣реЗ рдЖрдгрдЦреА рдЬрдЯрд┐рд▓рддрд╛ рдЬреЛрдбрддреЗ. рдЖрдгрд┐ рдПрдХрд╛рдЪ рд╡реЗрд│реА рд╡реНрд╣реЙрд▓реНрдпреВрдо (рдкреАрд╡реНрд╣реАрд╕реА) рдЖрдгрд┐ рдХреЗрд╡рд│-рд╡рд╛рдЪрдиреАрдп рд░реВрдЯ рдлрд╛рдЗрд▓рд╕рд┐рд╕реНрдЯрдо (рд╣реЗ рджреЗрдЦреАрд▓ рдШрдбрддреЗ) рдХрдиреЗрдХреНрд╢рди рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдзреЛрд░рдгреЗ рд╡рд╛рдкрд░рдд рдЕрд╕рддрд╛рдирд╛ рдХреЙрдиреНрдлрд┐рдЧрд░рдореЕрдкрджреНрд╡рд╛рд░реЗ Nginx рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреЗ рдкреВрд░реНрдгрдкрдгреЗ рдЕрд╢рдХреНрдп рд╣реЛрддреЗ.
NJS рдЗрдВрдЯрд░рдореАрдбрд┐рдПрдЯ рд╡рд╛рдкрд░реВрди, рдЖрдореНрд╣рд╛рд▓рд╛ рдПрдирдЬрд┐рдирдХреНрд╕ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдордзреАрд▓ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рдкрд░реНрдпрд╛рд╡рд░рдг рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓реНрд╕ рд╡рд╛рдкрд░реВрди рдмрджрд▓рдгреНрдпрд╛рдЪреА рдЖрдгрд┐ рд╕реНрдХреНрд░рд┐рдкреНрдЯрдордзреНрдпреЗ рдХрд╛рд╣реА рддрдкрд╛рд╕рдгреА рдХрд░рдгреНрдпрд╛рдЪреА рд╕рдВрдзреА рдорд┐рд│рддреЗ (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЪреБрдХреАрдЪреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ 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 рдкреНрд░рдорд╛рдгреАрдХрд░рдгрд╛рд╕рд╣ тАЬbikeтАЭ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА!
рдЪрд▓рд╛ рдмрд╛рдзрдХрд╛рдВрдХрдбреЗ рдЬрд╛рдКрдпрд╛
рдорд╛рдЭреНрдпрд╛рд╕рд╛рдареА, рдмрд╛рд╣реНрдп 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 рдордзреНрдпреЗ рд╡рд┐рд╡рд┐рдз JavaScript рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд╛рдЧреВ рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЛ. рддреНрдпрд╛рдЪреНрдпрд╛ рд╡рд┐рдХрд╛рд╕рд╛рджрд░рдореНрдпрд╛рди, рдХрд╛рд░реНрдпрдХреНрд╖рдорддреЗрд╡рд░ рдЦреВрдк рд▓рдХреНрд╖ рджрд┐рд▓реЗ рдЧреЗрд▓реЗ. рдЕрд░реНрдерд╛рдд, рдЕрдЬреВрдирд╣реА рдмрд░реЗрдЪ рдХрд╛рд╣реА рдЧрд╣рд╛рд│ рдЖрд╣реЗ, рдкрд░рдВрддреБ рдкреНрд░рдХрд▓реНрдк рдПрдХрд╛ рд▓рд╣рд╛рди рд╕рдВрдШрд╛рджреНрд╡рд╛рд░реЗ рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рдд рдЖрд╣реЗ рдЖрдгрд┐ рддреЗ рд╕рдХреНрд░рд┐рдпрдкрдгреЗ рдирд╡реАрди рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ рдЬреЛрдбрдд рдЖрд╣реЗрдд рдЖрдгрд┐ рджреЛрд╖ рдирд┐рд░рд╛рдХрд░рдг рдХрд░рдд рдЖрд╣реЗрдд. рдорд▓рд╛ рдЖрд╢рд╛ рдЖрд╣реЗ рдХреА рдПрдЦрд╛рджреНрдпрд╛ рджрд┐рд╡рд╢реА NJS рддреБрдореНрд╣рд╛рд▓рд╛ рдмрд╛рд╣реНрдп рдореЙрдбреНрдпреВрд▓ рдХрдиреЗрдХреНрдЯ рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрдИрд▓, рдЬреНрдпрд╛рдореБрд│реЗ Nginx рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬрд╡рд│рдЬрд╡рд│ рдЕрдорд░реНрдпрд╛рджрд┐рдд рд╣реЛрдИрд▓. рдкрдг рдПрдирдЬреАрдЖрдпрдПрдирдПрдХреНрд╕ рдкреНрд▓рд╕ рдЖрд╣реЗ рдЖрдгрд┐ рдмрд╣реБрдзрд╛ рдХреЛрдгрддреАрд╣реА рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ рдирд╕рддреАрд▓!
рд╕реНрддреНрд░реЛрдд: www.habr.com