{"id":482701,"date":"2026-06-07T12:47:05","date_gmt":"2026-06-07T12:47:05","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=482701"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=482701","title":{"rendered":"CI\/CD \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d\u0430: GitLab Registry, Docker in Docker \u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u044c"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0422\u0440\u0435\u0442\u044c\u044f \u0447\u0430\u0441\u0442\u044c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e CI\/CD \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 gitlab container registry.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u0441\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043c\u043d\u043e\u0439 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0435 \u0433\u0430\u0439\u0434\u044b \u043d\u0435 \u0434\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435, \u043f\u0440\u0438\u0447\u0435\u043c \u043f\u043e\u0434 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u0438 \u043a\u0435\u0439\u0441: .net, Java, Node JS, etc.<\/p>\n<p>\u0426\u0435\u043b\u044c\u044e \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0438 \u0441\u0445\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0432\u0441\u0435 \u044d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e. \u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0432\u043e\u043e\u0440\u0443\u0436\u0438\u0442\u044c \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0435\u043c\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0435\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u041f\u043e\u043c\u0438\u043c\u043e \u0441\u0430\u043c\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a \u0436\u0435 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0434\u043b\u044f \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 DevOps, \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439:<\/p>\n<ul>\n<li>\n<p>\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 Gitlab (\u043e\u0431\u0449\u0438\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b \u0438 \u0434\u043b\u044f \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432).<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b: Bash, Docker, Kubernetes \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0449\u0443\u044e \u0442\u0435\u043e\u0440\u0438\u044e \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443 \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0441\u0442\u0430\u0434\u0438\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u0433\u0434\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c \u0440\u044b\u043d\u043e\u043a, \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0431\u0435\u0441\u043f\u0435\u0440\u0435\u0431\u043e\u0439\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c downtime, \u0440\u0430\u0437\u0433\u0440\u0443\u0437\u0438\u0442\u044c production \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442 \u043b\u0438\u0448\u043d\u0435\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043b\u0438\u0437\u0430 \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c\u0441\u044f.<\/p>\n<hr\/>\n<p>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0440\u0430\u0437\u0431\u0438\u0442 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u0435\u0439.<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1031452\/\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 GitLab CI\/CD: \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 pipeline<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1032654\/\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 self-hosted gitlab runner (CI\/CD)<\/a><\/p>\n<\/li>\n<li>\n<p>[\u0412\u044b \u0437\u0434\u0435\u0441\u044c \u2192 ] \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 registry (GitLab CI\/CD)<\/p>\n<\/li>\n<li>\n<p>[todo] \u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 CI\/CD (\u0432\u044b\u0441\u043e\u043a\u043e-\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d)<\/p>\n<\/li>\n<\/ol>\n<h2>\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/h2>\n<ul>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0430\u043c\u0438 \u0438 registry \u0432 <code>.gitlab-ci.yml<\/code><\/p>\n<\/li>\n<li>\n<p>Gitlab Container Registry<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 <code>gitlab-ci.yml<\/code> <\/p>\n<ul>\n<li>\n<p>\u0414\u0436\u043e\u0431\u0430 build-image<\/p>\n<\/li>\n<li>\n<p>\u0414\u0436\u043e\u0431\u0430 test-image<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 <\/p>\n<ul>\n<li>\n<p>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 gitlab runner \u0432 SELinux<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430 \u043f\u0440\u043e\u0434-\u0441\u0435\u0440\u0432\u0435\u0440\u0435<\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0430\u043c\u0438 \u0438 registry \u0432 .gitlab-ci.yml<\/h2>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 <code>.gitlab-ci.yml<\/code> \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0447\u0442\u043e \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 \u043e\u0431\u0440\u0430\u0437\u0430. \u041e\u0431\u0440\u0430\u0437\u0443 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 registry. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043d\u0430\u0448\u0438\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432 \u0432 \u043f\u0440\u043e\u0434\u0435 \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f. \u0415\u0449\u0435 \u043e\u0434\u043d\u0438\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 production \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430 \u043f\u0440\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043c.<\/p>\n<ol>\n<li>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u0432 \u0432\u0438\u0434\u0435 Docker \u043e\u0431\u0440\u0430\u0437\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0444\u0430\u0439\u043b. \u041d\u043e \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0434\u043b\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u0445 \u043c\u0435\u0436\u0434\u0443 \u0434\u0436\u043e\u0431\u0430\u043c\u0438. \u0415\u0441\u043b\u0438 \u043f\u043e\u0439\u0442\u0438 \u0442\u0430\u043a\u0438\u043c \u043f\u0443\u0442\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0442\u0430\u043a\u043e\u0435:<\/p>\n<pre><code class=\"yaml\">build-image:  stage: build  script:    - docker build -t myapp:latest .    - docker save myapp:latest -o myapp.tar   # \u043e\u0431\u0440\u0430\u0437 \u2192 \u0444\u0430\u0439\u043b  artifacts:    paths:      - myapp.tar    expire_in: 2 weeks          # \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f 2 \u043d\u0435\u0434\u0435\u043b\u0438,                                 # \u0437\u0430\u0442\u0435\u043c \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u0441\u043e\u0440\u044f\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/li>\n<li>\n<p><strong>Gitlab \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f Docker \u043e\u0431\u0437\u0430\u0440\u043e\u0432: GitLab Container Registry. \u0418\u043c\u0435\u043d\u043d\u043e \u0435\u0433\u043e \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/strong><\/p>\n<\/li>\n<\/ol>\n<h2>Gitlab Container Registry<\/h2>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0432\u0438\u0434\u0435 bash \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c:<\/p>\n<p><code>my-app.sh<\/code><\/p>\n<pre><code class=\"bash\">#!\/bin\/bashecho \"Message from my-app.sh v1.0.0: Hello world!\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 Dockerfile \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p><code>Dockerfile<\/code><\/p>\n<pre><code>FROM alpine:3.23# \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440COPY my-app.sh \/my-app.sh# \u0414\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043cRUN chmod +x \/my-app.sh# \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430CMD [\"\/my-app.sh\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 gitlab-ci.yml<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0438\u0448\u0435\u043c <code>.gitlab-ci.yml<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0434\u0432\u0443\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 stages. \u0422\u0430\u043a \u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0438\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432. \u041d\u043e \u043d\u0430\u0448\u0430 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043f\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 <a href=\"https:\/\/semver.org\/\" rel=\"noopener noreferrer nofollow\">semver<\/a>, \u0442\u0430\u043a \u043a\u0430\u043a semver \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0434\u0430\u0442\u0443 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435: <code>YYYY-MM-DD-HH-MM<\/code>. \u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0443\u0434\u043e\u0431\u0435\u043d \u0442\u0435\u043c \u0447\u0442\u043e \u043e\u043d \u0441\u0440\u0430\u0437\u0443 \u0434\u0430\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043e \u0434\u0430\u0442\u0435 \u0440\u0435\u043b\u0438\u0437\u0430 \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u043f\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044e.<\/p>\n<pre><code class=\"yaml\">stages:  - build  - testdefault:  image: docker:29.4build-image:  stage: build  script:    - IMAGE_TAG=$(date +%Y-%m-%d-%H-%M)    - echo \"\u0412\u0435\u0440\u0441\u0438\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 $IMAGE_TAG\"    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY    - docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .    - docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG    - docker tag $CI_REGISTRY_IMAGE:$IMAGE_TAG $CI_REGISTRY_IMAGE:latest    - docker push $CI_REGISTRY_IMAGE:latesttest-image:  stage: test  script:    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY    - docker run --rm $CI_REGISTRY_IMAGE:latest<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438\u0437 script <\/summary>\n<div class=\"spoiler__content\">\n<h3>\u0414\u0436\u043e\u0431\u0430 build-image<\/h3>\n<pre><code class=\"bash\">IMAGE_TAG=$(date +%Y-%m-%d-%H-%M)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e IMAGE_TAG, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0434\u0430\u0442\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>YYYY-MM-DD-HH-MM<\/code>.<\/p>\n<pre><code>$(...)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043a\u043e\u0431\u043e\u043a \u0438 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0451 <a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/894854\/\" rel=\"noopener noreferrer nofollow\">stdout<\/a> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<pre><code>date +%Y-%m-%d-%H-%M<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>date<\/code> \u2014 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0423\u043c\u0435\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0432\u044b\u0432\u043e\u0434\u0430. <br \/> <code>+<\/code> \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0440\u0435\u043c\u044f, \u0430 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c, \u0434\u0430\u043b\u0435\u0435 \u0438\u0434\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f. <br \/> \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u201c\u0442\u043e\u043a\u0435\u043d\u044b\u201d \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435:<\/p>\n<ul>\n<li>\n<p><code>%Y<\/code> \u2014 \u0433\u043e\u0434, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>2026<\/code><\/p>\n<\/li>\n<li>\n<p><code>%m<\/code> \u2014 \u043c\u0435\u0441\u044f\u0446, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>04<\/code><\/p>\n<\/li>\n<li>\n<p><code>%d<\/code> \u2014 \u0434\u0435\u043d\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>10<\/code><\/p>\n<\/li>\n<li>\n<p><code>%H<\/code> \u2014 \u0447\u0430\u0441\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>15<\/code><\/p>\n<\/li>\n<li>\n<p><code>%M<\/code> \u2014 \u043c\u0438\u043d\u0443\u0442\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>42<\/code><\/p>\n<\/li>\n<\/ul>\n<p><a href=\"https:\/\/man7.org\/linux\/man-pages\/man1\/date.1.html\" rel=\"noopener noreferrer nofollow\">\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/a> <\/p>\n<pre><code>echo \"\u0412\u0435\u0440\u0441\u0438\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 $IMAGE_TAG\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>$IMAGE_TAG<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0442\u0435\u0433\u0430.<\/p>\n<pre><code class=\"bash\">docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0432 Docker-\u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u0435\u0434\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 <a href=\"https:\/\/docs.gitlab.com\/ci\/variables\/predefined_variables\/\" rel=\"noopener noreferrer nofollow\">(predefined CI\/CD variables)<\/a> \u0432 gitlab ci. <br \/> <code>docker login<\/code> \u2014 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 Docker registry <br \/> <code>-u $CI_REGISTRY_USER<\/code> \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f <br \/> <code>-p $CI_REGISTRY_PASSWORD<\/code> \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u0440\u043e\u043b\u044c <br \/> <code>$CI_REGISTRY<\/code> \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u043e\u0433\u043e registry <\/p>\n<p>\u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 gitlab \u0441\u0430\u043c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442, \u043c\u044b \u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0442\u0430\u0435\u043c.<\/p>\n<pre><code class=\"bash\">docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>docker build -t &lt;...&gt; .<\/code> \u2014 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0443 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <a href=\"https:\/\/docs.docker.com\/build\/concepts\/context\/\" rel=\"noopener noreferrer nofollow\">build context<\/a> \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e (\u0442\u043e\u0447\u043a\u0430 <code>.<\/code> \u043d\u0430 \u043a\u043e\u043d\u0446\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e). Build context \u2014 \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0441\u0431\u043e\u0440\u043a\u0435. \u041c\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0441\u044e \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0443\u0436\u043d\u044b, \u0430 \u043a\u0430\u043a\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>.dockerignore<\/code> <a href=\"https:\/\/docs.docker.com\/build\/concepts\/context\/#dockerignore-files\" rel=\"noopener noreferrer nofollow\">(\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f)<\/a>. <br \/> <code>-t $CI_REGISTRY_IMAGE:$IMAGE_TAG<\/code> \u2014 \u0437\u0430\u0434\u0430\u0435\u0442 \u0442\u0435\u0433 \u043e\u0431\u0440\u0430\u0437\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>\u0438\u043c\u044f:\u0442\u044d\u0433<\/code>. <br \/> <code>$CI_REGISTRY_IMAGE<\/code> \u2014 \u0413\u0438\u0442\u043b\u0430\u0431 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442 \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 <code>registry.gitlab.com\/mygroup\/myproject<\/code> <br \/> <code>$IMAGE_TAG<\/code> \u2014 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>2026-04-10-15-42<\/code> <br \/> \u0418\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435: <code>registry.gitlab.com\/mygroup\/myproject:2026-04-10-15-42<\/code>. <\/p>\n<pre><code class=\"bash\">docker tag $CI_REGISTRY_IMAGE:$IMAGE_TAG $CI_REGISTRY_IMAGE:latest<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430, \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0442\u0435\u0433 <code>:latest<\/code>. \u0415\u0441\u043b\u0438 \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: <code>registry.gitlab.com\/mygroup\/myproject:2026-04-10-15-42<\/code>, \u0442\u043e \u043c\u044b \u0434\u0430\u0435\u043c \u0435\u043c\u0443 \u0442\u0430\u043a \u0436\u0435 \u0438\u043c\u044f <code>registry.gitlab.com\/mygroup\/myproject:latest<\/code>.<\/p>\n<pre><code class=\"bash\">docker push $CI_REGISTRY_IMAGE:latest<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432 registry \u0442\u0430\u043a \u0436\u0435 \u043d\u0430\u0448 \u0442\u0435\u0433 <code>latest<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432 registry \u0435\u0441\u0442\u044c 1 \u043e\u0431\u0440\u0430\u0437 \u0441 2 \u0438\u043c\u0435\u043d\u0430\u043c\u0438. \u041a\u043e\u0433\u0434\u0430 \u0434\u0436\u043e\u0431\u0430 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e, \u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0448\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c latest \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0443 \u0447\u0435\u0440\u0435\u0437 \u0442\u0435\u0433 <code>latest<\/code>. \u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e <code>latest<\/code>, \u043d\u043e \u044d\u0442\u043e \u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435\u0439\u043c\u0438\u043d\u0433\u0430 \u0434\u043e\u043a\u0435\u0440 \u043e\u0431\u0440\u0430\u0437\u043e\u0432.<\/p>\n<h3>\u0414\u0436\u043e\u0431\u0430 test-image<\/h3>\n<pre><code class=\"bash\">docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0434\u0436\u043e\u0431\u0435 <code>test-image<\/code> \u043c\u044b \u0441\u043d\u043e\u0432\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 registry, \u043a\u0430\u043a \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435 \u043d\u0430 \u0441\u0445\u0435\u043c\u0435 (\u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438\u043b\u0438 \u043d\u0438\u0436\u0435 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439), \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u0443\u044e \u0434\u0436\u043e\u0431\u0443 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440.<\/p>\n<pre><code class=\"bash\">docker run --rm $CI_REGISTRY_IMAGE:latest<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>docker run<\/code> \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <br \/> <code>--rm<\/code> \u2014 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0435\u0433\u043e <br \/> <code>$CI_REGISTRY_IMAGE:latest<\/code> \u2014 \u0441\u0441\u044b\u043b\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 <code>latest<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 <\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0432\u0441\u0435 \u043b\u043e\u0433\u0438\u0447\u043d\u043e. \u041d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 shared runners \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.<\/p>\n<p>\u041d\u0430 \u0448\u0430\u0433\u0435 <code>docker build<\/code> \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<pre><code>$ docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .ERROR: failed to connect to the docker API at tcp:\/\/docker:2375: lookup docker on 169.254.169.254:53: no such host<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>image: docker<\/code>, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u043a\u0435\u0440, \u0430 \u043b\u0438\u0448\u044c \u0435\u0433\u043e cli \u043a\u043b\u0438\u0435\u043d\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a docker daemon. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043a\u0443 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a docker daemon \u043c\u044b \u0438 \u0432\u0438\u0434\u0438\u043c.<\/p>\n<p>Shared runner \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043d\u0430\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 docker daemon, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u043e\u0442\u043e\u0432 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0442 CLI-\u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e \u0447\u0442\u043e \u043e\u043d \u0435\u0441\u0442\u044c \u0438 \u043e\u043d \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043d\u0430\u0448\u0438 \u0434\u0436\u043e\u0431\u044b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c docker-cli \u0432 \u043d\u0430\u0448\u0438\u0445 \u0434\u0436\u043e\u0431\u0430\u0445, \u0442\u043e \u043c\u044b \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u043c\u0443 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0443\u0442\u043e\u0432\u044b\u0439 docker daemon (\u043d\u0435 dind)<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d docker daemon, \u043d\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0434\u043b\u044f \u0434\u0436\u043e\u0431 (dind)<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d docker-cli \u0438 docker daemon. \u0415\u0441\u0442\u044c 2 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>Docker daemon (dind, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u0440\u0430\u0437 <code>docker:29-dind<\/code>)<\/p>\n<\/li>\n<li>\n<p>Docker CLI (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u0440\u0430\u0437 <code>docker:29-cli<\/code> \u0438\u043b\u0438 \u0431\u0435\u0437 \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u0430 <code>cli<\/code>)<\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e\u0431\u044b CLI-\u043a\u043b\u0438\u0435\u043d\u0442, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0443, \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u0442\u044c\u0441\u044f \u0441 docker daemon. \u0421\u0432\u044f\u0437\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f 2-\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p>ip + port<\/p>\n<\/li>\n<li>\n<p><code>docker.sock<\/code> \u0444\u0430\u0439\u043b (linux socket \u2014 \u044d\u0442\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 ip + port, \u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u0444\u0430\u0439\u043b\u0430)<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u0432\u044f\u0437\u0438 (ip+port \u0438\u043b\u0438 docker.sock) \u0441 docker daemon, \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u043d\u0435\u0440\u0430, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 shared runner. \u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u043d\u0435\u0440\u0430, \u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0433\u043e executor \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439 self-hosted gitlab runner.<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1032654\/\" rel=\"noopener noreferrer nofollow\">\u041c\u043e\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 self-hosted gitlab runner.<\/a><\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u0443\u0442\u0435\u0439<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c kaniko \u2014 \u043e\u043d \u0431\u044b\u043b \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u043b \u043b\u0435\u0433\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0438\u043b\u0434 \u0431\u0435\u0437 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0430 docker. \u041f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 kaniko \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c (<a href=\"https:\/\/github.com\/GoogleContainerTools\/kaniko\/issues\/3348\" rel=\"noopener noreferrer nofollow\">issue<\/a>). \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u0435\u0433\u043e \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/docs.gitlab.com\/ci\/docker\/using_docker_build\/#buildah-example\" rel=\"noopener noreferrer nofollow\">buildah<\/a>, \u0447\u0435\u043c-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 kaniko, \u043f\u0440\u0435\u043f\u043e\u0434\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0435\u0433\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430. \u041d\u043e \u043c\u0435\u043d\u044f \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u043e\u0436\u0435 \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442 \u2014 \u0441\u0443\u0434\u044f \u043f\u043e issues \u0435\u0441\u0442\u044c \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043d\u0443\u0436\u0434\u0430\u044e\u0442 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c (\u0447\u0442\u043e \u043f\u0440\u0438\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u043a \u0448\u0438\u0440\u043e\u043a\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u043c\u0443 dind).<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u043c\u0435\u0441\u0442\u043d\u043e \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/6d\/2c\/86\/6d2c86b6f37e989aa9a1ec70b965436b.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/6d\/2c\/86\/6d2c86b6f37e989aa9a1ec70b965436b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/6d\/2c\/86\/6d2c86b6f37e989aa9a1ec70b965436b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u042d\u0442\u0430 \u0441\u0445\u0435\u043c\u0430 \u043f\u0440\u0430\u0432\u0434\u0438\u0432\u0430 \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 GitLab Runner \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043d\u0430 host \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u042f \u0436\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c Gitlab Runner \u0432 Docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u043a\u0430\u043a \u044f \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b \u044d\u0442\u043e \u0432 \u0441\u0432\u043e\u0435\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0434\u043b\u044f \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0437\u0432\u0443\u0447\u0435\u043d\u044b \u0432\u044b\u0448\u0435.<\/p>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u0442\u043e\u0432\u043e\u0433\u043e docker daemon (\u043d\u0435 dind)<\/h3>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/fb\/f7\/1e\/fbf71ef0f230a9952de3562e47c501c9.png\" alt=\"\u042d\u0442\u043e \u043d\u0435 docker in docker\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/fb\/f7\/1e\/fbf71ef0f230a9952de3562e47c501c9.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/fb\/f7\/1e\/fbf71ef0f230a9952de3562e47c501c9.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u042d\u0442\u043e \u043d\u0435 docker in docker<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043d\u0435 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 docker daemon, \u043a\u043e\u043c\u0430\u043d\u0434\u044b CLI \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u043a \u0445\u043e\u0441\u0442\u043e\u0432\u043e\u043c\u0443 docker\u2019\u0443, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0430\u0444\u0444\u0435\u043a\u0442\u0438\u0442\u044c \u0440\u0443\u0442\u043e\u0432\u0443\u044e \u043c\u0430\u0448\u0438\u043d\u0443. \u0412\u0441\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043e\u0431\u0449\u0438\u0439 \u043a\u044d\u0448 \u0445\u043e\u0441\u0442\u0430. \u0418\u0437\u043e\u043b\u044f\u0446\u0438\u0438 \u0434\u0436\u043e\u0431\u043e\u0432 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c race condition (\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0433\u043e\u043d\u043a\u0438), \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u043b\u0438 \u0434\u0432\u0435 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0436\u043e\u0431\u044b \u043f\u043e\u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043e\u0431\u0440\u0430\u0437.<\/p>\n<p>\u041d\u043e \u0435\u0441\u0442\u044c \u043f\u043b\u044e\u0441 \u2014 \u0434\u0436\u043e\u0431\u044b \u0431\u0443\u0434\u0443\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0449\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 `config.toml`<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>concurrent = 1check_interval = 0[[runners]]  name = \"laptop-dc\"  url = \"https:\/\/gitlab.com\/\"  token = \"\u0412\u0410\u0428_\u0420\u0410\u041d\u041d\u0415\u0420_\u0422\u041e\u041a\u0415\u041d_\u0418\u0417_\u041d\u0410\u0421\u0422\u0420\u041e\u0415\u041a_GITLAB\"  executor = \"docker\"  [runners.docker]    image = \"alpine:3.22.4\"     privileged = false    disable_entrypoint_overwrite = false    disable_cache = false    volumes = [        \"\/cache\",        \"\/var\/run\/docker.sock:\/var\/run\/docker.sock\"    ]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0437\u0434\u0435\u0441\u044c: <code>\"\/var\/run\/docker.sock:\/var\/run\/docker.sock\"<\/code>.<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435\u043c \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438 \u043c\u0435\u043d\u044f \u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.  \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0445\u0435\u043c\u0443, \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0435 \u043c\u044b \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.<\/p>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e docker daemon, \u043d\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0434\u043b\u044f \u0434\u0436\u043e\u0431 (dind)<\/h3>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/a0\/67\/83\/a06783589dcd882bb4ff0bbb28e33fb8.png\" alt=\"Docker in docker (dind)\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/a0\/67\/83\/a06783589dcd882bb4ff0bbb28e33fb8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/a0\/67\/83\/a06783589dcd882bb4ff0bbb28e33fb8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Docker in docker (dind)<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0432 \u0446\u0435\u043b\u044f\u0445 \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 docker daemon, \u0440\u0443\u0442\u043e\u0432\u044b\u0439 docker daemon \u0438 \u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0436\u0438\u0432\u0443\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0430\u043a. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 docker daemon \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0432 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435.<\/p>\n<p>\u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c docker daemon \u0447\u0435\u0440\u0435\u0437 \u0442\u043e\u0442 \u0436\u0435 <code>docker.sock<\/code> \u0444\u0430\u0439\u043b \u2014 \u0442\u0430 \u0436\u0435 \u0441\u0430\u043c\u0430\u044f \u0431\u0440\u0435\u0448\u044c \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438. \u0422\u043e\u0442, \u043a\u0442\u043e \u0437\u0430\u0431\u0440\u0430\u043b\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430, \u0441\u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u044c \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (<a href=\"https:\/\/www.wiz.io\/academy\/container-security\/container-escape\" rel=\"noopener noreferrer nofollow\">container escape \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0430 \u0430\u043d\u0433.<\/a>). \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u043b\u043e\u0435\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 podman. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u044f \u043f\u0438\u0441\u0430\u043b \u0432 \u0441\u0442\u0430\u0442\u044c\u0435: <a href=\"https:\/\/habr.com\/ru\/articles\/1040300\/\" rel=\"noopener noreferrer nofollow\">\u201cRoot \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u2014 \u044d\u0442\u043e root \u043d\u0430 \u0445\u043e\u0441\u0442\u0435? \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u044e \u0432\u0430\u0436\u043d\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u0432 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445 Docker\/Podman\u201d<\/a><\/p>\n<hr\/>\n<h2>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u0431\u044b\u043b \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u043d\u043a\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u043d\u0435\u0440 \u043d\u0430 \u0441\u0432\u043e\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e runnera \u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0435\u0433\u043e \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u0430 \u0441 gitlab.com \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d, \u043d\u043e \u0442\u0430\u043a, \u0447\u0442\u043e \u0431\u044b \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b \u043d\u0430\u0448 self hosted runner. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0442\u0435\u0433 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432 \u0440\u0430\u043d\u043d\u0435\u0440\u0435. \u0412 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0442\u0435\u0433 <code>laptop-dc<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 <code>gitlab-ci.yml<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0442\u0435\u0433 \u0434\u043b\u044f \u0434\u0436\u043e\u0431\u043e\u0432.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/e4\/49\/41\/e449413720450b8e9dd8b97a0bbf3a33.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/e4\/49\/41\/e449413720450b8e9dd8b97a0bbf3a33.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/e4\/49\/41\/e449413720450b8e9dd8b97a0bbf3a33.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 <code>gitlab-ci.yml<\/code>, \u043a \u0431\u043b\u043e\u043a\u0443 <code>default<\/code>, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0441 docker daemon:<\/p>\n<pre><code class=\"yaml\">default:  image: docker:29.4-cli  services:    - docker:29.4-dind<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0447\u0442\u043e\u0431\u044b cli \u0438 dind \u0441\u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u0438\u043c\u0430\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c, \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f:<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0431\u043b\u043e\u043a\u043e\u043c <code>default<\/code>, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c 2 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435:<\/p>\n<pre><code class=\"yaml\">variables:  DOCKER_HOST: tcp:\/\/docker:2375  DOCKER_TLS_CERTDIR: \"\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<details class=\"spoiler\">\n<summary>\u0418\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f gitlab-ci.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">stages:  - build  - testvariables:  DOCKER_HOST: tcp:\/\/docker:2375  DOCKER_TLS_CERTDIR: \"\"default:  image: docker:29.5.3-cli  services:    - docker:29.5.3-dindbuild-image:  tags:    - laptop-dc  stage: build  script:    - IMAGE_TAG=$(date +%Y-%m-%d-%H-%M)    - echo \"\u0412\u0435\u0440\u0441\u0438\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 $IMAGE_TAG\"    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY    - docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .    - docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG    - docker tag $CI_REGISTRY_IMAGE:$IMAGE_TAG $CI_REGISTRY_IMAGE:latest    - docker push $CI_REGISTRY_IMAGE:latesttest-image:  tags:    - laptop-dc  stage: test  script:    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY    - docker run --rm $CI_REGISTRY_IMAGE:latest<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c Runner \u043a\u043e\u043d\u0444\u0438\u0433 (<code>config.toml<\/code>) \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430 dind \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0432 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c:<\/p>\n<pre><code>concurrent = 1check_interval = 0[[runners]]  name = \"laptop-dc\"  url = \"https:\/\/gitlab.com\/\"  token = \"\u0412\u0410\u0428_\u0422\u041e\u041a\u0415\u041d\"  executor = \"docker\"  [runners.docker]    image = \"alpine:3.22.4\"     privileged = true    tls_verify = false    disable_entrypoint_overwrite = false    oom_kill_disable = false    disable_cache = false    volumes = [\"\/cache\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u0430\u0432\u043a\u0430:<\/p>\n<pre><code>    privileged = true    tls_verify = false<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 gitlab runner \u0432 SELinux<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 ubuntu (\u043d\u0435 SELinux), \u0442\u043e \u0432\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u0442\u0430\u043a\u043e\u0439 volume: <code>\/var\/run\/docker.sock:\/var\/run\/docker.sock<\/code><\/p>\n<p>\u041d\u043e \u043c\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e gitlab runner \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 podman \u043d\u0430 fedora (SELinux). \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, <code>docker.sock<\/code> \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0432\u043e\u043b\u0443\u043c:<\/p>\n<pre><code> - \/run\/user\/1000\/podman\/podman.sock:\/var\/run\/docker.sock:z<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0413\u0434\u0435 1000 \u044d\u0442\u043e user id \u043f\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u0440\u0430\u043d\u043d\u0435\u0440\u043e\u043c (\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>id -u<\/code>).<\/p>\n<p>\u041d\u043e \u0438 \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0435\u0449\u0435 \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043d\u0430\u0447\u043d\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u0434\u0436\u043e\u0431\u043e\u0432:<\/p>\n<pre><code>ERROR: Preparation failed: getting docker info: permission denied while trying to connect to the Docker daemon socket at unix:\/\/\/var\/run\/docker.sock: Get \"http:\/\/%2Fvar%2Frun%2Fdocker.sock\/v1.51\/info\": dial unix \/var\/run\/docker.sock: connect: permission denied (docker.go:1218:0s)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e docker executor \u043e\u0442 gitlab-runner, \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0434\u0436\u043e\u0431\u0430. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u2014 \u043d\u0435\u0442 \u043f\u0440\u0430\u0432 \u043d\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0437\u0430\u043f\u0438\u0441\u0438 \u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0436\u0443\u0440\u043d\u0430\u043b\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u0430 SELinux.<\/p>\n<pre><code class=\"bash\">sudo ausearch -m avc<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0432\u044b\u0432\u043e\u0434\u0435 \u0432\u0438\u0434\u0438\u043c:<\/p>\n<pre><code>type=AVC msg=audit(1780685305.517:1634): avc:  denied  { connectto } for  pid=3001141 comm=\"gitlab-runner\" path=\"\/run\/user\/1000\/podman\/podman.sock\" scontext=system_u:system_r:container_t:s0:c635,c686 tcontext=unconfined_u:unconfined_r:container_runtime_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0440\u0435\u0436\u0438\u043c Permissive (\u0431\u0435\u0437 \u0437\u0430\u043f\u0440\u0435\u0442\u043e\u0432, \u043d\u043e \u0441 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439).<\/p>\n<pre><code class=\"bash\">gtosss@laptop-dc:~\/inf-config$ getenforceEnforcinggtosss@laptop-dc:~\/inf-config$ sudo setenforce 0gtosss@laptop-dc:~\/inf-config$ getenforcePermissive<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 UI gitlab \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d \u0438 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0440\u0435\u0448\u0438\u043b\u0430\u0441\u044c.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0432 Enforcing \u0440\u0435\u0436\u0438\u043c.<\/p>\n<p>\u042f \u0437\u0430\u043f\u0438\u0441\u0430\u043b \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u043e\u0442\u043a\u0430\u0437\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0432 <code>sudo ausearch -m avc<\/code>, \u0432 \u0444\u0430\u0439\u043b <code>audit.log<\/code>.<\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043f\u043e\u043b\u0438\u0442\u0438\u043a \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f:<\/p>\n<pre><code class=\"bash\">sudo yum install selinux-policy-devel<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443:<\/p>\n<pre><code>audit2allow -i audit.log -R &gt; gitlab_runner_connect_for_dind.te<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code>require {        type container_t;}#============= container_t ==============container_stream_connect(container_t)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<details class=\"spoiler\">\n<summary>\u041a\u0430\u043a \u0443\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 container_stream_connect<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430 <code>macro-expander<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f <code>container_stream_connect<\/code>:<\/p>\n<pre><code class=\"bash\">macro-expander \"container_stream_connect(container_t)\" &gt; macros_output.te<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u0444\u0430\u0439\u043b\u0435 <code>macros_output.te<\/code> \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441\u043e \u0432\u0441\u0435\u043c\u0438 allow \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438.<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c:<\/p>\n<pre><code>policy_module(gitlab_runner_connect_for_dind, 1.0)require {        type container_t;}#============= container_t ==============container_stream_connect(container_t)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0447\u0435\u0440\u0435\u0437 <code>make<\/code>:<\/p>\n<pre><code class=\"bash\">make -f \/usr\/share\/selinux\/devel\/Makefile gitlab_runner_connect_for_dind.pp<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c:<\/p>\n<pre><code class=\"bash\">sudo semodule -i gitlab_runner_connect_for_dind.pp<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d:<\/p>\n<pre><code class=\"bash\">sudo semodule -l | grep gitlab_runner_connect_for_dind<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c:<\/p>\n<pre><code class=\"bash\">sudo setenforce 1<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d \u0438 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<h2>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443<\/h2>\n<p>\u042f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d 2 \u0440\u0430\u0437\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043e\u0436\u0438\u0434\u0430\u044e 3 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432 Gitlab Container Registry: 2 \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0442\u0435\u0433\u043e\u043c \u0438 1 \u0441 \u0442\u0435\u0433\u043e\u043c <code>latest<\/code>.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/53\/4c\/9d\/534c9d8294e9c52dc06b4d75ec83b7fc.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/53\/4c\/9d\/534c9d8294e9c52dc06b4d75ec83b7fc.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/53\/4c\/9d\/534c9d8294e9c52dc06b4d75ec83b7fc.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0437 \u0433\u0434\u0435 \u0443\u0433\u043e\u0434\u043d\u043e, \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0442\u044c \u043a\u043b\u0438\u043a\u043e\u043c \u043f\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0438\u043a\u043e\u043d\u043a\u0435.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/80\/f6\/88\/80f688983312872899a5b8ec5518211a.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/80\/f6\/88\/80f688983312872899a5b8ec5518211a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/80\/f6\/88\/80f688983312872899a5b8ec5518211a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u0443\u0442\u044c \u043a \u043c\u043e\u0435\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>registry.gitlab.com\/webstap\/self-server-config:2026-06-05-22-07<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0417\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430 \u043f\u0440\u043e\u0434-\u0441\u0435\u0440\u0432\u0435\u0440\u0435<\/h2>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 bash \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 gitlab docker registry, \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e <code>docker-login-gitlab-registry.bash<\/code>:<\/p>\n<pre><code class=\"bash\">#!\/usr\/bin\/env bashecho \"$CI_DEPLOY_PASSWORD\" | docker login $CI_REGISTRY -u $CI_DEPLOY_USER --password-stdin<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0432 UI Gitlab.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/5a\/fe\/a1\/5afea1f5621588c4ff1c9d74bb84311e.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/5a\/fe\/a1\/5afea1f5621588c4ff1c9d74bb84311e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/5a\/fe\/a1\/5afea1f5621588c4ff1c9d74bb84311e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/da\/7e\/d5\/da7ed54eb19ddfec3136ecc152afa43e.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/da\/7e\/d5\/da7ed54eb19ddfec3136ecc152afa43e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/da\/7e\/d5\/da7ed54eb19ddfec3136ecc152afa43e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0430\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438 \u043f\u0430\u0440\u043e\u043b\u044c, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a registry, \u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0438\u0445 \u0432 \u0444\u0430\u0439\u043b <code>variables.sh<\/code>.<\/p>\n<pre><code class=\"bash\">export CI_REGISTRY=\"registry.gitlab.com\"export CI_DEPLOY_USER=\"&lt;\u041f\u041e\u041b\u0423\u0427\u0415\u041d\u041d\u042b\u0419_DEPLOY_USER&gt;\"export CI_DEPLOY_PASSWORD=\"\u041f\u041e\u041b\u0423\u0427\u0415\u041d\u041d\u042b\u0419_DEPLOY_PASSWORD\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0431\u0430 \u0444\u0430\u0439\u043b\u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>user-gitlab-registry<\/code>. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u044d\u0442\u0443 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0447\u0435\u0440\u0435\u0437 <code>cd<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code>source variables.sh<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 shell process. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c <code>docker-login-gitlab-registry.bash<\/code>:<\/p>\n<pre><code class=\"bash\">.\/docker-login-gitlab-registry.bash<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0431\u0443\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0437:<\/p>\n<pre><code class=\"bash\">docker run registry.gitlab.com\/webstap\/self-server-config:2026-06-05-22-07<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>$ docker run registry.gitlab.com\/webstap\/self-server-config:2026-06-05-22-07Unable to find image 'registry.gitlab.com\/webstap\/self-server-config:2026-06-05-22-07' locally2026-06-05-22-07: Pulling from webstap\/self-server-config11ab09ea930b: Pull complete a9b65603287c: Pull complete Digest: sha256:fecc87f73faf11a953caa6479490c8551727b49c0eff024d65080b1a36d87fc0Status: Downloaded newer image for registry.gitlab.com\/webstap\/self-server-config:2026-06-05-22-07Message from my-app.sh v1.0.0: Hello world!<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0447\u0442\u043e \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438!<\/p>\n<p>\u041a\u0442\u043e \u0443\u0436\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d \u043d\u0430 <a href=\"https:\/\/t.me\/gtosss_group\" rel=\"noopener noreferrer nofollow\">\u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u043a\u0430\u043d\u0430\u043b<\/a> \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u044c. \u041f\u043e\u043c\u0438\u043c\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u0438 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0432\u0430\u0436\u043d\u044b\u0435 \u0442\u0435\u043c\u044b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043f\u043e\u043b\u0435\u0437\u0435\u043d \u0438 \u0438\u0437\u043b\u043e\u0436\u0435\u043d \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c \u044f\u0437\u044b\u043a\u043e\u043c \u2014 \u043d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0439\u0442\u0435\u0441\u044c \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043b\u044e\u0441\u044b. \u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0444\u043e\u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439, \u0442\u0430\u043a \u0436\u0435 \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u0435\u043d\u044f.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421 \u0432\u0430\u043c\u0438 \u0431\u044b\u043b \u0422\u0438\u043c\u043e\u0444\u0435\u0439. \u041a\u0442\u043e \u044f?<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e \u0441 2015 \u0433\u043e\u0434\u0430. \u0421\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u043b \u043a\u0430\u043a front-end \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0430 React, \u043f\u043e\u0441\u043b\u0435 6-\u043b\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u043b\u0441\u044f \u043d\u0430 full-stack, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0433\u043e\u0434\u044b \u2014 \u0447\u0430\u0449\u0435 DevOps. \u041c\u043e\u0439 <a href=\"https:\/\/wakatime.com\/@gtoss\" rel=\"noopener noreferrer nofollow\">\u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 WakaTime<\/a>.<\/p>\n<\/div>\n<\/details>\n<hr\/>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1044570\/\">https:\/\/habr.com\/ru\/articles\/1044570\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0422\u0440\u0435\u0442\u044c\u044f \u0447\u0430\u0441\u0442\u044c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e CI\/CD \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 gitlab container registry.\u041e \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439\u0412\u0441\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043c\u043d\u043e\u0439 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0435 \u0433\u0430\u0439\u0434\u044b \u043d\u0435 \u0434\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u043c\u0443 \u0441\u0447\u0435\u0442\u0443 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435, \u043f\u0440\u0438\u0447\u0435\u043c \u043f\u043e\u0434 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u0438 \u043a\u0435\u0439\u0441: .net, Java, Node JS, etc.\u0426\u0435\u043b\u044c\u044e \u0441\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0442\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0438 \u0441\u0445\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0432\u0441\u0435 \u044d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e. \u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0432\u043e\u043e\u0440\u0443\u0436\u0438\u0442\u044c \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c, \u0447\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0435\u043c\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0435\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435. \u041f\u043e\u043c\u0438\u043c\u043e \u0441\u0430\u043c\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a \u0436\u0435 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0434\u043b\u044f \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 DevOps, \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439:\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 Gitlab (\u043e\u0431\u0449\u0438\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b \u0438 \u0434\u043b\u044f \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432).\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b: Bash, Docker, Kubernetes \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.\u041e\u0431\u0449\u0443\u044e \u0442\u0435\u043e\u0440\u0438\u044e \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0443 \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c\u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u043c\u0438.\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0441\u0442\u0430\u0434\u0438\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u0433\u0434\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c \u0440\u044b\u043d\u043e\u043a, \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0431\u0435\u0441\u043f\u0435\u0440\u0435\u0431\u043e\u0439\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c downtime, \u0440\u0430\u0437\u0433\u0440\u0443\u0437\u0438\u0442\u044c production \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442 \u043b\u0438\u0448\u043d\u0435\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u043d\u0446\u0438\u0434\u0435\u043d\u0442\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043b\u0438\u0437\u0430 \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043a\u0430\u0442\u0438\u0442\u044c\u0441\u044f.\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0440\u0430\u0437\u0431\u0438\u0442 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u0435\u0439.\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 GitLab CI\/CD: \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 pipeline\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 self-hosted gitlab runner (CI\/CD)[\u0412\u044b \u0437\u0434\u0435\u0441\u044c \u2192 ] \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 registry (GitLab CI\/CD)[todo] \u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 CI\/CD (\u0432\u044b\u0441\u043e\u043a\u043e-\u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d)\u041e\u0433\u043b\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0430\u043c\u0438 \u0438 registry \u0432 .gitlab-ci.ymlGitlab Container Registry\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 gitlab-ci.yml \u0414\u0436\u043e\u0431\u0430 build-image\u0414\u0436\u043e\u0431\u0430 test-image\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 gitlab runner \u0432 SELinux\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443\u0417\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430 \u043f\u0440\u043e\u0434-\u0441\u0435\u0440\u0432\u0435\u0440\u0435\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0430\u043c\u0438 \u0438 registry \u0432 .gitlab-ci.yml\u0420\u0430\u0441\u0448\u0438\u0440\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 .gitlab-ci.yml \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u0447\u0442\u043e \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 \u043e\u0431\u0440\u0430\u0437\u0430. \u041e\u0431\u0440\u0430\u0437\u0443 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 registry. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043d\u0430\u0448\u0438\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432 \u0432 \u043f\u0440\u043e\u0434\u0435 \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f. \u0415\u0449\u0435 \u043e\u0434\u043d\u0438\u043c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 production \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430 \u043f\u0440\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e.\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043c.\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u0432 \u0432\u0438\u0434\u0435 Docker \u043e\u0431\u0440\u0430\u0437\u0430 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0444\u0430\u0439\u043b. \u041d\u043e \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0434\u043b\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u0445 \u043c\u0435\u0436\u0434\u0443 \u0434\u0436\u043e\u0431\u0430\u043c\u0438. \u0415\u0441\u043b\u0438 \u043f\u043e\u0439\u0442\u0438 \u0442\u0430\u043a\u0438\u043c \u043f\u0443\u0442\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0442\u0430\u043a\u043e\u0435:build-image:  stage: build  script:    &#8212; docker build -t myapp:latest .    &#8212; docker save myapp:latest -o myapp.tar   # \u043e\u0431\u0440\u0430\u0437 \u2192 \u0444\u0430\u0439\u043b  artifacts:    paths:      &#8212; myapp.tar    expire_in: 2 weeks          # \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f 2 \u043d\u0435\u0434\u0435\u043b\u0438,                                 # \u0437\u0430\u0442\u0435\u043c \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u0441\u043e\u0440\u044f\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435Gitlab \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u043b\u044f Docker \u043e\u0431\u0437\u0430\u0440\u043e\u0432: GitLab Container Registry. \u0418\u043c\u0435\u043d\u043d\u043e \u0435\u0433\u043e \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.Gitlab Container Registry\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0432\u0438\u0434\u0435 bash \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c:my-app.sh#!\/bin\/bashecho &#171;Message from my-app.sh v1.0.0: Hello world!&#187;\u0418 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 Dockerfile \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:DockerfileFROM alpine:3.23# \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440COPY my-app.sh \/my-app.sh# \u0414\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043cRUN chmod +x \/my-app.sh# \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430CMD [&#171;\/my-app.sh&#187;]\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 gitlab-ci.yml\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0438\u0448\u0435\u043c .gitlab-ci.yml \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0434\u0432\u0443\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 stages. \u0422\u0430\u043a \u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0438\u0445 \u0440\u0435\u043b\u0438\u0437\u043e\u0432. \u041d\u043e \u043d\u0430\u0448\u0430 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0435 \u043f\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 semver, \u0442\u0430\u043a \u043a\u0430\u043a semver \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0434\u0430\u0442\u0443 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435: YYYY-MM-DD-HH-MM. \u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0443\u0434\u043e\u0431\u0435\u043d \u0442\u0435\u043c \u0447\u0442\u043e \u043e\u043d \u0441\u0440\u0430\u0437\u0443 \u0434\u0430\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043e \u0434\u0430\u0442\u0435 \u0440\u0435\u043b\u0438\u0437\u0430 \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u043f\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u0445\u0440\u043e\u043d\u043e\u043b\u043e\u0433\u0438\u044e.stages:  &#8212; build  &#8212; testdefault:  image: docker:29.4build-image:  stage: build  script:    &#8212; IMAGE_TAG=$(date +%Y-%m-%d-%H-%M)    &#8212; echo &#171;\u0412\u0435\u0440\u0441\u0438\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 $IMAGE_TAG&#187;    &#8212; docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY    &#8212; docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .    &#8212; docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG    &#8212; docker tag $CI_REGISTRY_IMAGE:$IMAGE_TAG $CI_REGISTRY_IMAGE:latest    &#8212; docker push $CI_REGISTRY_IMAGE:latesttest-image:  stage: test  script:    &#8212; docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY    &#8212; docker run &#8212;rm $CI_REGISTRY_IMAGE:latest\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438\u0437 script \u0414\u0436\u043e\u0431\u0430 build-imageIMAGE_TAG=$(date +%Y-%m-%d-%H-%M)\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e IMAGE_TAG, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0434\u0430\u0442\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 YYYY-MM-DD-HH-MM.$(&#8230;)\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043a\u043e\u0431\u043e\u043a \u0438 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0451 stdout \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.date +%Y-%m-%d-%H-%Mdate \u2014 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0423\u043c\u0435\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0432\u044b\u0432\u043e\u0434\u0430.  + \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0440\u0435\u043c\u044f, \u0430 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c, \u0434\u0430\u043b\u0435\u0435 \u0438\u0434\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f.  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u201c\u0442\u043e\u043a\u0435\u043d\u044b\u201d \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435:%Y \u2014 \u0433\u043e\u0434, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 2026%m \u2014 \u043c\u0435\u0441\u044f\u0446, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 04%d \u2014 \u0434\u0435\u043d\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 10%H \u2014 \u0447\u0430\u0441\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 15%M \u2014 \u043c\u0438\u043d\u0443\u0442\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 42\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u044b. echo &#171;\u0412\u0435\u0440\u0441\u0438\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 $IMAGE_TAG&#187;\u0412\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 $IMAGE_TAG, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0442\u0435\u0433\u0430.docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0432 Docker-\u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u0435\u0434\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 (predefined CI\/CD variables) \u0432 gitlab ci.  docker login \u2014 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 Docker registry  -u $CI_REGISTRY_USER \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f  -p $CI_REGISTRY_PASSWORD \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0430\u0440\u043e\u043b\u044c  $CI_REGISTRY \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u043e\u0433\u043e registry \u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 gitlab \u0441\u0430\u043c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442, \u043c\u044b \u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0438\u0442\u0430\u0435\u043c.docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .docker build -t &lt;&#8230;&gt; . \u2014 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0443 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 build context \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e (\u0442\u043e\u0447\u043a\u0430 . \u043d\u0430 \u043a\u043e\u043d\u0446\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e). Build context \u2014 \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0441\u0431\u043e\u0440\u043a\u0435. \u041c\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0441\u044e \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0443\u0436\u043d\u044b, \u0430 \u043a\u0430\u043a\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 .dockerignore (\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f).  -t $CI_REGISTRY_IMAGE:$IMAGE_TAG \u2014 \u0437\u0430\u0434\u0430\u0435\u0442 \u0442\u0435\u0433 \u043e\u0431\u0440\u0430\u0437\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0438\u043c\u044f:\u0442\u044d\u0433.  $CI_REGISTRY_IMAGE \u2014 \u0413\u0438\u0442\u043b\u0430\u0431 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442 \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 registry.gitlab.com\/mygroup\/myproject  $IMAGE_TAG \u2014 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 2026-04-10-15-42  \u0418\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435: registry.gitlab.com\/mygroup\/myproject:2026-04-10-15-42. docker tag $CI_REGISTRY_IMAGE:$IMAGE_TAG $CI_REGISTRY_IMAGE:latest\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430, \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0442\u0435\u0433 :latest. \u0415\u0441\u043b\u0438 \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: registry.gitlab.com\/mygroup\/myproject:2026-04-10-15-42, \u0442\u043e \u043c\u044b \u0434\u0430\u0435\u043c \u0435\u043c\u0443 \u0442\u0430\u043a \u0436\u0435 \u0438\u043c\u044f registry.gitlab.com\/mygroup\/myproject:latest.docker push $CI_REGISTRY_IMAGE:latest\u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0432 registry \u0442\u0430\u043a \u0436\u0435 \u043d\u0430\u0448 \u0442\u0435\u0433 latest. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432 registry \u0435\u0441\u0442\u044c 1 \u043e\u0431\u0440\u0430\u0437 \u0441 2 \u0438\u043c\u0435\u043d\u0430\u043c\u0438. \u041a\u043e\u0433\u0434\u0430 \u0434\u0436\u043e\u0431\u0430 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e, \u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0448\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c latest \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0443 \u0447\u0435\u0440\u0435\u0437 \u0442\u0435\u0433 latest. \u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e latest, \u043d\u043e \u044d\u0442\u043e \u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435\u0439\u043c\u0438\u043d\u0433\u0430 \u0434\u043e\u043a\u0435\u0440 \u043e\u0431\u0440\u0430\u0437\u043e\u0432.\u0414\u0436\u043e\u0431\u0430 test-imagedocker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\u0412 \u0434\u0436\u043e\u0431\u0435 test-image \u043c\u044b \u0441\u043d\u043e\u0432\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 registry, \u043a\u0430\u043a \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435 \u043d\u0430 \u0441\u0445\u0435\u043c\u0435 (\u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438\u043b\u0438 \u043d\u0438\u0436\u0435 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439), \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u0443\u044e \u0434\u0436\u043e\u0431\u0443 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440.docker run &#8212;rm $CI_REGISTRY_IMAGE:latestdocker run \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440  &#8212;rm \u2014 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0435\u0433\u043e  $CI_REGISTRY_IMAGE:latest \u2014 \u0441\u0441\u044b\u043b\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 latest \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0432\u0441\u0435 \u043b\u043e\u0433\u0438\u0447\u043d\u043e. \u041d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 shared runners \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.\u041d\u0430 \u0448\u0430\u0433\u0435 docker build \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443:$ docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG .ERROR: failed to connect to the docker API at tcp:\/\/docker:2375: lookup docker on 169.254.169.254:53: no such host\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c image: docker, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u043a\u0435\u0440, \u0430 \u043b\u0438\u0448\u044c \u0435\u0433\u043e cli \u043a\u043b\u0438\u0435\u043d\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a docker daemon. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043a\u0443 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a docker daemon \u043c\u044b \u0438 \u0432\u0438\u0434\u0438\u043c.Shared runner \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043d\u0430\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 docker daemon, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u043e\u0442\u043e\u0432 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0442 CLI-\u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e \u0447\u0442\u043e \u043e\u043d \u0435\u0441\u0442\u044c \u0438 \u043e\u043d \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043d\u0430\u0448\u0438 \u0434\u0436\u043e\u0431\u044b.\u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c docker-cli \u0432 \u043d\u0430\u0448\u0438\u0445 \u0434\u0436\u043e\u0431\u0430\u0445, \u0442\u043e \u043c\u044b \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u043c\u0443 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432:\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0443\u0442\u043e\u0432\u044b\u0439 docker daemon (\u043d\u0435 dind)\u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d docker daemon, \u043d\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0434\u043b\u044f \u0434\u0436\u043e\u0431 (dind)\u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d docker-cli \u0438 docker daemon. \u0415\u0441\u0442\u044c 2 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430:Docker daemon (dind, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u0440\u0430\u0437 docker:29-dind)Docker CLI (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u0440\u0430\u0437 docker:29-cli \u0438\u043b\u0438 \u0431\u0435\u0437 \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u0430 cli)\u0427\u0442\u043e\u0431\u044b CLI-\u043a\u043b\u0438\u0435\u043d\u0442, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u0443, \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u0442\u044c\u0441\u044f \u0441 docker daemon. \u0421\u0432\u044f\u0437\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f 2-\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438:ip + portdocker.sock \u0444\u0430\u0439\u043b (linux socket \u2014 \u044d\u0442\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 ip + port, \u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u0444\u0430\u0439\u043b\u0430)\u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u0432\u044f\u0437\u0438 (ip+port \u0438\u043b\u0438 docker.sock) \u0441 docker daemon, \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u043d\u0435\u0440\u0430, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 shared runner. \u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u043d\u0435\u0440\u0430, \u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0433\u043e executor \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439 self-hosted gitlab runner.\u041c\u043e\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 self-hosted gitlab runner.\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043f\u0443\u0442\u0435\u0439\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c kaniko \u2014 \u043e\u043d \u0431\u044b\u043b \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u043b \u043b\u0435\u0433\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0438\u043b\u0434 \u0431\u0435\u0437 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0430 docker. \u041f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 kaniko \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u043b\u0430\u0441\u044c (issue). \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u0435\u0433\u043e \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c.\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c buildah, \u0447\u0435\u043c-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 kaniko, \u043f\u0440\u0435\u043f\u043e\u0434\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0435\u0433\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430. \u041d\u043e \u043c\u0435\u043d\u044f \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u043e\u0436\u0435 \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442 \u2014 \u0441\u0443\u0434\u044f \u043f\u043e issues \u0435\u0441\u0442\u044c \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u043d\u0443\u0436\u0434\u0430\u044e\u0442 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c (\u0447\u0442\u043e&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-482701","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/482701","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=482701"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/482701\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=482701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=482701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=482701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}