рд╕реНрдХрд╛рд▓рд╛ рдкрд░ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдХрд╛ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг

рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдорд╣рд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рдЕрдХреНрд╕рд░ рдЖрдк рдЕрддрд┐рд░рд┐рдХреНрдд рд░реВрдк рд╕реЗ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЪрд▓ рд░рд╣рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИред рд╕реЗрд╡рд╛рдУрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рддреЗрдЬреА рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдФрд░ рдбреЙрдХрд░ рдЖрдкрдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдЪреАрдЬреЗрдВ рдмрд╣реБрдд рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИрдВ, рдЬрдм рдмрд╣реБрдд рдЕрдзрд┐рдХ рдорд╛рдЗрдХреНрд░реЛрд╕реЗрд╡рд╛ рдФрд░ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВред

RIT ++ рдореЗрдВ рдпреВрд░реА рдмреИрдбрд▓рд┐рдВрдЯреНрд╕ рдиреЗ рдмрддрд╛рдпрд╛ рдХрд┐ рдХреИрд╕реЗ 2GIS рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕реЗрд╡рд╛рдУрдВ рдФрд░ рдкреВрд░реА рддрдХрдиреАрдХ рдЪрд┐рдбрд╝рд┐рдпрд╛рдШрд░ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣рд╛ рд╣реИред рдХрдЯ рдХреЗ рддрд╣рдд, рдЗрд╕ рд░рд┐рдкреЛрд░реНрдЯ рдХрд╛ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг, рд╕реНрдкреАрдХрд░ рдХреЗ рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рдкрд░реНрдпрд╡реЗрдХреНрд╖рдг рдХреЗ рддрд╣рдд рдкреВрд░рдХ рдФрд░ рдЕрджреНрдпрддрди рдХрд┐рдпрд╛ рдЧрдпрд╛: рдЖрдкрдиреЗ рдХреНрдпрд╛ рд╡рд┐рдХрд▓реНрдк рдЖрдЬрд╝рдорд╛рдП, рдЖрдк рдХреНрдпрд╛ рд▓реЗрдХрд░ рдЖрдП рд╣реИрдВ, рдЕрдм рдЖрдкрдХреЛ рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИред рдпрд╣ Docker, Testcontainers, рдФрд░ Scala рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рд╣реЛрдЧрд╛ред


рд╕реНрдкреАрдХрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ: рдпреВрд░реА рдмреИрдбрд▓рд┐рдВрдЯреНрд╕ (@ LMnet ) рдиреЗ 2011 рдореЗрдВ рдПрдХ рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдкрдирд╛ рдХрд░рд┐рдпрд░ рд╢реБрд░реВ рдХрд┐рдпрд╛, PHP, рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдЬрд╛рд╡рд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ред рдЕрдм рд╡рд╣ 2GIS рдореЗрдВ рд╕реНрдХрд╛рд▓рд╛ рдкрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВред

рдХреИрд╕рд┐рдиреЛ


2 рдЬреАрдЖрдИрдПрд╕ 20 рд╡рд░реНрд╖реЛрдВ рд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╢рд╣рд░ рдХреЗ рдирдХреНрд╢реЗ рдФрд░ рдХрдВрдкрдиреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкреНрд░рджрд╛рди рдХрд░ рд░рд╣рд╛ рд╣реИ, рдФрд░ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд░реВрд╕ рдХреЗ рдЕрд╕реАрдорд┐рдд рдирдХреНрд╢реЗ рдХреЗ рд╕рд╛рде рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИ ред рдореИрдВрдиреЗ рдЖрдкрдХреЛ рдХреИрд╕реАрдиреЛ рдЯреАрдо рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рджреМрд░рд╛рди рдкреНрд░рд╛рдкреНрдд рдЕрдиреБрднрд╡ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдпрд╛ред рдпрд╣ рдЯреАрдо рддреАрди рдореБрдЦреНрдп рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ:

  • рд╡рд┐рдЬреНрдЮрд╛рдкрди - рдХреМрди рд╕рд╛ рд╡рд┐рдЬреНрдЮрд╛рдкрдирджрд╛рддрд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдирд╛ рд╣реИ, рдХреМрди рд╕рд╛ рдЫрд┐рдкрд╛рдирд╛ рд╣реИ, рдХрд┐рд╕рдХреЛ рдЙрдард╛рдирд╛ рд╣реИ рдФрд░ рдХреИрд╕реЗ рд░реЗрдЯрд┐рдВрдЧ рдХрдо рдХрд░рдиреА рд╣реИред

  • рдмрд┐рдЧрдбрд╛рдЯрд╛ рд╡рд┐рдЬреНрдЮрд╛рдкрди рдФрд░ рдЗрд╕рдХреЗ рдирд┐рдЬреАрдХрд░рдг рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдПрдирд╛рд▓рд┐рдЯрд┐рдХреНрд╕ рдФрд░ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдмрд┐рд▓реНрдбрд┐рдВрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред
  • рдХреНрд░реЙрд▓рд░ рдПрдХ рдРрд╕рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣реИ рдЬреЛ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рд╕рдВрдЧрдардиреЛрдВ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИред

рдпреЗ рддреАрди рдХреНрд╖реЗрддреНрд░ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рд╣реИрдВ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ, рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЙрдк-рдореБрдЦреМрдЯреЗ рд╣реИрдВред рд╡рд░реНрддрдорд╛рди рдореЗрдВ, рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ 25 рд╕реЗ рдЕрдзрд┐рдХ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╣рдорд╛рд░рд╛ рдХреЛрдб рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рдо рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреЛрд╕реНрдЯрдЧреНрд░реЗрд╕реАрдХреНрдпреВ, рдХреИрд╕реЗрдВрдбреНрд░рд╛ рдФрд░ рдХрд╛рдлреНрдХрд╛ред рд╣рдо Hadoop рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╕реНрдкрд╛рд░реНрдХ рдореЗрдВ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдбреЗрдЯрд╛ рд╕рд╛рдЗрдВрд╕ рдЯреАрдо рджреНрд╡рд╛рд░рд╛ рджреА рдЧрдИ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдирддреАрдЬрддрди, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕реЗрд╡рд╛рдПрдВ рдФрд░ рдорд╛рдЗрдХреНрд░реЛрд╕реЙрд░реНрдлрд╝рд┐рд╕ рд╣реИрдВ, рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВ, рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЗрди рд╕рднреА рдХреЛ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдмреЗрд╢рдХ, рд╣рдо рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рднрд▓реЗ рд╣реА рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд╣рд░реЗ рд╣реЛрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдШрдЯрдХреЛрдВ рдпрд╛ microservices рдХреЗ рдПрдХреАрдХрд░рдг рдЪрд░рдг рдХреЗ рджреМрд░рд╛рди рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╣реИрдВред

рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг


рдХрд╕реАрдиреЛ рдЯреАрдо рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдХрд╕рд┐рдд рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдЕрдкрдиреА рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЧрд┐рдЯрд▓реИрдм рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рднрдВрдбрд╛рд░ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред рдпрд╣ рд▓реЗрдЦ рд▓реЙрдХ рдХрд┐рдП рдЧрдП рдЖрд╢реНрд░рд┐рддреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдРрд╕реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА (microservice) рдХреЗ рднреАрддрд░ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдЧрд╛, рдЬреЛ рд╕реНрд╡рдпрдВ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд╣реИред рдХреНрдпреВрдП рдЯреАрдо рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдХреА рдмрд╛рддрдЪреАрдд рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реА рд╣реИ, рдФрд░ рдореИрдВ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдирд╣реАрдВ рдЫреВрдКрдВрдЧрд╛ред

