рдпрд╕ рд▓реЗрдЦрдорд╛ рдо NJS рд╕рдВрдЧ рдореЗрд░реЛ рдЕрдиреБрднрд╡ рд╕рд╛рдЭрд╛ рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреБ, Nginx Inc рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдХрд╕рд┐рдд Nginx рдХреЛ рд▓рд╛рдЧрд┐ рдЬрд╛рднрд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреЛрднрд╛рд╖реЗ, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдпрд╕рдХреЛ рдореБрдЦреНрдп рдХреНрд╖рдорддрд╛рд╣рд░реВ рд╡рд░реНрдгрди рдЧрд░реНрджреИред NJS JavaScript рдХреЛ рдПрдХ рдЙрдкрд╕рдореВрд╣ рд╣реЛ рдЬрд╕рд▓реЗ рддрдкрд╛рдИрдВрд▓рд╛рдИ Nginx рдХреЛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫред рдкреНрд░рд╢реНрдирдорд╛
рдзреЗрд░реИ рд╕рдордп рдЕрдШрд┐тАж
рдореЗрд░реЛ рдЕрдиреНрддрд┐рдо рдХрд╛рдордорд╛, рдореИрд▓реЗ рдбрдХрд░-рдХрдореНрдкреЛрдЬ, рдбрд┐рдиреНрдб рд░ рдЕрдиреНрдп рд░рдорд╛рдЗрд▓реЛрд╣рд░реВрдХрд╛ рд╕рд╛рде рдзреЗрд░реИ рдореЛрдЯрд▓реА рд╕реАрдЖрдИ/рд╕реАрдбреА рдкрд╛рдЗрдкрд▓рд╛рдЗрдирд╣рд░реВрдХрд╛ рд╕рд╛рде рдЧрд┐рдЯрд▓реНрдпрд╛рдм рдкреНрд░рд╛рдкреНрдд рдЧрд░реЗрдВ, рдЬреБрди рдХрд╛рдирд┐рдХреЛ рд░реЗрд▓рд╣рд░реВрдорд╛ рд╣рд╕реНрддрд╛рдиреНрддрд░рдг рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛред рдЫрд╡рд┐рд╣рд░реВ рдЬреБрди рдкрд╣рд┐рд▓реЗ CI рдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХрд╛ рдерд┐рдП рддрд┐рдиреАрд╣рд░реВрдХреЛ рдореВрд▓ рд░реВрдкрдорд╛ рд╕рд╛рд░рд┐рдпреЛред рддрд┐рдиреАрд╣рд░реВрд▓реЗ рдареАрдХрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реЗ рдЬрдмрд╕рдореНрдо рд╣рд╛рдореНрд░реЛ gitlab IP рдкрд░рд┐рд╡рд░реНрддрди рднрдпреЛ рд░ CI рдХрджреНрджреВрдорд╛ рдкрд░рд┐рдгрдд рднрдпреЛред рд╕рдорд╕реНрдпрд╛ рдпреЛ рдерд┐рдпреЛ рдХрд┐ CI рдорд╛ рднрд╛рдЧ рд▓рд┐рдиреЗ рдбрдХрд░ рдЫрд╡рд┐рд╣рд░реВ рдордзреНрдпреЗ рдПрдЙрдЯрд╛ git рдерд┐рдпреЛ, рдЬрд╕рд▓реЗ ssh рдорд╛рд░реНрдлрдд рдкрд╛рдЗрдерди рдореЛрдбреНрдпреБрд▓рд╣рд░реВ рддрд╛рдиреНрдпреЛред ssh рдХреЛ рд▓рд╛рдЧреА рддрдкрд╛рдИрд▓рд╛рдИ рдирд┐рдЬреА рдХреБрдЮреНрдЬреА рдЪрд╛рд╣рд┐рдиреНрдЫ рд░... рдпреЛ рдЬреНрдЮрд╛рдд_рд╣реЛрд╕реНрдЯрдХреЛ рд╕рд╛рде рдЫрд╡рд┐рдорд╛ рдерд┐рдпреЛред рд░ рдХреБрдиреИ рдкрдирд┐ CI рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЖрдИрдкреА рд░ рдЬреНрдЮрд╛рдд_рд╣реЛрд╕реНрдЯрдорд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдмреАрдЪрдХреЛ рдореЗрд▓ рдирдорд┐рд▓реНрдиреЗ рдХрд╛рд░рдгрд▓реЗ рдХреБрдЮреНрдЬреА рдкреНрд░рдорд╛рдгреАрдХрд░рдг рддреНрд░реБрдЯрд┐рд╕рдБрдЧ рдЕрд╕рдлрд▓ рднрдпреЛред рдЕрд╡рд╕реНрдерд┐рдд рдбрдХрдлрд╛рдЗрд▓рд╣рд░реВрдмрд╛рдЯ рдирдпрд╛рдБ рдЫрд╡рд┐ рджреНрд░реБрдд рд░реВрдкрдорд╛ рднреЗрд▓рд╛ рдЧрд░рд┐рдпреЛ рд░ рд╡рд┐рдХрд▓реНрдк рдердкрд┐рдпреЛ StrictHostKeyChecking no
ред рддрд░ рдЦрд░рд╛рдм рд╕реНрд╡рд╛рдж рд░рд╣реНрдпреЛ рд░ libs рд▓рд╛рдИ рдирд┐рдЬреА PyPI рднрдгреНрдбрд╛рд░рдорд╛ рд╕рд╛рд░реНрдиреЗ рдЗрдЪреНрдЫрд╛ рдерд┐рдпреЛред рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдмреЛрдирд╕, рдирд┐рдЬреА PyPI рдорд╛ рд╕реНрд╡рд┐рдЪ рдЧрд░реЗрдкрдЫрд┐, рдПрдХ рд╕рд░рд▓ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рд╣рд░реВрдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╡рд░рдг рдерд┐рдпреЛредtxt
рдЫрдиреЛрдЯ рднрдЗрд╕рдХреЗрдХреЛ рдЫ, рд╣рдЬреБрд░рд╣рд░реБ!
рд╣рд╛рдореАрд▓реЗ рдХреНрд▓рд╛рдЙрдб рд░ рдХреБрдмрд░реНрдиреЗрдЯреНрд╕рдорд╛ рд╕рдмреИ рдХреБрд░рд╛ рдЪрд▓рд╛рдЙрдБрдЫреМрдВ, рд░ рдЕрдиреНрддрдорд╛ рд╣рд╛рдореА рдПрдЙрдЯрд╛ рд╕рд╛рдиреЛ рд╕реЗрд╡рд╛ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдереНрдпреМрдВ рдЬреБрди рдмрд╛рд╣реНрдп рднрдгреНрдбрд╛рд░рдг рднрдПрдХреЛ рд╕реНрдЯреЗрдЯрд▓реЗрд╕ рдХрдиреНрдЯреЗрдирд░ рдерд┐рдпреЛред рдард┐рдХ рдЫ, рд╣рд╛рдореАрд▓реЗ S3 рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрдХреЛрд▓реЗ, рдпрд╕рд▓рд╛рдИ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджрд┐рдЗрдпреЛред рд░, рдпрджрд┐ рд╕рдореНрднрд╡ рдЫ рднрдиреЗ, gitlab рдорд╛ рдкреНрд░рдорд╛рдгреАрдХрд░рдгрдХреЛ рд╕рд╛рде (рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рднрдПрдорд╛ рддрдкрд╛рдЗрдБ рдпрд╕рд▓рд╛рдИ рдЖрдлреИрдВ рдердкреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ)ред
рджреНрд░реБрдд рдЦреЛрдЬрд▓реЗ рдзреЗрд░реИ рдирддрд┐рдЬрд╛рд╣рд░реВ рд▓реНрдпрд╛рдпреЛ: s3pypi, pypicloud рд░ рд╢рд▓рдЬрдордХрд╛ рд▓рд╛рдЧрд┐ html рдлрд╛рдЗрд▓рд╣рд░реВрдХреЛ "рдореНрдпрд╛рдиреБрдЕрд▓" рд╕рд┐рд░реНрдЬрдирд╛рдХреЛ рд╕рд╛рде рд╡рд┐рдХрд▓реНрдкред рдЕрдиреНрддрд┐рдо рд╡рд┐рдХрд▓реНрдк рдЖрдлреИ рдЧрд╛рдпрдм рднрдпреЛред
s3pypi: рдпреЛ S3 рд╣реЛрд╕реНрдЯрд┐рдЩ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдХреЛ рд▓рд╛рдЧреА рдПрдХ cli рд╣реЛред рд╣рд╛рдореА рдлрд╛рдЗрд▓рд╣рд░реВ рдЕрдкрд▓реЛрдб рдЧрд░реНрдЫреМрдВ, html рдЙрддреНрдкрдиреНрди рдЧрд░реНрдЫреМрдВ рд░ рдЙрд╣реА рдмрд╛рд▓реНрдЯреАрдорд╛ рдЕрдкрд▓реЛрдб рдЧрд░реНрдЫреМрдВред рдШрд░рдХреЛ рдкреНрд░рдпреЛрдЧрдХреЛ рд▓рд╛рдЧрд┐ рдЙрдкрдпреБрдХреНрддред
pypicloud: рдпреЛ рдПрдХ рдЪрд╛рдЦрд▓рд╛рдЧреНрджреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЬрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдереНрдпреЛ, рддрд░ рдХрд╛рдЧрдЬрд╛рдд рдкрдвреЗрдкрдЫрд┐ рдо рдирд┐рд░рд╛рд╢ рднрдПрдБред рд░рд╛рдореНрд░реЛ рдХрд╛рдЧрдЬрд╛рддрд╣рд░реВ рд░ рддрдкрд╛рдИрдВрдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛рд╣рд░реВ рдЕрдиреБрд░реВрдк рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрдиреЗ рдХреНрд╖рдорддрд╛рдХреЛ рдмрд╛рд╡рдЬреБрдж, рд╡рд╛рд╕реНрддрд╡рдорд╛ рдпреЛ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд░ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрди рдЧрд╛рд╣реНрд░реЛ рднрдпреЛред рддрдкрд╛рдИрдВрдХреЛ рдХрд╛рд░реНрдпрд╣рд░реВ рдЕрдиреБрд░реВрдк рдХреЛрдб рд╕рдЪреНрдпрд╛рдЙрди, рддреНрдпрд╕ рд╕рдордпрдХреЛ рдЕрдиреБрдорд╛рди рдЕрдиреБрд╕рд╛рд░, 3-5 рджрд┐рди рд▓рд╛рдЧреНрдиреЗ рдерд┐рдпреЛред рд╕реЗрд╡рд╛рд▓рд╛рдИ рдбрд╛рдЯрд╛рдмреЗрд╕ рдкрдирд┐ рдЪрд╛рд╣рд┐рдиреНрдЫред рд╣рд╛рдореАрд▓реЗ рдЕрд░реБ рдХреЗрд╣рд┐ рдирднреЗрдЯреЗрдХреЛ рдЕрд╡рд╕реНрдерд╛рдорд╛ рдЫреЛрдбреНрдпреМрдВред
рдердк рдЧрд╣рд┐рд░реЛ рдЦреЛрдЬрд▓реЗ Nginx, ngx_aws_auth рдХреЛ рд▓рд╛рдЧрд┐ рдПрдХ рдореЛрдбреНрдпреБрд▓ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдпреЛред рдЙрд╕рдХреЛ рдкрд░реАрдХреНрд╖рдгрдХреЛ рдирддрд┐рдЬрд╛ рдмреНрд░рд╛рдЙрдЬрд░рдорд╛ XML рджреЗрдЦрд╛рдЗрдПрдХреЛ рдерд┐рдпреЛ, рдЬрд╕рд▓реЗ S3 рдмрд╛рд▓реНрдЯрд┐рдирдХреЛ рд╕рд╛рдордЧреНрд░реА рджреЗрдЦрд╛рдЙрдБрджрдЫред рдЦреЛрдЬрдХреЛ рд╕рдордпрдорд╛ рдЕрдиреНрддрд┐рдо рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рдПрдХ рд╡рд░реНрд╖ рдкрд╣рд┐рд▓реЗ рдерд┐рдпреЛред рднрдгреНрдбрд╛рд░ рдЫреЛрдбрд┐рдПрдХреЛ рджреЗрдЦрд┐рдиреНрдереНрдпреЛред
рд╕реНрд░реЛрддрдорд╛ рдЧрдПрд░ рдкрдвреЗрд░
рдпреЛ рдЙрджрд╛рд╣рд░рдгрд▓рд╛рдИ рдЖрдзрд╛рд░рдХреЛ рд░реВрдкрдорд╛ рд▓рд┐рдБрджреИ, рдПрдХ рдШрдгреНрдЯрд╛ рдкрдЫрд┐ рдореИрд▓реЗ рдореЗрд░реЛ рдмреНрд░рд╛рдЙрдЬрд░рдорд╛ ngx_aws_auth рдореЛрдбреНрдпреБрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрд╛ рдЙрд╣реА XML рджреЗрдЦреЗ, рддрд░ рд╕рдмреИ рдХреБрд░рд╛ рдкрд╣рд┐рд▓реЗ рдиреИ JS рдорд╛ рд▓реЗрдЦрд┐рдПрдХреЛ рдерд┐рдпреЛред
рдорд▓рд╛рдИ рд╕рд╛рдБрдЪреНрдЪреИ 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
рдПрдХ subquery рдмрдирд╛рдЗрдПрдХреЛ рдЫ location = /sub-query
, рддрд░реНрдХрдмрд╛рдЯ рдкреНрд░рд╛рдкреНрдд рд╡рд┐рдзрд┐ (рд╣рд╛рд▓рдХреЛ рдЙрджрд╛рд╣рд░рдг GET рдорд╛) рд╕рдВрдЧ (r)
, рдпрд╕ рдкреНрд░рдХрд╛рд░реНрдпрд▓рд╛рдИ рдХрд▓ рдЧрд░реНрджрд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдкрдорд╛ рдкрд╛рд░рд┐рдд рдЧрд░рд┐рдпреЛред subrequest рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдХрд╛рд░реНрдп рдорд╛ рдкреНрд░рд╢реЛрдзрди рдЧрд░рд┐рдиреЗрдЫ 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-рдЕрдиреБрд░реЛрдз рд░ 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>"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 рдХреЛ рд░реВрдкрдорд╛ рдкрдард╛рдЙрдиреБ рд╣реЛ, рдкрд╣рд┐рд▓реЗ рд╕рд╛рдордЧреНрд░реА-рдкреНрд░рдХрд╛рд░ рд╣реЗрдбрд░рд▓рд╛рдИ рдЯреЗрдХреНрд╕реНрдЯ/рдПрдЪрдЯреАрдПрдордПрд▓рд╕рдБрдЧ рдмрджрд▓реЗрд░ред
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="/ne/${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 рдирд┐рд░реНрджреЗрд╢рди рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░, рд╣рд╛рдореА рд╕реНрдХреНрд░рд┐рдкреНрдЯрдорд╛ рдПрдХ рдкреНрд░рдХрд╛рд░реНрдп рдХрд▓ рд╕рдорд╛рд╡реЗрд╢ subrequest рдорд╛ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдбрд╛рдЯрд╛ рдкреБрди: рдирд┐рд░реНрджреЗрд╢рд┐рдд рдЧрд░реНрдиреЗрдЫреМрдВред рд╕реНрдХреНрд░рд┐рдкреНрдЯрд▓реЗ Gitlab url рдорд╛ рдЕрд░реНрдХреЛ subrequest рдЧрд░реНрдиреЗрдЫ рд░ рдпрджрд┐ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдбрд╛рдЯрд╛ рд╕рд╣реА рд░реВрдкрдорд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ рднрдиреЗ, Gitlab рд▓реЗ рдХреЛрдб 200 рдлрд░реНрдХрд╛рдЙрдиреЗрдЫ рд░ рдкреНрдпрд╛рдХреЗрдЬрдХреЛ рдЕрдкрд▓реЛрдб/рдбрд╛рдЙрдирд▓реЛрдбрд▓рд╛рдИ рдЕрдиреБрдорддрд┐ рджрд┐рдЗрдиреЗрдЫред рдХрд┐рди рдПрдЙрдЯрд╛ рд╕рдмрдХреНрд╡реЗрд░реА рдкреНрд░рдпреЛрдЧ рдирдЧрд░реНрдиреЗ рд░ рддреБрд░реБрдиреНрддреИ Gitlab рдорд╛ рдбрд╛рдЯрд╛ рдкрдард╛рдЙрдиреЗ? рдХрд┐рдирднрдиреЗ рддреНрдпрд╕реЛ рднрдП рд╣рд╛рдореАрд▓реЗ 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 = рдЖрд╡рд╢реНрдпрдХ ('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 рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд▓рдЧрднрдЧ рдЕрд╕реАрдорд┐рдд рдмрдирд╛рдЙрдиреЗрдЫред рддрд░ рддреНрдпрд╣рд╛рдБ NGINX рдкреНрд▓рд╕ рдЫ рд░ рд╕рдореНрднрд╡рддрдГ рддреНрдпрд╣рд╛рдБ рдХреБрдиреИ рд╕реБрд╡рд┐рдзрд╛рд╣рд░реВ рд╣реБрдиреЗрдЫреИрдирдиреН!
рд╕реНрд░реЛрдд: www.habr.com