рдЬрдм рдореИрдВ рдкрд╣рд▓реА рдмрд╛рд░ рдЯреАрдо рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реБрдЖ, 2016 рдХреЗ рдЕрдВрдд рдореЗрдВ, рд▓рдЧрднрдЧ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдпреЛрдЬрдирд╛ рдереА:


  1. рдбреЗрд╡рд▓рдкрд░ рдЬреАрдЖрдИрдЯреА рдореЗрдВ рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдорд╛рдЗрдХреНрд░реЛрд╕реЗрд╡рд╛ рдХреЛрдб рдЯреАрдорд╕рд┐рдЯреА рдореЗрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддрд╛ рд╣реИред рдЯреАрдорд╕рд┐рдЯреА рдХреЛрдб рдмрдирд╛рдирд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдирд╛ рд╢реБрд░реВ рдХрд░рддреА рд╣реИред
  2. TeamCity, рд╢реЗрдл рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ (рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди) рд▓реЗрддрд╛ рд╣реИ (Ansible рдХреЗ рд╕рдорд╛рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкреНрд░рдмрдВрдзрди рдкреНрд░рдгрд╛рд▓реА, рдЬреЛ рдХреЗрд╡рд▓ рд░реВрдмреА рдореЗрдВ рд▓рд┐рдЦреА рдЧрдИ рд╣реИ)ред рд╢реЗрдл рднреА рддреИрдирд╛рддреА рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред рдЬрдм рдореЗрд░реЗ рдкрд╛рд╕ 100 рдорд╢реАрдиреЗрдВ рд╣реЛрддреА рд╣реИрдВ, рддреЛ рдореИрдВ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рдирд╣реАрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдПрд╕рдПрд╕рдПрдЪ рдкрд░ рдореБрдЭреЗ рдЬреЛ рдХреБрдЫ рднреА рдЪрд╛рд╣рд┐рдП рдЙрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдмрд╛рд╡рд░реНрдЪреА рдореБрдЭреЗ рдЗрд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
  3. рдЯреАрдорд╕рд┐рдЯреА рдЬрд╛рд░ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рддрд╛ рд╣реИ (рдЬрдм рд╕реЗ рд╣рдо рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд▓рд╛рдХреГрддрд┐ рд╣рдо рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рд╡рд╣ рдЬрд╛рд░ рд╣реИ), рдлрд┐рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЗрд╕реЗ рд╕реАрдЖрдИ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХреЛ рд╡рд╣рд╛рдВ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреБрдЫ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рднреА рд╣реИрдВред рдЖрд░реЗрдЦ рдореЗрдВ, рдПрдХ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рдВрднрд╡ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрдИ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рдФрд░ рд╢реЗрдл рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рдорд╛рд░рд╛ рдЖрд╡реЗрджрди рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред
  4. рдЗрд╕рдХреЗ рдмрд╛рдж, рдЯреАрдорд╕рд┐рдЯреА рдиреЗ рдПрд╕рдмреАрдЯреА рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ (рдпрд╣ рд╣рдорд╛рд░реА рдмрд┐рд▓реНрдб рд╕рд┐рд╕реНрдЯрдо рд╣реИ, рдЬрд╣рд╛рдВ рд╕рдВрдХрд▓рди рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ) рдФрд░ рдкрд░реАрдХреНрд╖рдг рдЦреБрдж рдЪрд▓рд╛рддреЗ рд╣реИрдВред рд╡реЗ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рд╕рдорд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдЗрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ: http рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрддреЗ рдкрд░ рдЬрд╛рдПрдВ, рдХреБрдЫ рд╡рд┐рдзрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рджреЗрддрд╛ рд╣реИ; рдпрд╛ рдХреБрдЫ рддреИрдпрд╛рд░реА рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЬрд░реВрд░рдд рд╣реИ рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ рд╣реИред

рдРрд╕реА рдпреЛрдЬрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЬрдм рд╕рдм рдХреБрдЫ рд╕реЗрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдирд╛ рдЖрд╕рд╛рди рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдкреНрд▓рд╕рд╕ рд╡рд╣реАрдВ рдЦрддреНрдо рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред

рдФрд░ рдЕрдВрдд рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред CI рдкрд░реНрдпрд╛рд╡рд░рдг рд╣рдореЗрд╢рд╛ рдЪрд╛рд▓реВ рд░рд╣рддрд╛ рд╣реИ , рдФрд░ рдпрд╣ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЕрддрд┐рд░рд┐рдХреНрдд рдмрд░реНрдмрд╛рджреА рд╣реИред рдЪреВрдВрдХрд┐ рд╢реЗрдл рдПрдХ рд╕реНрдерд┐рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдорд╢реАрди рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рдЬрд╣рд╛рдВ рд╕рднреА рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХреА рдЬрд╛рдПрдВрдЧреА, рдЬрд╣рд╛рдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рддреИрдирд╛рдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред рдРрд╕реА рдорд╢реАрди рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░реЗрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╕рдордп-рд╕рдордп рдкрд░ рдЪрд▓рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдорд╢реАрди рдХреЛ рд╣рд░ рд╕рдордп рддреИрдпрд╛рд░ рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реАрдЖрдИ рд╡рд╛рддрд╛рд╡рд░рдг рд╕рднреА рдирд┐рд░реНрднрд░рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╢рд╛рдорд┐рд▓ рд╣реИред

рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рджреЛ рд╢рд╛рдЦрд╛рдУрдВ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ ред рдпрд╣ рдкрд┐рдЫрд▓реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ: рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд╛рддрд╛рд╡рд░рдг рд╣реИ, рд╣рдо рдмрд╕ рдЙрдиреНрд╣реЗрдВ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдирд╣реАрдВ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред

рд╕реНрдЯрд╛рд░реНрдЯ, рд╕реНрдЯреЙрдк рдФрд░ рд░реАрд╕реНрдЯрд╛рд░реНрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ ред рдореИрдВ рд╕рдордЭрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ: рд╣рдорд╛рд░реЗ рд╕рднреА рдЕрдиреБрдкреНрд░рдпреЛрдЧ рддрдерд╛рдХрдерд┐рдд рд╢рдЯрдбрд╛рдЙрди рд╢рдЯрдбрд╛рдЙрди рдХреЗ рддрд░реНрдХ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН, рдЬрдм рд╣рдо рд╕рд┐рдЧрд╛рд░рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмреАрдЪ рдореЗрдВ рдирд╣реАрдВ рд░реЛрдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рд╕рдВрдХреЗрдд рдХреЛ рд░реЛрдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдХреБрдЫ рддрд░реНрдХ рдЪрд╛рд▓реВ рд╣реЛрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрди HTTP рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ "рдЙрдбрд╝рд╛рди рдореЗрдВ" рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╛ рдпрджрд┐ рд╣рдо рдХрд╛рдлреНрдХрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╕рднреА рдмрдВрджреЛрдВ рдХреЛ рдкреНрд░рддрд┐рдмрджреНрдз рдХрд░рддреЗ рд╣реИрдВ - рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рд╣рдо рдХреБрдЫ рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдо рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХрд╛рдо рдкреВрд░рд╛ рдХрд░ рд╕рдХреЗрдВ, рдФрд░ рдлрд┐рд░, рдЬрдм рд╕рдм рдХреБрдЫ рд╣реЛ рдЬрд╛рдП, рддреЛ рдмрдВрдж рдХрд░ рджреЗрдВред

рдпрд╣ рддрд░реНрдХ рд╣рдореЗрд╢рд╛ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЖрдк рдЗрд╕реЗ рдХреЗрд╡рд▓ рдЗрд╕ рдпреЛрдЬрдирд╛ рдХреЗ рд╕рд╛рде рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬреАрд╡рди рдЪрдХреНрд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдЯреАрдорд╕рд┐рдЯреА рдиреЗ рд╢реЗрдл рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд┐рд╕реА рддрд░рд╣ рдХреБрдЫ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдкрд░реАрдХреНрд╖рдг рдПрдХ рдЕрд▓рдЧ рд╕реНрддрд░ рдкрд░ рд╣реИрдВ рдФрд░ рдпрд╣ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдЖрд╡реЗрджрди рдХреИрд╕реЗ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЕрдЧрд▓рд╛ рдЛрдг рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реИ ред рдпрд╣реА рд╣реИ, рдХрдИ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВ, рдЙрдирдХреЗ рдкрд╛рд╕ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рд╕реНрдерд╛рдиреАрдп рдорд╢реАрди рдкрд░ рдЙрдард╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдкрд╛рд╕ рд╕реНрд╡рдпрдВ рдХреА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рднреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдХрдИ рдорд╛рди рд╣реИрдВред рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╕реНрд╡рдпрдВ рдПрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдорд┐рд▓рд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдорд╛рди рднреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рдЗрддрдирд╛ рдбрд░рд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕реЗ "рддреАрди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдХреЙрдиреНрдлрд┐рдЧреНрд╕ рдХреЛ рдЬрд╛рдирд╛ рдФрд░ рдареАрдХ рдХрд░рдирд╛", рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирдП рдХрд░реНрдордЪрд╛рд░рд┐рдпреЛрдВ рдХреЛ рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рдШрдВрдЯреЛрдВ рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВред

рдЧрд┐рдЯрд▓рдм рд╕реАрдЖрдИ + рдбреЙрдХрдЯрд░


рд╕рдордп рдХреЗ рд╕рд╛рде, рдпрд╣ рдпреЛрдЬрдирд╛ рджреВрд╕рд░реЗ рдореЗрдВ рдмрджрд▓ рдЧрдИ рд╣реИ: рдЧрд┐рдЯрд▓реИрдм рд╕реАрдЖрдИ рдФрд░ рдбреЛрдХрд░ ред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рдирд╣реАрдВ рд╣реБрдЖ рдХреНрдпреЛрдВрдХрд┐ рдкрд┐рдЫрд▓реА рдпреЛрдЬрдирд╛ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рдереА, рдмрд▓реНрдХрд┐ рдЗрд╕рд▓рд┐рдП рдХрд┐ рдХрдВрдкрдиреА рдиреЗ рдкреНрд░рд╢рд╛рд╕рдирд┐рдХ рд╕рдВрдЧрдарди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдереЛрдбрд╝рд╛ рдмрджрд▓рд╛рд╡ рдХрд┐рдпрд╛ред

рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ, рдкреНрд░рддреНрдпреЗрдХ рдЯреАрдо, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрдирдореЗрдВ рд╕реЗ рдмрд╣реБрдд рдХреБрдЫ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рдереЗ рдпрд╛ рд╣рдо рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рдереЗ, рдФрд░ рдЗрд╕рдХреЗ рдХрд╛рдо рдХреЛ рддреИрдирд╛рдд рдХрд░ рд╕рдХрддреЗ рдереЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЯреАрдорд╕рд┐рдЯреА, рд╢реЗрдл рдФрд░ рдЕрдиреНрдп рдЯреАрдореЗрдВ рдЬреЗрдирдХрд┐рдВрд╕ рдпрд╛ рдПрдВрд╕рд┐рдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреА рдереАрдВред

рдЕрдм рд╣рдо рд╕реНрдерд╛рдиреАрдп рдХреНрд▓рд╛рдЙрдб рдФрд░ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреА рдУрд░ рдмрдврд╝ рд░рд╣реЗ рд╣реИрдВ, рдФрд░ рдПрдХ рдЕрд▓рдЧ рдЯреАрдо рд╣реИ рдЬреЛ рдпрд╣ рд╕рдм GitLab CI рдФрд░ Kubernetes рджреЛрдиреЛрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддреА рд╣реИред рдЕрдиреНрдп рдЯреАрдореЗрдВ рдЗрд╕реЗ рд╕реЗрд╡рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИрдВред рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдпрд╣ рд╕рдм рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдордиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдпреЛрдЬрдирд╛ рдХреЛ рддреИрдирд╛рдд рдХрд┐рдпрд╛:


  1. TeamCity рдХреЗ рдмрдЬрд╛рдп, Gitlab CI рдХрд╛ рдЕрдм рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  2. GitLab CI рдПрдХ рдбреЙрдХ рдЗрдореЗрдЬ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореЗрдВ рднреЗрдЬрддрд╛ рд╣реИред рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЕрдм рд╕реАрдзреЗ рднрдВрдбрд╛рд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╢реЗрдл рдореЗрдВ рдЕрд▓рдЧ рд╕реЗ рдирд╣реАрдВ, рдЗрд╕рд▓рд┐рдП рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рддреГрддреАрдп-рдкрдХреНрд╖ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
  3. рдирд┐рд░реНрднрд░рддрд╛рдПрдБ рдЕрдЧреНрд░рд┐рдо рд░реВрдк рд╕реЗ рдЙрдард╛рдИ рдЬрд╛рддреА рд╣реИрдВ, рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдореЗрдВ рднреАред
  4. рдлрд┐рд░ GitLab CI рдиреЗ SBT рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдФрд░ рдПрдХ рдЕрд▓рдЧ рдЪрд░рдг рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ред

рд╕рдм рдХреБрдЫ рдкрд┐рдЫрд▓реА рдпреЛрдЬрдирд╛ рдХреЗ рд╕рдорд╛рди рд╣реИ рдФрд░ рдореВрд▓ рд░реВрдк рд╕реЗ рдЗрд╕рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИ, рдЕрд░реНрдерд╛рддреН, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖ рдмрд┐рд▓реНрдХреБрд▓ рд╕рдорд╛рди рд╣реЛрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдбреЙрдХрд░ рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИред

рдбреЙрдХрдЯрд░ рдХреЗ рд╕рд╛рде, рдЖрдк рдЕрд▓рдЧ-рдЕрд▓рдЧ рдордЬрд╝реЗрджрд╛рд░ рдЪреАрдЬреЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдбреЙрдХ-рдХрдВрдкреЛрдЬрд╝ рд╣реИред

рдбреЛрдХрд░-рд▓рд┐рдЦреЗрдВ


рдпрд╣ рдбреЙрдХрд░ рдкрд░ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ "рдУрд╡рд░рд▓реЗ" рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рдЗрдХрд╛рдИ рдХреЗ рд░реВрдк рдореЗрдВ рдХрдИ рдбреЙрдХрдЯрд░-рдЪрд┐рддреНрд░ рдЪрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рдЬрд╣рд╛рдВ рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬрд╝ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рд╣реИ рдХрд╛рдлреНрдХрд╛ред рдЙрд╕реЗ рджреМрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд┐рдбрд╝рд┐рдпрд╛рдШрд░ рдХреАрдкрд░ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдпрджрд┐ рдЖрдк рдмрд┐рдирд╛ рдХреИрд╕рд░-рд░рдЪрдирд╛ рдХреЗ рдХрд╛рдлреНрдХрд╛ рдФрд░ рдЬрд╝реВрдХреЗрдкрд░ рдХреЛ рдЙрдард╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдбреЙрдХ рдореЗрдВ рдЬрд╝реВрдХреЗрд░ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдард╛рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ, рдЕрд▓рдЧ-рдЕрд▓рдЧ - рдХрд╛рдлреНрдХрд╛, рдФрд░ рдЗрди рджреЛ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рд▓рдЧрд╛рддрд╛рд░ рдмрдирд╛рдП рд░рдЦреЗрдВред рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬрд╝ рдЖрдкрдХреЛ рджреЛрдиреЛрдВ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рдПрдХ рдбреЙрдХ-рдХрдВрдкреЛрдЬрд╝.рдЖрдИрдПрдордПрд▓ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рдХрд╛рдлреНрдХрд╛ рдФрд░ рдЬрд╝реВрдХрд┐рдкрд░ docker-compose run Kafka рдЙрдард╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░рд▓ рдбреЙрдХ docker-compose run Kafka рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

рдЖрдк рдбреЙрдХрдЯрд░-рдХрдореНрдкреЛрдЬрд╝ рдкрд░ рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦреЗрдЧрд╛ред


  1. рдлрд┐рд░, GitLab рдореЗрдВ рд╕рдм рдХреБрдЫ рдзрдХреНрдХрд╛ред
  2. GitLab CI рдиреЗ рдбреЙрдХрдЯрд░-рдХрдореНрдкреЛрдЬрд╝ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ред
  3. рдбреЙрдХрдЯрд░-рдХрдореНрдкреЛрдЬрд╝ рдореЗрдВ, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдКрдкрд░ рдЬрд╛рддрд╛ рд╣реИ, рд╕рднреА рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рдФрд░ рдПрд╕рдмреАрдЯреА рдКрдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдПрд╕рдмреАрдЯреА рдЗрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддрд╛ рд╣реИ - рд╕рдм рдХреБрдЫ рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬ рдХреЗ рдЕрдВрджрд░ рд╣реЛрддрд╛ рд╣реИред

рдЗрд╕ рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдПрдХ рдЕрд▓рдЧ рд╡рд╛рддрд╛рд╡рд░рдг рдФрд░ рдирд┐рд░реНрднрд░рддрд╛ рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдм рдХреБрдЫ рд╕реАрдзреЗ рдЧрд┐рдЯрд▓рдм рд╕реАрдЖрдИ рдзрд╛рд╡рдХ рдХреЗ рдкрд╛рд╕ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдбреЙрдХрдЯрд░ рдФрд░ рдбреЙрдХ-рдХрдВрдкреЛрдЬ рдХреЛ рдмрд╕ рд╣реЛрдирд╛ рд╣реИред рд╢реБрд░реБрдЖрдд рдХреЗ рджреМрд░рд╛рди, рд╡рд╣ рдЖрд╡рд╢реНрдпрдХ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рдкрдВрдк рдХрд░реЗрдЧрд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЪрд▓рд╛рдПрдЧрд╛ред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рд╢рд╛рдЦрд╛рдУрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдм рдХреБрдЫ рдзрд╛рд╡рдХ рдкрд░ рд╣реЛрддрд╛ рд╣реИред

рдЕрдм рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ , рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЕрднреА рднреА рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рд╕рдордиреНрд╡рдп рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЕрдм, рдЬрдм рд╣рдо рд╕реНрдерд╛рдиреАрдп рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рд╕рдм рдХреБрдЫ рд╕реНрдерд╛рдиреАрдп рдорд╢реАрди рдкрд░ рдбрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рдм рдХреБрдЫ docker-compose.yml рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЖрдкрдХреЛ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ - рдпрд╣ docker-compose.yml рдФрд░ рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╣реИред

рдХреЗ рд░реВрдк рдореЗрдВ minuses рдХреЗ рд▓рд┐рдП, рдЕрднреА рднреА рдкрд░реАрдХреНрд╖рдг рд╢реБрд░реВ рдХрд░рдирд╛, рд░реЛрдХрдирд╛ рдФрд░ рдкреБрдирдГ рдЖрд░рдВрдн рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ , рдХреНрдпреЛрдВрдХрд┐ рдПрд╕рдмреАрдЯреА рд╕реЗ, рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ, рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬреАрд╡рди рдЪрдХреНрд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ docker-compose рджреНрд╡рд╛рд░рд╛ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ SBT рдЪрд▓рд╛рддрд╛ рд╣реИ рдФрд░ SBT рдХреЗ рдЕрдВрджрд░ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЖрд╡реЗрджрди рдХрд╛ рдХреЛрдИ рдкреВрд░реНрдг рдЬреАрд╡рди рдЪрдХреНрд░ рдкреНрд░рдмрдВрдзрди рдирд╣реАрдВ рд╣реИред рд▓реЙрдиреНрдЪ рдХреЗ рд╕рд╛рде рдореБрд╢реНрдХрд┐рд▓реЗрдВ рднреА рд╣реИрдВ, рдЬрд┐рдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рдФрд░ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

docker- рд░рдЪрдирд╛ реи


Docker-compose 2 рдХреЗ рджрд┐рдиреЛрдВ рдореЗрдВ, docker-compose.yml рдлрд╛рдЗрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:

 version: '2.1' services: web: build: . depends_on: db: condition: service_healthy redis: condition: service_started redis: image: redis db: image: db healthcheck: test: "some test here" 

рдпрд╣рд╛рдВ рд╕реЗрд╡рд╛рдПрдВ рдкрдВрдЬреАрдХреГрдд рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рд╣рдо рдЗрд╕ рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрдпрд╛ рдмрдврд╝рд╛рдПрдВрдЧреЗред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВрдиреЗ рд╕рд┐рд░реНрдл рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬрд╝ рдбреЙрдХреНрдпреВрдореЗрдВрдЯреЗрд╢рди рд╕реЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдпрд╛ рд╣реИред рддреАрди рд╕реЗрд╡рд╛рдПрдВ рд╣реИрдВ: рд╡реЗрдм, рд░реЗрдбрд┐рд╕ рдФрд░ рдбреАрдмреА (рдбреЗрдЯрд╛рдмреЗрд╕)ред

рд╡реЗрдм рд╣рдорд╛рд░рд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ, рдФрд░ рд░реЗрдбрд┐рд╕ рдФрд░ рдбреАрдмреА рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреА рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВред

рд╡реЗрдм рдмреНрд▓реЙрдХ рдореЗрдВ рдПрдХ рдЖрдЗрдЯрдо рд╣реИ, рдЬрд┐рд╕реЗ depends_on рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреБрдЫ рдЕрдиреНрдп рдХрдВрдЯреЗрдирд░реЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдиреАрдЪреЗ рд╡рд░реНрдгрд┐рдд рд╣реИ рдЬрд┐рд╕ рдкрд░: рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рд░реЗрдбрд┐рд╕ рд╕реЗред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ condition рд╣реИред рд░реЗрдбрд┐рд╕ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕реЗрд╡рд╛_рд╕реНрдЯрд╛рд░реНрдЯ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЬрдм рддрдХ рд░реЗрдбрд┐рд╕ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддрдм рддрдХ рдХрдВрдЯреЗрдирд░ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред

рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рдЗрд╕рдХреА рд╕реНрдерд┐рддрд┐ service_healthy , рдФрд░ рд╕реНрд╡рд╛рд╕реНрдереНрдп рдЬрд╛рдВрдЪ рдиреАрдЪреЗ рд╡рд░реНрдгрд┐рдд рд╣реИред рдпрд╣реА рд╣реИ, рд╣рдореЗрдВ рди рдХреЗрд╡рд▓ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реНрд╡рд╛рд╕реНрдереНрдп рдкрд░реАрдХреНрд╖рдг рдХреЛ рднреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдХреЛрдИ рднреА рдХрд╕реНрдЯрдо рддрд░реНрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо PostgreSQL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ PostGIS рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдордп рдЪрд╛рд╣рд┐рдПред рдЬрдм рд╣рдо рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рддреБрд░рдВрдд рдкреЛрд╕реНрдЯрдЧрд┐рд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рд╣рдореЗрдВ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЕрднреА SELECT PostGIS_Version(); рд▓рд┐рдП SELECT PostGIS_Version(); рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ SELECT PostGIS_Version(); ред рдЬрдм рддрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрдм рддрдХ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдореЗрдВ рдПрд░рд░ рдЖ рдЬрд╛рдПрдЧреА рдФрд░ рдЬрдм рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рддреЛ рд╡рд╣ рд╡рд░реНрдЬрди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдЧрд╛ред рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рддрд╛рд░реНрдХрд┐рдХ рд╣реИ - рдкрд╣рд▓реЗ рд╣рдо рд╕рднреА рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рдмрдврд╝рд╛рдПрдВрдЧреЗ, рдФрд░ рдлрд┐рд░ рдЖрд╡реЗрджрди рдХрд░реЗрдВрдЧреЗ ред

docker- рд░рдЪрдирд╛ рей


рдЬрдм рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬ 3 рдмрд╛рд╣рд░ рдЖрдпрд╛, рддреЛ рд╣рдордиреЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред

рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ, рдПрдХ рдЖрдЗрдЯрдо depend_on рддрд░реНрдХ рдХреЛ рдмрджрд▓рдиреЗ рдкрд░ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ред рдбреЙрдХ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рддрдп рдХрд┐рдпрд╛ рдХрд┐ рдирд┐рд░реНрднрд░рддрд╛ рдЧреНрд░рд╛рдл рдХрд╛ рд╡рд░реНрдгрди рдкрд░реНрдпрд╛рдкреНрдд рдерд╛ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рдЖрдк docker-compose run web рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдФрд░ рдбреАрдмреА рдЬрд┐рд╕ рдкрд░ рд╡рд╣ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рджреЛрдиреЛрдВ рдПрдХ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрдВрдЧреЗред



рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЕрдЧрд▓рд╛ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХрд╣рддрд╛ рд╣реИ рдХрд┐ depend_on рдЕрдм рдХреЛрдИ рд╢рд░реНрдд рдирд╣реАрдВ рд╣реИред

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрджрд┐ рдЖрдк рдЕрднреА рднреА рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд╕рдм рдХреБрдЫ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рд▓реЗрдирд╛ рд╣реЛрдЧрд╛ред

рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдЖрджреЗрд╢ рдкреГрд╖реНрда рдХрдИ рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИ рдХрд┐ рд╡реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ-for-it.sh ред

рдЕрдм docker-compose.yml рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рджрд┐рдЦрддрд╛ рд╣реИ:

 version: '3' services: web: build: . depends_on: [ db, redis ] redis: image: redis command: [ "./wait-for-it.sh", ... ] db: image: redis command: [ "./wait-for-db.sh", ... ] 

depends_on рд╕рд┐рд░реНрдл рдПрдХ рд╕рд░рдгреА рд╣реИ, рдХреЛрдИ рд╢рд░реНрддреЗрдВ рдирд╣реАрдВ рд╣реИрдВред

рд╣рдорд╛рд░реА рдирд┐рд░реНрднрд░рддрд╛ рдореЗрдВ, рд╣рдо рдХрдорд╛рдВрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН, docker-compose рдореЗрдВ рдЖрдк рдПрдХ рдХрдорд╛рдВрдб рдЕрдЯреИрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред

рд╡рд╣рд╛рдВ рд╣рдореЗрдВ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП- for-it.sh, рдФрд░ рдХреБрдЫ рдФрд░ред рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рддреАрди рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдмрдЬрд╛рдп, рд╣рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╣рдореЗрдВ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдореВрд▓ рдЖрджреЗрд╢ рдЬреЛ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рддрд╛ рд╣реИред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдбреЙрдХ рдлрд╝рд╛рдЗрд▓ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд╣рд╛рдВ рд╕реЗ рд░реЗрдбрд┐рд╕ рдХреЗ рд▓рд┐рдП рдХрдорд╛рдВрдб рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдкреЗрд╕реНрдЯ рдХрд░реЗрдВ, рд╡рд╣реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рдмрд╣реБрдд рдмрдбрд╝рд╛ рдЛрдг рдпрд╣ рд╣реИ рдХрд┐ рдЕрдореВрд░реНрдд рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИ - рдореИрдВ рдпрд╣ рдирд╣реАрдВ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддрд╛ рдХрд┐ рдХреМрди рд╕рд╛ рдХрдорд╛рдВрдб рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рд▓реЙрдиреНрдЪ рдХрд░рддрд╛ рд╣реИред рдпреЗ рдЖрджреЗрд╢ рдиреИрд╢рдирд▓, рдХрд╛рдлреА рдЬрдЯрд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛, рдореИрдВ рд╕рд┐рд░реНрдл docker run рджрд░реНрдЬ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдпрд╣ рд╣реИред

рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЛ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рд╕реЗрд╡рд╛рдПрдВ рдереАрдВ рдЬреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИрдВред

рдбреЙрдХрдЯрд░-рдХрдореНрдкреЛрдЬ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ


рддрдм рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ "рд╕рд╛рдЗрдХрд┐рд▓ рдирд┐рд░реНрдорд╛рдг " рдХрд╛ рд╕рдордп рдЖ рдЧрдпрд╛ рдерд╛, рдФрд░ рдореЗрд░реЗ рдкрд╛рд╕ docker-compose-run.sh рдерд╛:

 version: '3' services: postgres: ... my_service: depends_on: [ postgres ] ... sbt: depends_on: [ my_service ] ... 

рдореИрдВ рдПрдХ рдЕрд░реНрдз-рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реВрдВ: docker-compose.yml рдореЗрдВ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рд╣реИ, my_service рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ, рдЬреЛ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдФрд░ SBT рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЬреЛ рдореЗрд░реА рд╕реЗрд╡рд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдбреЙрдХ docker run рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ docker-compose-run.sh рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛рддрд╛ рд╣реВрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рд╕рдмрд╕реЗ рдЧрд╣рд░реА рдирд┐рд░реНрднрд░рддрд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рд╣реИред рд╕реНрдХреНрд░рд┐рдкреНрдЯ "рдбреЗрдореЙрди" рдореЛрдб рдореЗрдВ рдирд┐рд░реНрднрд░рддрд╛ рд╢реБрд░реВ рдХрд░рддреА рд╣реИ, рдЕрд░реНрдерд╛рдд, рдпрд╣ рдЯрд░реНрдорд┐рдирд▓ рдХреЛ рдмреНрд▓реЙрдХ рдирд╣реАрдВ рдХрд░рддреА рд╣реИ:

 docker-compose up -d postgres 

рдлрд┐рд░ рдореИрдВ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рдерд╛ рдХрд┐ рд╣рд╛рд▓рдд рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред рдпрд╣ рд▓рдЧрднрдЧ рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд╛- for-it.sh, рдХреЗрд╡рд▓, рдЗрддрдирд╛ рдмреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрдирд┐рд╡рд╛рд░реНрдп рд╢реИрд▓реА рдореЗрдВред рдЬрдмрдХрд┐ PostGIS рдЖрд░рдВрдн рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЯрд░реНрдорд┐рдирд▓ рдЕрд╡рд░реБрджреНрдз рд╣реИ, рдЕрд░реНрдерд╛рдд, рдкреНрд░реЛрдЧреНрд░рд╛рдо рднреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдЧрд░ рдпрд╣ рдЗрдВрддрдЬрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд╛рдо рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВред

 wait_until 10 2 docker-compose exec -T postgres psql 

рдЬрдм PostGIS рдЖрд░рдВрднреАрдХреГрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЕрдЧрд▓реЗ рдЪрд░рдг рдкрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВ рдФрд░ рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде рднреА рдРрд╕рд╛ рд╣реА рдХрд░реЗрдВред рдЙрд╕рдХреЗ рд▓рд┐рдП, рдкрд░реАрдХреНрд╖рдг рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рд╣реИ: рдкреЛрд░реНрдЯ 80 рдХреЛ рдмрд╛рдзреНрдп рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

 docker-compose up -d my_service wait_until 10 2 docker-compose exec -T \ my_service sh -c "netstat -ntlp | grep 80 || exit 1" 

рдЕрдВрддрд┐рдо рдЪрд░рдг рд░рди рдХрдорд╛рдВрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрд╕рдмреАрдЯреА рдХреЛ рдЪрд▓рд╛рдирд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред

 docker-compose run sbt down $? 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рдм рдХреБрдЫ рд╕рд╣реА рдХреНрд░рдо рдореЗрдВ рдЙрдард╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗред

рдЕрдВрдд рдореЗрдВ, down рдлрдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдкрд┐рдЫрд▓реЗ рдХрдорд╛рдВрдб рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ "0" рд╣реИ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдкрд╛рд╕ рд╣реЛ рдЧрдП рд╣реИрдВ, рдФрд░ рд╣рдо рд╕рд┐рд░реНрдл рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬ рдХреЛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ; рдЕрдиреНрдпрдерд╛, рд╣рдо рдкрд╣рд▓реЗ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЧрд▓рдд рд╣реБрдЖ, рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЙрдЧреНрд╕ рдХреЛ рдмрдВрдж рдХрд░реЗрдВ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬ рдХреЛ рдмрдВрдж рдХрд░реЗрдВред

 function down { echo "Exiting with code $1" if [[ $1 -eq 0 ]]; then docker-compose down exit $1 else docker-compose logs -t postgres my_service docker-compose down exit $1 fi } 

рдЗрд╕ рддрд░рд╣ рдХреА рдпреЛрдЬрдирд╛ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдкреИрдорд╛рдирд╛ рдирд╣реАрдВ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдХреЛ рдЕрдкрдиреЗ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ docker-compose-run.sh рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд▓реЙрдиреНрдЪ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди docker-compose-run.sh рдФрд░ docker-compose.yml рдХреЗ рдмреАрдЪ рдлреИрд▓реА рд╣реБрдИ рд╣реИред рдЦреИрд░, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреА рдХрдорд┐рдпреЛрдВ рд╕реЗ рдЬреВрдЭ рд░рд╣реЗ рд╣реИрдВред

рдХреЛрдб рд╕реЗ рдЪрд▓ рд░рд╣рд╛ рд╣реИ


рдЬрдм рдкрд┐рдЫрд▓реА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдЧрдИ рдереА, рддреЛ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛: рдЕрдЧрд░ рдореЗрд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбреЙрдХрдЯрд░ рдореЗрдВ рд╕рдм рдХреБрдЫ рд╣реИ, рддреЛ рдЗрд╕реЗ рдХреЛрдб рд╕реЗ рдХреНрдпреЛрдВ рди рдЪрд▓рд╛рдпрд╛ рдЬрд╛рдПред рдореИрдВрдиреЗ рдПрдХ рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рд╢реБрд░реВ рдХреА рдФрд░ рдХрдИ рд╡рд┐рдХрд▓реНрдк рдкрд╛рдПред

рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдХреЗрд╡рд▓ рдбреЙрдХ рдХреНрд▓рд╛рдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ ред JVM рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рджреЛ рдореБрдЦреНрдп docker рдХреНрд▓рд╛рдЗрдВрдЯ рд╣реИрдВ: docker-java рдФрд░ Spotify docker-client ред

Docker рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдкрдХреЛ API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рд╕реЗ рд╕реАрдзреЗ docker рдХрдорд╛рдВрдб рдЪрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╛рдиреА, `docker run ...` рдЬреИрд╕реЗ рдХрдорд╛рдВрдб рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рдХреЙрдиреНрдЯреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдХреЛрдб рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдХрдорд╛рдВрдб рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕реЗ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред

рдпрд╣ рд╡рд┐рдзрд┐ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рдФрд░, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╡реЗ рд╕рдм рдХреБрдЫ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдмрд╣реБрдд рдирд┐рдореНрди рд╕реНрддрд░ рд╣реИред рдореБрдЭреЗ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдбреЙрдХреНрдпреВ-рдХрдВрдкреЛрдЬрд╝ рдПрдирд╛рд▓реЙрдЧ рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдПрдХ рдмрд╣реБрдд рдмрдбрд╝рд╛ рдХрд╛рдо рд╣реИред

рдЕрдЧрд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдбреЙрдХрдЯрд░-рдЗрдЯ-рд╕реНрдХрд╛рд▓рд╛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ , рдЬреЛ рдЗрди рджреЛрдиреЛрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдпрд╣ рдЪреБрдирдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рдмреИрдХреЗрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рд╡рд╣ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рдЪрд▓рд╛ рд╕рдХрддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдорд╛рдЗрдирд╕ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рд▓рдЪреАрд▓рд╛ рдПрдкреАрдЖрдИ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЬреАрд╡рди рдЪрдХреНрд░ рдирд┐рдпрдВрддреНрд░рдг рдирд╣реАрдВ рд╣реИред

рдореБрдЭреЗ рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдкрд╕рдВрдж рдирд╣реАрдВ рдерд╛, рдореИрдВрдиреЗ рдЦреЛрдЬ рдЬрд╛рд░реА рд░рдЦреА рдФрд░ рдЯреЗрд╕реНрдЯрдХреЛрдирдЯреЗрдирд░реНрд╕ рдкрд╛рдпрд╛ред рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдмрддрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

Testcontainers


рдпрд╣ рдбреЙрдХ рдХрдВрдЯреЗрдирд░ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЬрд╛рд╡рд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИред рдПрдХ рд╕реНрдХрд╛рд▓рд╛ рдореБрдЦреМрдЯрд╛, рд╡реГрд╖рдг-рд╢рд┐рд▓рд╛рд▓реЗрдЦ рд╣реИред рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░, рдХрдИ рд▓реЛрдХрдкреНрд░рд┐рдп рд╕реЗрд╡рд╛рдПрдВ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, PostgreSQL, MySQL, Nginx, Kafka, Seleniumред рдЖрдк рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдХрд╛рдлреА рд╕рд░рд▓ рдФрд░ рд▓рдЪреАрд▓рд╛ рдПрдкреАрдЖрдИ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛рдКрдВрдЧрд╛ред

рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрдВрдЯреЗрдирд░


рддреЛ, рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдВ, рдЬреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рд╣реИрдВ: рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрдВрдЯреЗрдирд░ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:

 val pgContainer: PostgreSQLContainer = PostgreSQLContainer("postgres:9.6") pgContainer.start() val pgUrl: String = pgContainer.jdbcUrl val pgPort: Int = pgContainer.mappedPort(5432) pgContainer.stop() 

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо PostgreSQLContainer рдмрдирд╛рддреЗ рд╣реИрдВ, рд╣рдо рдЗрд╕реЗ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ jbdcUrl рдорд┐рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЖрдк PostgreSQL рд╕реЗ рдЬреБрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж рд╣рдореЗрдВ mappedPort ред

рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ PostgreSQL рдбреЙрдХ рдкреЛрд░реНрдЯ 5432 рд╕реЗ рдЪрд┐рдкрдХ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ Testcontainers рдЗрд╕ рдкреЛрд░реНрдЯ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ рдФрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдкреЛрд░реНрдЯ рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВред рдЕрд░реНрдерд╛рддреН, рд╣рдо рдЬреЛ рдкрд░реАрдХреНрд╖рдг рджреЗрдЦрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 32422ред рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╣реЛрддрд╛ рд╣реИред

рдХрд╕реНрдЯрдо рдХрдВрдЯреЗрдирд░


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреГрд╢реНрдп, рддрдерд╛рдХрдерд┐рдд рдХрд╕реНрдЯрдо рдХрдВрдЯреЗрдирд░ рднреА рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ:

 class GenericContainer( imageName: String, exposedPorts: Seq[Int] = Seq(), env: Map[String, String] = Map(), command: Seq[String] = Seq(), classpathResourceMapping: Seq[(String, String, BindMode)] = Seq(), waitStrategy: Option[WaitStrategy] = None ) ... 

рдПрдХ GenericContainer рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЖрдкрдХреЛ рдХрдИ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЗрдирд╣реЗрд░рд┐рдЯ рдФрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдХреЗрд╡рд▓ imageName рд╕реЗрдЯ рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ - рдпрд╣ рдЙрд╕ рдХрдВрдЯреЗрдирд░ рдХрд╛ рдирд╛рдо рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдЖрдк exposedPorts рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рд╡реЗ рдкреЛрд░реНрдЯ рдЬреЛ рдХрдВрдЯреЗрдирд░ рд╕реЗ рдЪрд┐рдкрдХ рдЬрд╛рдПрдВрдЧреЗред Env рдореЗрдВ, рдЖрдк рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдк рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП command рднреА рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

classpathResourceMapping рдЖрдкрдХреЛ classpathResourceMapping рд╕реЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдлреЗрдВрдХрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реАрдзреЗ рдкрд░реАрдХреНрд╖рдг рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рд╣реИред рдЖрдк рдмрд╕ рдЕрдВрджрд░ рдХрд╛ рдирдХреНрд╢рд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдбреЙрдХрдЯрд░ рдХреЗ рдЕрдВрджрд░ рдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрд╕ рдХреЙрдиреНрдлрд┐рдЧ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рддрд╛ рд╣реИред

waitStrategy рдПрдХ рдмрд╣реБрдд рд╣реА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЪреАрдЬ рд╣реИ рдЬреЛ waitStrategy 3 рдореЗрдВ рдЧрд╛рдпрдм рдереА, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ HealthCheck рд╣реИред рдХрдИ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд waitStrategy , рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рддрдм рддрдХ рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рдХреЛрдИ рдкреЛрд░реНрдЯ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ http рд╡рд┐рдзрд┐ 200 рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреАред рд▓реЗрдХрд┐рди рдЖрдк рдЕрдкрдиреЗ рдХрд┐рд╕реА рднреА HealthCheck рдХреЛ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдЪреВрдБрдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ HealthCheck рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдк рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рднрд╛рд╖рд╛ рдХрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рди рдХрд┐ рдмреИрд╢ рдФрд░, рджреВрд╕рд░реА рдмрд╛рдд, рдЖрдкрдХреЗ рдХреЛрдб рд╕реЗ рдЙрдкрд▓рдмреНрдз рдХреЛрдИ рднреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА: рдпрджрд┐ рдЖрдк рдХреИрд╕реЗрдВрдбреНрд░рд╛ рдореЗрдВ рдХрд╕реНрдЯрдо рд╣реЗрд▓реНрдердЪреЗрдХ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ - рддреЛ рдбреНрд░рд╛рдЗрд╡рд░ рд▓реЗрдВ рдФрд░ рд▓рд┐рдЦреЗрдВ рдХреЛрдИ рднреА рд╕реНрд╡рд╛рд╕реНрдереНрдп рдЬрд╛рдВрдЪред

рдкрд░реАрдХреНрд╖рдг рдЪрд▓ рд░рд╣рд╛ рд╣реИ


рдФрд░ рдЕрдм рдереЛрдбрд╝рд╛ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ:

 class PostgresqlSpec extends FlatSpec with ForAllTestContainer { override val container = PostgreSQLContainer() "PostgreSQL container" should "be started" in { Class.forName(container.driverClassName) val connection = DriverManager .getConnection(container.jdbcUrl, container.username, container.password) // test some stuff } } 

рдореИрдВ ScalaTest рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ , Scala рджреБрдирд┐рдпрд╛ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рдирдХред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдПрдХ PostgresqlSpec рдкрд░реАрдХреНрд╖рдг рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕реЗ ForAllTestContainer рд╕реЗ ForAllTestContainer ред рдпрд╣ рдкреБрд╕реНрддрдХрд╛рд▓рдп рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИред рдпрд╣ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдкрд╣рд▓реЗ рдЖрд╡рд╢реНрдпрдХ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рд╢реБрд░реВ рдХрд░реЗрдЧрд╛ рдФрд░ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдмрд╛рдж рдЙрдиреНрд╣реЗрдВ рд░реЛрдХ рджреЗрдЧрд╛ред рдпрд╛ рдЖрдк ForeachTestContainer рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд┐рд░ рдХрдВрдЯреЗрдирд░ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкрд╣рд▓реЗ рд╢реБрд░реВ рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рдмрд╛рдж рдмрдВрдж рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред

рдлрд┐рд░ рдЖрдкрдХреЛ рдХрдВрдЯреЗрдирд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ container рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ PostgreSQLContainer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдлрд┐рд░ рд╣рдо рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореИрдВ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рддрд╛ рд╣реВрдВ, jdbcUrl, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо, рдкрд╛рд╕рд╡рд░реНрдб рд▓реЗрдВ, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВ, рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВред

рдЖрдорддреМрд░ рдкрд░, рдПрдХреАрдХрд░рдг рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдХрдИ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдореИрдВ рдЙрдиреНрд╣реЗрдВ MultipleContainers рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:

 val pgContainer = PostgreSQLContainer() val myContainer = MyContainer() override val container = MultipleContainers(pgContainer, myContainer) 

рдпрд╣реА рд╣реИ, рдореИрдВ рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддрд╛ рд╣реВрдВ, рдЙрдиреНрд╣реЗрдВ рдорд▓реНрдЯреАрдкрд▓рдЯреЗрдирд░ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реВрдВ, рдФрд░ container рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред

Testcontainers рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:



  1. GitLa рдореЗрдВ рдХреЛрдб рдкреБрд╢ рдХрд░реЗрдВред
  2. GitLab CI рдзрд╛рд╡рдХ рдиреЗ SBT рдХреЛ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ред
  3. SBT рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддрд╛ рд╣реИред рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдЕрдВрджрд░, рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдФрд░ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд▓реЙрдиреНрдЪ рдХреА рдЬрд╛рддреА рд╣реИрдВред

рдЗрд╕ рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд╛рдн:

  • рдПрдХ рдЕрд▓рдЧ рд╡рд╛рддрд╛рд╡рд░рдг рдФрд░ рдирд┐рд░реНрднрд░рддрд╛ рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд╕рдм рдХреБрдЫ рдзрд╛рд╡рдХ рдкрд░ рд╣реЛрддрд╛ рд╣реИред
  • рдЖрдк рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рд╢рд╛рдЦрд╛рдУрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  • рдЖрдк рд╕реНрдЯрд╛рд░реНрдЯ, рд╕реНрдЯреЙрдк рдФрд░ рд░рд┐рд╕реНрдЯрд╛рд░реНрдЯ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЬреАрд╡рди рдЪрдХреНрд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдореЗрдВ рд╕рдм рдХреБрдЫ рд╕рд╣реА рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ)ред
  • рд╡рд╣рд╛рдБ рд▓рдЪреАрд▓реЗ HealthChecks рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рд╕рдВрднрд╡рддрдГ рдХрдореА рдереАред
  • рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдХреЛрдИ * .sh рдлрд╛рдЗрд▓реЗрдВ рдирд╣реАрдВ рд╣реИрдВ, рдЖрдк рдЪрд╛рд╣реЗрдВ рддреЛ рд▓рдЪреАрд▓реЗрдкрди рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  • ClasspathResource рдореИрдкрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдЖрдк рдкрд░реАрдХреНрд╖рдг рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  • рдЖрдк рдХреЛрдб рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
  • рдпрд╣ рд╕рдм рд╕реАрдЖрдИ рдФрд░ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рджреЛрдиреЛрдВ рдкрд░ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдЪрд▓рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпреЗ рдХреЗрд╡рд▓ рдкрд░реАрдХреНрд╖рдг рд╣реИрдВ рдЬреЛ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрддреЗ рд╣реИрдВ рдФрд░ рдЪрд▓рддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд╕рдм рдХреБрдЫ рдКрдкрд░ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рд╕рдВрджрд┐рдЧреНрдз рд░реВрдк рд╕реЗ рдЪрд┐рдХрдиреА рдФрд░ рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдордиреЗ рдХрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ред

рдЖрд╢реНрд░рд┐рдд рдХрдВрдЯреЗрдирд░


рд╣рдордиреЗ рдЬреЛ рдкрд╣рд▓реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдЖрд╢реНрд░рд┐рдд рдХрдВрдЯреЗрдирд░ рд╣реИ ред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░реАрдХреНрд╖рд╛ рд╣реИ:

 class MySpec extends FlatSpec with ForAllTestContainer { val pgCont = PostgreSQLContainer() val appCont = AppContainer(pgCont.jdbcUrl, pgCont.username, pgCont.password) override val container = MultipleContainers(appCont, pgCont) // tests here } 

рдпрд╣ рдкреЛрд╕реНрдЯрдЧреНрд░рд╛рдВрдЯреНрд╕ рдФрд░ AppContainer рдЪрд▓рд╛рддрд╛ рд╣реИред рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкреЛрд╕реНрдЯрдЧреНрд░реИрд╕ рд╕реЗ appContainer jdbcUrl, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рдФрд░ рдкрд╛рд╕рд╡рд░реНрдб рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж, рдорд▓реНрдЯреАрдкрд▓рд░рдЯреЗрдирд░реНрд╕ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдореИрдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЪрд▓рд╛рддрд╛ рд╣реВрдВ рдФрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗрдЦрддрд╛ рд╣реВрдВ:

 Exception encountered when invoking run on a nested suite - Mapped port can only be obtained after the container is started 

рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдХрдВрдЯреЗрдирд░ рд╢реБрд░реВ рд╣реЛрдиреЗ рддрдХ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреЛрд░реНрдЯ рдирд╣реАрдВ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХреНрдпреЛрдВ рд╣реЛ рд░рд╣рд╛ рд╣реИ?

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ ForAllTestContainer рдпрд╛ ForEachTestContainer рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдареАрдХ рдкрд╣рд▓реЗ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЙрд╕ рд╕рдордп рдирд╣реАрдВ рдЬрдм рдореИрдВ рдХрдВрдЯреЗрдирд░ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддрд╛ рд╣реВрдВред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдЬрд┐рд╕ рд╕рдордп рдореИрдВ AppContainer рдмрдирд╛рддрд╛ рд╣реВрдВ, рдореЗрд░реЗ рдкрд╛рд╕ рдЕрднреА рддрдХ PostgreSQLContainer рдЪрд╛рд▓реВ рдирд╣реАрдВ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдореБрдЭреЗ рдЗрд╕рдореЗрдВ рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреЛрд░реНрдЯ рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ jdbcUrl рдмрдирд╛рдиреЗ рдХреА jdbcUrl ред

рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдХрдВрдЯреЗрдирд░ рдХрд╛ рд╕рд╛рд░ рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓ рд╣реИ: рдЗрд╕рдореЗрдВ рдХрдИ рд░рд╛рдЬреНрдп рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдмрдВрдж рдФрд░ рдЪрд╛рд▓реВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд░реЗрдВ? рдкрд╣рд▓реА рд╡рд┐рдзрд┐ рдореИрдВ "рдЖрд▓рд╕реА" рдХрд╣реВрдВрдЧрд╛ред

 class MyTest extends FreeSpec with BeforeAndAfterAll { lazy val pgCont = PostgreSQLContainer() lazy val appCont = AppContainer(pgCont.jdbcUrl, pgCont.username, pgCont.password) override def beforeAll(): Unit = { super.beforeAll() pgCont.start() appCont.start() } override def afterAll(): Unit = { super.afterAll() appCont.stop() pgCont.stop() } // tests here } 

рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдЖрд▓рд╕реА рдШрд╛рдЯреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрдВрдЯреЗрдирд░ рдмрдирд╛рдирд╛ рд╣реИред рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдкрд░реАрдХреНрд╖рдг рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ рддреБрд░рдВрдд рдЖрд░рдВрдн рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рдХреЙрд▓ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗред рд╣рдо beforeAll рдФрд░ afterAll рдореЗрдВ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдХрд┐ рд╕реНрдХреИрд▓реЗрд╕реНрдЯ рд╕реЗ рдкрд╣рд▓реЗ рдХреЗAAndAfterAll BeforeAndAfterAll рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдкрд╣рд▓реЗ beforeAll рдХрдВрдЯреЗрдирд░ рд╢реБрд░реВ рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдмрд╛рдж рдореЗрдВ, рд╡реЗ рдмрдВрдж рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рдЖрд▓рд╕реА рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрд╕ рд╕рдордп рдкреНрд░рд╛рд░рдВрдн рд╡рд┐рдзрд┐ рдХреЛ рдкрд╣рд▓реЗ рд╕рднреА рдореЗрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЖрд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдПрдХ рддреНрд░реБрдЯрд┐ рдЕрднреА рднреА рд╣реЛрддреА рд╣реИ рдХрд┐ рдореИрдВ рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛: 32787:

 org.postgresql.util.PSQLException: Connection to localhost:32787 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. 

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдордиреЗ jdbcUrl рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ рдХреНрдпреЛрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ? рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ jdbcUrl рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:

 @Override public String getJdbcUrl() { return "jdbc:postgresql://" + getContainerIpAddress() + ":" + getMappedPort(POSTGRESQL_PORT) + "/" + databaseName; } 

рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рдВрдШрдирди рд╣реИред рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рд╡реЗ рдЯреВрдЯ рдирд╣реАрдВ рд╕рдХрддреЗред getMappedPort рдХреЛ рднреА рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╣реА рдЗрд╕реЗ рдареАрдХ рдХрд░ рдЪреБрдХреЗ рд╣реИрдВред databaseName рдПрдХ рд╣рд╛рд░реНрдб-рдХреЛрдбрд┐рдд рд╕реНрдерд┐рд░рд╛рдВрдХ рд╣реИред рд▓реЗрдХрд┐рди getContainerIpAddress рд╕рд╛рде рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред рдирд╛рдо рд╕реЗ, рд╣рдо рдорд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕реЗ рдХрдВрдЯреЗрдирд░ рдХрд╛ рдЖрдИрдкреА рдкрддрд╛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдЗрд╕ рдХреЛрдб рдХреЛ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛ рд▓реЛрдХрд▓рд╣реЛрд╕реНрдЯ рджреЗрддрд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдирд┐рдХрд▓рд╛, рдпрд╣ рд╡рд┐рдзрд┐ рдЕрдВрддрд░-рдХрдВрдЯреЗрдирд░ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рдирд╣реАрдВ рд╣реИ: getContainerIpAddress рдХрдВрдЯреЗрдирд░ рдХреЗ рдЕрдВрджрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ ред

Testcontainers рдбреЗрд╡рд▓рдкрд░ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢: рдЗрдВрдЯрд░-рдХрдВрдЯреЗрдирд░ рд╕рдВрдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╕реНрдЯрдо рдиреЗрдЯрд╡рд░реНрдХ рдмрдирд╛рдПрдВ ред рдбреЙрдХрд░-рд░рдЪрдирд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ: рдпрд╣ рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдмрдирд╛рддреА рд╣реИ рдФрд░ рдЕрдкрдиреЗ рдЖрдк рд╣реА рд╕рдм рдХреБрдЫ рд╣рд▓ рдХрд░рддреА рд╣реИред

рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

 class MyTest extends FreeSpec with BeforeAndAfterAll { val network: Network = Network.newNetwork() val dbName = "some_db" val pgContainerAlias = "postgres" val jdbcUrl = s"jdbc:postgresql://$pgContainerAlias:5432/$dbName" lazy val pgCont = { val c = PostgreSQLContainer("postgres:9.6") c.container.withNetwork(network) c.container.withNetworkAliases(pgContainerAlias) c.container.withDatabaseName(dbName) c } lazy val appCont = { val c = AppContainer(jdbcUrl, pgCont.username, pgCont.password) c.container.withNetwork(network) c } override def beforeAll(): Unit = { super.beforeAll() pgCont.start() appCont.start() } override def afterAll(): Unit = { super.afterAll() appCont.stop() pgCont.stop() network.close() } // tests here } 

рдЕрдм рд╣рдореЗрдВ рдЕрдкрдиреЗ jdbcUrl рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдореЗрдВ рдЕрдкрдиреЗ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рдиреЗрдЯрд╡рд░реНрдХ рдореЗрдВ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ PostgreSQLContainer рдХреЗ рд▓рд┐рдП рдЕрдиреНрдп рдирд╛рдо рд╕реЗрдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рднреАрддрд░ рдХреБрдЫ рдбреЛрдореЗрди рдирд╛рдо рд╕реЗ рд╕реБрд▓рдн рд╣реЛред рдЕрдВрдд рдореЗрдВ, рдЖрдкрдХреЛ рдиреЗрдЯрд╡рд░реНрдХ рдХреЛ "рдорд╛рд░" рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЕрдВрдд рдореЗрдВ, рдРрд╕рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

Testcontainers-scala рдХреЗ рд╣рд╛рд▓ рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ, рдЖрд▓рд╕реА рдХрдВрдЯреЗрдирд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рд╕рдорд░реНрдерд┐рдд рд╣реИ:

 class MyTest extends FreeSpec with ForAllTestContainer with BeforeAndAfterAll { val network: Network = Network.newNetwork() val dbName = "some_db" val pgContainerAlias = "postgres" val jdbcUrl = s"jdbc:postgresql://$pgContainerAlias:5432/$dbName" lazy val pgCont = { val c = PostgreSQLContainer("postgres:9.6") c.container.withNetwork(network) c.container.withNetworkAliases(pgContainerAlias) c.container.withDatabaseName(dbName) c } lazy val appCont = { val c = AppContainer(jdbcUrl, pgCont.username, pgCont.password) c.container.withNetwork(network) c } override val container = MultipleContainers(pgCont, appCont) override def afterAll(): Unit = { super.afterAll() network.close() } // tests here } 

рдЖрдк ForAllTestContainer рдФрд░ MultipleContainers рдлрд┐рд░ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╣рд▓реЗ beforeAll рдкреНрд░рд╛рд░рдВрдн рдЖрджреЗрд╢ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ beforeAll рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЕрдм рдорд▓реНрдЯреАрдкрд▓рд░рдЯреЗрдирд░ рдЖрд▓рд╕реА рд╡реИрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рд╣реА рдХреНрд░рдо рдореЗрдВ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдирд┐рд░реНрдорд╛рдг рдкрд░ рддреБрд░рдВрдд рд╕рдЦреНрдд рдЖрд░рдВрднреАрдХрд░рдг рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕реА рд╕рдордп, рдХрд╕реНрдЯрдо рдиреЗрдЯрд╡рд░реНрдХ рдФрд░ jdbcUrl рдХреЗ рд╕рд╛рде рд╣реЗрд░рдлреЗрд░ рднреА рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

mocks


рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрднреА рднреА рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдореЛрдХреАред рдХрднреА-рдХрднреА рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд╣рдо рд╕реНрдкрд╛рд░реНрдХ рдЬреЙрдмрд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╕реНрдкрд╛рд░реНрдХ рдиреМрдХрд░рд┐рдпрд╛рдВ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рд╕реНрдкрд╛рд░реНрдХ рдореЗрдВ рдЙрдирдХреЗ рдЬреАрд╡рди рдЪрдХреНрд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╣рдо рдЗрд╕рдХреЗ рджреЛ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: "рдмрдирд╛рдПрдБ" рдФрд░ "рд╕реНрдерд┐рддрд┐ рджреЗрдВ"ред

рдбреЙрдХ рдХреЗ рдЕрдВрджрд░ рд╕реНрдкрд╛рд░реНрдХ рдЬреЛрдмрд╕реЗрд╡рд░ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рд╕реНрдкрд╛рд░реНрдХ рдХреЛ рдЙрдард╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЬрдм рддрдХ, рдЗрд╕рдореЗрдВ рдбреЙрдХ рдХрдВрдЯреЗрдирд░ рдирд╣реАрдВ рдерд╛ рдФрд░ рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рдЗрдХрдЯреНрдард╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реНрдкрд╛рд░реНрдХ рдЬреЙрдмрд╕реЗрд╡рд░ рд░рд╛рдЬреНрдпреЛрдВ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП PostgreSQL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдирддреАрдЬрддрди, рдЖрдкрдХреЛ рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рдХрд╛рдо рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ рдЬрдм рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрдкреАрдЖрдИ рдХреЗ рд╕рд╛рде рдХреЗрд╡рд▓ рджреЛ рддрд░реАрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

рд▓реЗрдХрд┐рди рдЖрдк рд╕реНрдкрд╛рд░реНрдХ рдЬреЛрдмрд╕реЗрд╡рд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЭрд╛рдБрдХ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдРрд╕рд╛ рдореЙрдХ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореВрд▓ рд╕реНрдкрд╛рд░реНрдХ рдЬреЛрдмрд╕реЗрд╡рд░ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдПрдХ рд╕рд░рд▓ рдЫрджреНрдо рдХреЛрдб):

 val hostIp = ??? AppContainer(sparkJobServerMockHost = hostIp) val sparkJobServerMock = new SparkJobServerMock() sparkJobServerMock.init(someData) val apiResult = appApi.callMethod() assert(apiResult == someData) 

http- API Spark JobServer. - , . , , , mock.

- , . : ┬л┬╗ config; , host.

SparkJobServerMock , host-, docker-, , , docker-.

? docker-, , gateway , docker-.

, Testcontainers API. , Testcontainers docker-java-, . ┬л┬╗ docker-:

 val client: com.github.dockerjava.api.DockerClient = DockerClientFactory .instance .client val networkInfo: com.github.dockerjava.api.model.Network = client .inspectNetworkCmd() .withNetworkId(network.getId) .exec() val hostIp: String = networkInfo .getIpam .getConfig .get(0) .getGateway 

-, DockerClient . Testcontainers DockerClientFactory . c inspectNetworkCmd . , info, gateway.

, , .

тАФ . Docker : Windows, Mac, . Linux. , , Linux .

, Testcontainers . , docker-. :

 Testcontainers.exposeHostPorts(sparkJobServerMockPort) 

, . docker-. `host.testcontainers.internal` .

, :

 val sparkJobServerMockHost = "host.testcontainers.internal" val sparkJobServerMockPort = 33333 Testcontainers.exposeHostPorts(sparkJobServerPort) AppContainer(sparkJobServerMockHost, sparkJobServerMockPort) 


Testcontainers


, , Testcontainers , . Java-, Scala-. :

  • . , testcontainers-java JUnit, testcontainers-scala ScalaTest, testcontainers-java . Scala- .
  • Scala . . , . , predefined Java-. , .
  • API . API, . , . , , .

рдкрд░рд┐рдгрд╛рдо


. Docker , , , , network gateway.

Testcontainers тАФ , . API , .

Java-, . тАФ . .

, docker-, .

тАФ , , , . .?

, .

тАФ - ?

Kubernetes, . end-to-end , , , , .

, , unit-, .

тАФ Kubernetes ?

-, , -, , , , Spark Kubernetes ; , .

, , unit-, , , break point , , .

, , , CI , .

, minicube тАФ Mac, . , , , , .

тАФ ? : master? , - , , 2.1, 2.2, ?

ImageName, Postgres 9.6.

 val pgContainer: PostgreSQLContainer = PostgreSQLContainer("postgres:9.6") 

9.6, 10. [ ], .

Image tag тАФ , тАФ , . , latest .

тАФ , ?

, CI , GitLab CI , , Branch Name.

тАФ , , , ? - , ? 20- , ?

-, , . , , , , , .

- , , full-time , , , .

commit', , , , Android, iOS . . , , , , тАФ .

, , -: - , - . , - .

Scala тАУ ScalaConf . тАУ HighLoad++ 7-8 .

, , , , .

Source: https://habr.com/ru/post/hi464307/


All Articles