{"id":334364,"date":"2022-06-11T21:00:10","date_gmt":"2022-06-11T21:00:10","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=334364"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=334364","title":{"rendered":"<span>Docker: \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0435\u0431 \u0441\u0435\u0440\u0432\u0435\u0440<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h3>\n<p>\u0422\u0430\u043a \u0441\u043b\u043e\u0436\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u0430\u0439\u0442\u043e\u0432, \u0437\u0430\u0434\u0430\u0447\u0438 \u0440\u0435\u0448\u0430\u0442\u044c \u0442\u0430\u043a \u0436\u0435 \u0440\u0430\u0437\u043d\u044b\u0435 &#8212; \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043e &#171;\u0441\u0432\u0435\u0440\u0441\u0442\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0443&#187;. \u0418 \u0432\u043e\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 php (8.1 \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f), \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 CMS (1C Bitrix), \u043d\u0443 \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c, &#171;\u0434\u043e\u0432\u0435\u0441\u0442\u0438 \u0434\u043e \u0443\u043c\u0430&#187;.<br \/>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442 \u043e\u0431\u0440\u043e\u0441 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u0441\u0430\u0439\u0442\u043e\u043c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e (\u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0438 \u043f\u043e\u043b\u043d\u044b\u0435 \u0431\u044d\u043a\u0430\u043f\u044b \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0432 \u043e\u0431\u043b\u0430\u043a\u043e, \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0432\u0430\u0440\u0435\u0439, \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430\u043c\u0438), \u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0435\u0434\u0443\u0442\u0441\u044f \u0432 3 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\u0445 (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0430 \u0438 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u0441\u0430\u0439\u0442), \u0442\u043e \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432\u0441\u044e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b Docker.<br \/>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0443\u0436\u0435 \u0443\u0441\u0442\u043e\u044f\u0432\u0448\u0430\u044f\u0441\u044f, \u0442\u043e \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043d\u0430\u0439\u0434\u0435\u0442\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u0435\u0440\u0432\u0435\u0440\u0430 &#171;\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438&#187;, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u043f\u043e\u0434 \u043d\u0430\u0448\u0438 \u043d\u0443\u0436\u0434\u044b. \u041d\u043e \u043f\u043e\u0438\u0441\u043a\u0430\u0432, \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f &#8212; \u0432\u0435\u0437\u0434\u0435 \u0431\u044b\u043b\u0438 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043d\u044e\u0430\u043d\u0441\u044b, \u0438\u0437-\u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u043b\u043e. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0431\u044b\u043b \u0441\u043e\u0431\u0440\u0430\u043d \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u0430 \u043d\u0430 1\u0421 \u0411\u0438\u0442\u0440\u0438\u043a\u0441. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0438\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u044b\u043b\u043e \u0432\u044b\u0440\u0435\u0437\u0430\u043d\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u044d\u0442\u043e\u0439 CMS \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/a-kryvenko\/docker-webserver\/\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/p>\n<h3>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/h3>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>\u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (MySQL);<\/p>\n<\/li>\n<li>\n<p>PHP;<\/p>\n<\/li>\n<li>\n<p>NGINX;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u043a\u0441\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u043e\u0447\u0442\u044b (msmtp);<\/p>\n<\/li>\n<li>\n<p>composer;<\/p>\n<\/li>\n<li>\n<p>letsencrypt \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e &#8212; \u043e\u0431\u043b\u0430\u043a\u043e \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0431\u044d\u043a\u0430\u043f\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f crontab \u043d\u0430 <strong>\u0445\u043e\u0441\u0442\u0435<\/strong>, \u0430 \u043d\u0435 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445.<\/p>\n<h3>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0440\u0430\u0431\u043e\u0442<\/h3>\n<p>\u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f docker-compose. \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/initial-server-setup-with-ubuntu-22-04\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430<\/a> \u0441\u0435\u0440\u0432\u0435\u0440\u0430;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-and-use-docker-on-ubuntu-22-04\" rel=\"noopener noreferrer nofollow\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/a> docker;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-wordpress-with-docker-compose\" rel=\"noopener noreferrer nofollow\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/a> docker-compose.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u044b \u043a smtp \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 s3 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u043b\u044f \u0431\u044d\u043a\u0430\u043f\u043e\u0432 (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e).<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 gmail smtp<\/summary>\n<div class=\"spoiler__content\">\n<p>Google <a href=\"https:\/\/support.google.com\/accounts\/answer\/6010255?hl=en\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u043e\u0431\u0449\u0438\u043b<\/a>, \u0447\u0442\u043e \u0441 \u0438\u044e\u043d\u044f 2022 \u0433\u043e\u0434\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043f\u0430\u0440\u043e\u043b\u044e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430). \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c gmail smtp, \u043d\u0430\u0434\u043e \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0430\u0439\u0442\u0430 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<\/div>\n<\/details>\n<h3>\u0421\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0414\u043b\u044f \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u043c 4 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430 compose.yml:<\/p>\n<ul>\n<li>\n<p>compose-app.yml &#8212; \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, php, nginx, composer);<\/p>\n<\/li>\n<li>\n<p>compose-https.yml &#8212; \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0430\u0439\u0442\u0430 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 https. \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f certbot, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441 http \u043d\u0430 https \u0434\u043b\u044f nginx;<\/p>\n<\/li>\n<li>\n<p>compose-cloud.yml &#8212; \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0431\u044d\u043a\u0430\u043f\u043e\u0432 \u0432 \u0445\u043e\u043b\u043e\u0434\u043d\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435;<\/p>\n<\/li>\n<li>\n<p>compose-production.yml &#8212; \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>compose-app.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   db:     image: mysql     container_name: database     restart: unless-stopped     tty: true     environment:       MYSQL_DATABASE: ${DB_DATABASE}       MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}       MYSQL_USER: ${DB_USER}       MYSQL_PASSWORD: ${DB_USER_PASSWORD}     volumes:       - .\/.backups:\/var\/www\/.backups       - .\/.docker\/mysql\/my.cnf:\/etc\/mysql\/my.cnf       - database:\/var\/lib\/mysql     networks:       - backend    app:     image: php:8.1-fpm     container_name: application     build:       context: .       dockerfile: Dockerfile       args:         GID: ${SYSTEM_GROUP_ID}         UID: ${SYSTEM_USER_ID}         SMTP_HOST: ${MAIL_SMTP_HOST}         SMTP_PORT: ${MAIL_SMTP_PORT}         SMTP_EMAIL: ${MAIL_SMTP_USER}         SMTP_PASSWORD: ${MAIL_SMTP_PASSWORD}     restart: unless-stopped     tty: true     working_dir: \/var\/www\/app     volumes:       - .\/app:\/var\/www\/app       - .\/log:\/var\/www\/log       - .\/.docker\/php\/local.ini:\/usr\/local\/etc\/php\/conf.d\/local.ini     networks:       - backend     links:       - \"webserver:${APP_NAME}\"    composer:     build:       context: .     image: composer     container_name: composer     working_dir: \/var\/www\/app     command: \"composer install\"     restart: \"no\"     depends_on:       - app     volumes:       - .\/app:\/var\/www\/app    webserver:     image: nginx:stable-alpine     container_name: webserver     restart: unless-stopped     tty: true     ports:       - \"80:80\"       - \"443:443\"     volumes:       - .\/app\/public:\/var\/www\/app\/public       - .\/log:\/var\/www\/log       - .\/.docker\/nginx\/default.conf:\/etc\/nginx\/includes\/default.conf       - .\/.docker\/nginx\/templates\/http.conf.template:\/etc\/nginx\/templates\/website.conf.template     environment:       - APP_NAME=${APP_NAME}     networks:       - frontend       - backend  networks:   frontend:     driver: bridge   backend:     driver: bridge  volumes:   database: <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>compose-https.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   webserver:     volumes:       - .\/.docker\/certbot\/conf:\/etc\/letsencrypt       - .\/.docker\/certbot\/www:\/var\/www\/.docker\/certbot\/www       - .\/.docker\/nginx\/templates\/https.conf.template:\/etc\/nginx\/templates\/website.conf.template    certbot:     image: certbot\/certbot     container_name: certbot     restart: \"no\"     volumes:       - .\/log\/letsencrypt:\/var\/www\/log\/letsencrypt       - .\/.docker\/certbot\/conf:\/etc\/letsencrypt       - .\/.docker\/certbot\/www:\/var\/www\/.docker\/certbot\/www <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>compose-cloud.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   cloudStorage:     image: efrecon\/s3fs     container_name: cloudStorage     restart: unless-stopped     cap_add:       - SYS_ADMIN     security_opt:       - 'apparmor:unconfined'     devices:       - \/dev\/fuse     environment:       AWS_S3_BUCKET: ${AWS_S3_BUCKET}       AWS_S3_ACCESS_KEY_ID: ${AWS_S3_ACCESS_KEY_ID}       AWS_S3_SECRET_ACCESS_KEY: ${AWS_S3_SECRET_ACCESS_KEY}       AWS_S3_URL: ${AWS_S3_URL}       AWS_S3_MOUNT: '\/opt\/s3fs\/bucket'       S3FS_ARGS: -o use_path_request_style       GID: ${SYSTEM_GROUP_ID}       UID: ${SYSTEM_USER_ID}     volumes:       - ${AWS_S3_LOCAL_MOUNT_POINT}:\/opt\/s3fs\/bucket:rshared <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>compose-production.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   db:     restart: always    app:     restart: always    webserver:     restart: always    cloudStorage:     restart: always<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <em>.env<\/em><\/p>\n<details class=\"spoiler\">\n<summary>.env<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">COMPOSE_FILE=compose-app.yml:compose-cloud.yml:compose-https.yml:compose-production.yml SYSTEM_GROUP_ID=1000 SYSTEM_USER_ID=1000  APP_NAME=example.local ADMINISTRATOR_EMAIL=example@gmail.com  DB_HOST=db DB_DATABASE=example_db DB_USER=example DB_USER_PASSWORD=example DB_ROOT_PASSWORD=example  AWS_S3_URL=http:\/\/storage.example.net AWS_S3_BUCKET=storage AWS_S3_ACCESS_KEY_ID=#YOU_KEY# AWS_S3_SECRET_ACCESS_KEY=#YOU_KEY_SECRET# AWS_S3_LOCAL_MOUNT_POINT=\/mnt\/s3backups  MAIL_SMTP_HOST=smtp.gmail.com MAIL_SMTP_PORT=587 MAIL_SMTP_USER=example@gmail.com MAIL_SMTP_PASSWORD=example <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043d\u0443\u0436\u0435\u043d \u043d\u0430\u043c \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 &#8212; \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c  \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <strong>COMPOSE_FILE<\/strong> \u043d\u0430\u0431\u043e\u0440 compose-*.yml \u0444\u0430\u0439\u043b\u043e\u0432<\/p>\n<p>\u0412 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <em>.docker\/<\/em> \u0445\u0440\u0430\u043d\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0422\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c 2 \u0438\u0437 \u043d\u0438\u0445:<\/p>\n<ul>\n<li>\n<p>\u0414\u043b\u044f nginx \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 <em>.docker\/nginx\/default.conf<\/em> \u0438 \u0434\u0432\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 (<em>.docker\/nginx\/templates\/http.conf.template<\/em> \u0438 <em>.docker\/nginx\/templates\/https.conf.template<\/em>). \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c &#8212; \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 nginx. \u041e \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043e\u0431\u0440\u0430\u0437\u0430 <a href=\"https:\/\/hub.docker.com\/_\/nginx\" rel=\"noopener noreferrer nofollow\">nginx<\/a>;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f msmtp \u0432 \u0444\u0430\u0439\u043b\u0435 <em>.docker\/msmtp\/msmtp<\/em> \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043f\u043b\u0430\u0442\u043a\u0438 \u0432\u0438\u0434\u0430 <strong>#PASSWORD#<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u044b \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u043e\u0431\u0440\u0430\u0437\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>.docker\/msmtp\/msmtprc<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\"># Set default values for all following accounts. defaults auth           on tls            on logfile        \/var\/www\/log\/msmtp\/msmtp.log timeout 5  account        docker host           #HOST# port           #PORT# from           #EMAIL# user           #EMAIL# password       #PASSWORD#  # Set a default account account default : docker <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <em>Dockerfile<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0436\u0435\u043c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u0438, \u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u0434\u043b\u044f msmtp \u0437\u0430\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<details class=\"spoiler\">\n<summary>Dockerfile<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">FROM php:8.1-fpm  ARG GID ARG UID ARG SMTP_HOST ARG SMTP_PORT ARG SMTP_EMAIL ARG SMTP_PASSWORD  USER root  WORKDIR \/var\/www  RUN apt-get update -y \\     &amp;&amp; apt-get autoremove -y \\     &amp;&amp; apt-get -y --no-install-recommends \\     msmtp \\     zip \\     unzip \\     &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*  COPY .\/.docker\/msmtp\/msmtprc \/etc\/msmtprc  RUN sed -i \"s\/#HOST#\/$SMTP_HOST\/\" \/etc\/msmtprc \\         &amp;&amp; sed -i \"s\/#PORT#\/$SMTP_PORT\/\" \/etc\/msmtprc \\         &amp;&amp; sed -i \"s\/#EMAIL#\/$SMTP_EMAIL\/\" \/etc\/msmtprc \\         &amp;&amp; sed -i \"s\/#PASSWORD#\/$SMTP_PASSWORD\/\" \/etc\/msmtprc  COPY --from=composer \/usr\/bin\/composer \/usr\/bin\/composer  RUN getent group www || groupadd -g $GID www \\     &amp;&amp; getent passwd $UID || useradd -u $UID -m -s \/bin\/bash -g www www  USER www  EXPOSE 9000  CMD [\"php-fpm\"] <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>\u0411\u044d\u043a\u0430\u043f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0430\u0441\u0442\u0435\u0439: \u0430\u0440\u0445\u0438\u0432 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0438 \u0434\u0430\u043c\u043f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0425\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u043b\u0438\u0431\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u043a\u043e. \u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <em>cgi-bin\/create-backup.sh<\/em>.<br \/>\u0414\u043b\u044f \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f &#8212; <em>cgi-bin\/restore-backup.sh<\/em> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 &#8212; \u0442\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043c \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0438\u0437 \u043d\u0435\u0433\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>create-backup.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash  BASEDIR=$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\/..\/\" &amp;> \/dev\/null &amp;&amp; pwd)  source \"$BASEDIR\/.env\"  cd \"$BASEDIR\/\"  # If run script with --local, then don't send backup to remote storage moveToCloud=\"Y\" while [ $# -gt 0 ] ; do     case $1 in         --local) moveToCloud=\"N\";;     esac     shift done  # If backups storage is not mounted, then anyway store backups local if ! [[ $COMPOSE_FILE == *\"compose-cloud.yml\"* ]]; then     moveToCloud=\"N\" fi  # Current date, 2022-01-25_16-10 timestamp=`date +\"%Y-%m-%d_%H-%M\"` backups_local_folder=\"$BASEDIR\/.backups\/local\" backups_cloud_folder=\"$AWS_S3_LOCAL_MOUNT_POINT\"  # Creating local folder for backups mkdir -p \"$backups_local_folder\"  # Creating backup of application tar \\ --exclude='vendor' \\     -czvf $backups_local_folder\/\"$timestamp\"_app.tar.gz \\ -C $BASEDIR \"app\"  # Creating backup of database docker exec database sh -c \"exec mysqldump -u root -h $DB_HOST -p$DB_ROOT_PASSWORD $DB_DATABASE\" > $backups_local_folder\/\"$timestamp\"_database.sql gzip $backups_local_folder\/\"$timestamp\"_database.sql  # If required, then move current backup to cloud storage if [ $moveToCloud == \"Y\" ]; then     mv $backups_local_folder\/\"$timestamp\"_database.sql.gz $backups_cloud_folder\/\"$timestamp\"_database.sql.gz     mv $backups_local_folder\/\"$timestamp\"_app.tar.gz $backups_cloud_folder\/\"$timestamp\"_app.tar.gz fi  # If we already moved backup to cloud, then remove old backups (older than 30 days) from cloud storage if [ $moveToCloud == \"Y\" ]; then     \/usr\/bin\/find $backups_cloud_folder\/ -type f -mtime +30 -exec rm {} \\; fi <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>restore-backup.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash  BASEDIR=$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\/..\/\" &amp;> \/dev\/null &amp;&amp; pwd)  source \"$BASEDIR\/.env\"  cd \"$BASEDIR\/\"  backupsDestination=\"$BASEDIR\/.backups\/local\"  # If backups storage is mounted, ask, from where will restore backups if [[ $COMPOSE_FILE == *\"compose-cloud.yml\"* ]]; then     while true     do         reset         echo \"Select backups destination:\"         echo \"1. Local;\"         echo \"2. Cloud;\"         echo \"---------\"         echo \"0. Exit\"          read -r choice          case $choice in             \"0\")                 exit                 ;;             \"1\")                 break                 ;;             \"2\")                 backupsDestination=\"$AWS_S3_LOCAL_MOUNT_POINT\"                 break                 ;;             *)                 ;;         esac     done fi reset  # Select backup for restore echo \"Available backups:\" find \"$backupsDestination\"\/*.gz  -printf \"%f\\n\" echo \"------------\" echo \"Enter backup path:\"  read -i \"$backupsDestination\"\/ -e backup_name  if ! [ -f \"$backup_name\" ]; then     echo \"Wrong backup path.\"     exit 1 fi   backup_mode=\"unknown\" if [[ $backup_name == *\"app.tar.gz\"* ]]; then     backup_mode=\"app\" elif [[ $backup_name == *\"database.sql.gz\"* ]]; then     backup_mode=\"database\" fi  if [ $backup_mode == \"unknown\" ]; then     echo \"Unknown backup type\"     exit 1 fi  reset  if [ $backup_mode == \"app\" ]; then     mkdir -p \"$BASEDIR\"\/.backups\/tmp     cp \"$backup_name\" \"$BASEDIR\"\/.backups\/tmp\/app_tmp.tar.gz      tar -xvf \"$BASEDIR\"\/.backups\/tmp\/app_tmp.tar.gz -C \"$BASEDIR\"      rm -rf \"$BASEDIR\"\/.backups\/tmp fi  if [ $backup_mode == \"database\" ]; then     mkdir -p \"$BASEDIR\"\/.backups\/tmp     cp \"$backup_name\" \"$BASEDIR\"\/.backups\/tmp\/database_tmp.sql.gz      gunzip \"$BASEDIR\"\/.backups\/tmp\/database_tmp.sql.gz      if ! [ -f \"$BASEDIR\"\/.backups\/tmp\/database_tmp.sql ]; then         echo \"Error in database unpack process\"         exit 1     fi      docker-compose exec db bash -c \"exec mysql -u root -p$DB_ROOT_PASSWORD $DB_DATABASE &lt; \/var\/www\/.backups\/tmp\/database_tmp.sql\"      rm -rf \"$BASEDIR\"\/.backups\/tmp fi <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>Crontab<\/h3>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0445\u043e\u0441\u0442\u0430. \u0414\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b <em>cgi-bin\/prepare-crontab.sh<\/em>. \u0412 \u0445\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 <em>.crontab<\/em>, \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0432 \u043d\u0438\u0445 \u043f\u0443\u0442\u044c \u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e <strong>#APP_PATH#<\/strong> \u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439, \u0438 \u0432\u043d\u043e\u0441\u0438\u0442 \u0438\u0445 \u0432 crontab \u043d\u0430 \u0445\u043e\u0441\u0442\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>prepare-crontab.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash  BASEDIR=$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\/..\/\" &amp;> \/dev\/null &amp;&amp; pwd)  # Load environment variables source \"$BASEDIR\"\/.env  # Create temporary directory mkdir -p \"$BASEDIR\"\/.crontab_tmp\/  # Copy all crontab files to temporary directory cp \"$BASEDIR\"\/.crontab\/* \"$BASEDIR\"\/.crontab_tmp\/  # Set actual app path in crontab files find \"$BASEDIR\"\/.crontab_tmp\/ -name \"*.cron\" -exec sed -i \"s|#APP_PATH#|$BASEDIR|g\" {} +  # Set crontab if [[ $COMPOSE_FILE == *\"compose-https.yml\"* ]]; then     find \"$BASEDIR\"\/.crontab_tmp\/ -name '*.cron' -exec cat {} \\; | crontab - else     find \"$BASEDIR\"\/.crontab_tmp\/ -name '*.cron' -not -name 'certbot-renew.cron' -exec cat {} \\; | crontab - fi  # Remove temporary directory rm -rf \"$BASEDIR\"\/.crontab_tmp\/ <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>Certbot<\/h3>\n<p>\u0415\u0441\u043b\u0438 https \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043d\u0435 \u043d\u0443\u0436\u0435\u043d &#8212; \u0442\u043e \u044d\u0442\u043e\u0442 \u0448\u0430\u0433 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c.<br \/>\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f ssl \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c certbot. \u041d\u043e \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c &#8212; \u0434\u043b\u044f \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u044f \u0434\u043e\u043c\u0435\u043d\u043e\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c nginx, \u043d\u043e \u0431\u0435\u0437 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432 \u043e\u043d \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u043a\u043d\u0443\u0442\u044b\u0439 \u043a\u0440\u0443\u0433. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <em>cgi-bin\/prepare-certbot.sh<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 nginx, \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0438\u0445 \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 nginx.<br \/>\u0414\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0430\u0439\u043b <em>cgi-bin\/certbot-renew.sh<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e.<\/p>\n<details class=\"spoiler\">\n<summary>prepare-certbot.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash  BASEDIR=$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\/..\/\" &amp;> \/dev\/null &amp;&amp; pwd)  source \"$BASEDIR\/.env\"  cd \"$BASEDIR\/\"  if ! [ -x \"$(command -v docker-compose)\" ]; then   echo 'Error: docker-compose is not installed.' >&amp;2   exit 1 fi  domains=($APP_NAME www.$APP_NAME) rsa_key_size=4096 data_path=\"$BASEDIR\/.docker\/certbot\" email=$ADMINISTRATOR_EMAIL staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits  if [ -d \"$data_path\" ]; then   read -p \"Existing data found for $domains. Continue and replace existing certificate? (y\/N) \" decision   if [ \"$decision\" != \"Y\" ] &amp;&amp; [ \"$decision\" != \"y\" ]; then     exit   fi fi   if [ ! -e \"$data_path\/conf\/options-ssl-nginx.conf\" ] || [ ! -e \"$data_path\/conf\/ssl-dhparams.pem\" ]; then   echo \"### Downloading recommended TLS parameters ...\"   mkdir -p \"$data_path\/conf\"   curl -s https:\/\/raw.githubusercontent.com\/certbot\/certbot\/master\/certbot-nginx\/certbot_nginx\/_internal\/tls_configs\/options-ssl-nginx.conf > \"$data_path\/conf\/options-ssl-nginx.conf\"   curl -s https:\/\/raw.githubusercontent.com\/certbot\/certbot\/master\/certbot\/certbot\/ssl-dhparams.pem > \"$data_path\/conf\/ssl-dhparams.pem\"   echo fi  echo \"### Creating dummy certificate for $domains ...\" path=\"\/etc\/letsencrypt\/live\/$domains\" mkdir -p \"$data_path\/conf\/live\/$domains\" docker-compose run --rm --entrypoint \"\\   openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\\     -keyout '$path\/privkey.pem' \\     -out '$path\/fullchain.pem' \\     -subj '\/CN=localhost'\" certbot echo   echo \"### Starting nginx ...\" docker-compose up --force-recreate -d webserver echo  echo \"### Deleting dummy certificate for $domains ...\" docker-compose run --rm --entrypoint \"\\   rm -Rf \/etc\/letsencrypt\/live\/$domains &amp;&amp; \\   rm -Rf \/etc\/letsencrypt\/archive\/$domains &amp;&amp; \\   rm -Rf \/etc\/letsencrypt\/renewal\/$domains.conf\" certbot echo   echo \"### Requesting Let's Encrypt certificate for $domains ...\" domain_args=\"\" for domain in \"${domains[@]}\"; do   domain_args=\"$domain_args -d $domain\" done  case \"$email\" in   \"\") email_arg=\"--register-unsafely-without-email\" ;;   *) email_arg=\"--email $email\" ;; esac  if [ $staging != \"0\" ]; then staging_arg=\"--staging\"; fi  docker-compose run --rm --entrypoint \"\\   certbot certonly --webroot -w \/var\/www\/.docker\/certbot\/www \\     $staging_arg \\     $email_arg \\     $domain_args \\     --rsa-key-size $rsa_key_size \\     --agree-tos \\     --force-renewal\" certbot echo  echo \"### Reloading nginx ...\" docker-compose exec webserver nginx -s reload <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>certbot-renew.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash  BASEDIR=$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\/..\/\" &amp;> \/dev\/null &amp;&amp; pwd)  cd \"$BASEDIR\/\"  docker-compose run --rm certbot renew &amp;&amp; ocker-compose kill -s SIGHUP webserver docker system prune -af <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0441\u0430\u0439\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d, \u0438 \u0441 \u043d\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u041f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043d\u0430 <a href=\"https:\/\/github.com\/a-kryvenko\/docker-webserver\/\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \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\/post\/670938\/\"> https:\/\/habr.com\/ru\/post\/670938\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h3>\n<p>\u0422\u0430\u043a \u0441\u043b\u043e\u0436\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u0430\u0439\u0442\u043e\u0432, \u0437\u0430\u0434\u0430\u0447\u0438 \u0440\u0435\u0448\u0430\u0442\u044c \u0442\u0430\u043a \u0436\u0435 \u0440\u0430\u0437\u043d\u044b\u0435 &#8212; \u043e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043e &#171;\u0441\u0432\u0435\u0440\u0441\u0442\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0443&#187;. \u0418 \u0432\u043e\u0442 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u0434\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 php (8.1 \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f), \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 CMS (1C Bitrix), \u043d\u0443 \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c, &#171;\u0434\u043e\u0432\u0435\u0441\u0442\u0438 \u0434\u043e \u0443\u043c\u0430&#187;.<br \/>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442 \u043e\u0431\u0440\u043e\u0441 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u0441\u0430\u0439\u0442\u043e\u043c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e (\u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0438 \u043f\u043e\u043b\u043d\u044b\u0435 \u0431\u044d\u043a\u0430\u043f\u044b \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u0432 \u043e\u0431\u043b\u0430\u043a\u043e, \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0432\u0430\u0440\u0435\u0439, \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430\u043c\u0438), \u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0435\u0434\u0443\u0442\u0441\u044f \u0432 3 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\u0445 (\u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0430 \u0438 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u0441\u0430\u0439\u0442), \u0442\u043e \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432\u0441\u044e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b Docker.<br \/>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0443\u0436\u0435 \u0443\u0441\u0442\u043e\u044f\u0432\u0448\u0430\u044f\u0441\u044f, \u0442\u043e \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043d\u0430\u0439\u0434\u0435\u0442\u0441\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u0435\u0440\u0432\u0435\u0440\u0430 &#171;\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438&#187;, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u043f\u043e\u0434 \u043d\u0430\u0448\u0438 \u043d\u0443\u0436\u0434\u044b. \u041d\u043e \u043f\u043e\u0438\u0441\u043a\u0430\u0432, \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f &#8212; \u0432\u0435\u0437\u0434\u0435 \u0431\u044b\u043b\u0438 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043d\u044e\u0430\u043d\u0441\u044b, \u0438\u0437-\u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u043b\u043e. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0431\u044b\u043b \u0441\u043e\u0431\u0440\u0430\u043d \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u0430 \u043d\u0430 1\u0421 \u0411\u0438\u0442\u0440\u0438\u043a\u0441. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0438\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0431\u044b\u043b\u043e \u0432\u044b\u0440\u0435\u0437\u0430\u043d\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u044d\u0442\u043e\u0439 CMS \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/a-kryvenko\/docker-webserver\/\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/p>\n<h3>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/h3>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>\u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (MySQL);<\/p>\n<\/li>\n<li>\n<p>PHP;<\/p>\n<\/li>\n<li>\n<p>NGINX;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u043a\u0441\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u043e\u0447\u0442\u044b (msmtp);<\/p>\n<\/li>\n<li>\n<p>composer;<\/p>\n<\/li>\n<li>\n<p>letsencrypt \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e &#8212; \u043e\u0431\u043b\u0430\u043a\u043e \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0431\u044d\u043a\u0430\u043f\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f crontab \u043d\u0430 <strong>\u0445\u043e\u0441\u0442\u0435<\/strong>, \u0430 \u043d\u0435 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445.<\/p>\n<h3>\u041f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0440\u0430\u0431\u043e\u0442<\/h3>\n<p>\u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f docker-compose. \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/initial-server-setup-with-ubuntu-22-04\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430<\/a> \u0441\u0435\u0440\u0432\u0435\u0440\u0430;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-and-use-docker-on-ubuntu-22-04\" rel=\"noopener noreferrer nofollow\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/a> docker;<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-wordpress-with-docker-compose\" rel=\"noopener noreferrer nofollow\">\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/a> docker-compose.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u044b \u043a smtp \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 s3 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u043b\u044f \u0431\u044d\u043a\u0430\u043f\u043e\u0432 (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e).<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 gmail smtp<\/summary>\n<div class=\"spoiler__content\">\n<p>Google <a href=\"https:\/\/support.google.com\/accounts\/answer\/6010255?hl=en\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u043e\u0431\u0449\u0438\u043b<\/a>, \u0447\u0442\u043e \u0441 \u0438\u044e\u043d\u044f 2022 \u0433\u043e\u0434\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043f\u0430\u0440\u043e\u043b\u044e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430). \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c gmail smtp, \u043d\u0430\u0434\u043e \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u0432\u0443\u0445\u0444\u0430\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0430\u0439\u0442\u0430 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<\/div>\n<\/details>\n<h3>\u0421\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0414\u043b\u044f \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u043c 4 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430 compose.yml:<\/p>\n<ul>\n<li>\n<p>compose-app.yml &#8212; \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, php, nginx, composer);<\/p>\n<\/li>\n<li>\n<p>compose-https.yml &#8212; \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0430\u0439\u0442\u0430 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 https. \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f certbot, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441 http \u043d\u0430 https \u0434\u043b\u044f nginx;<\/p>\n<\/li>\n<li>\n<p>compose-cloud.yml &#8212; \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0431\u044d\u043a\u0430\u043f\u043e\u0432 \u0432 \u0445\u043e\u043b\u043e\u0434\u043d\u043e\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435;<\/p>\n<\/li>\n<li>\n<p>compose-production.yml &#8212; \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>compose-app.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   db:     image: mysql     container_name: database     restart: unless-stopped     tty: true     environment:       MYSQL_DATABASE: ${DB_DATABASE}       MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}       MYSQL_USER: ${DB_USER}       MYSQL_PASSWORD: ${DB_USER_PASSWORD}     volumes:       - .\/.backups:\/var\/www\/.backups       - .\/.docker\/mysql\/my.cnf:\/etc\/mysql\/my.cnf       - database:\/var\/lib\/mysql     networks:       - backend    app:     image: php:8.1-fpm     container_name: application     build:       context: .       dockerfile: Dockerfile       args:         GID: ${SYSTEM_GROUP_ID}         UID: ${SYSTEM_USER_ID}         SMTP_HOST: ${MAIL_SMTP_HOST}         SMTP_PORT: ${MAIL_SMTP_PORT}         SMTP_EMAIL: ${MAIL_SMTP_USER}         SMTP_PASSWORD: ${MAIL_SMTP_PASSWORD}     restart: unless-stopped     tty: true     working_dir: \/var\/www\/app     volumes:       - .\/app:\/var\/www\/app       - .\/log:\/var\/www\/log       - .\/.docker\/php\/local.ini:\/usr\/local\/etc\/php\/conf.d\/local.ini     networks:       - backend     links:       - \"webserver:${APP_NAME}\"    composer:     build:       context: .     image: composer     container_name: composer     working_dir: \/var\/www\/app     command: \"composer install\"     restart: \"no\"     depends_on:       - app     volumes:       - .\/app:\/var\/www\/app    webserver:     image: nginx:stable-alpine     container_name: webserver     restart: unless-stopped     tty: true     ports:       - \"80:80\"       - \"443:443\"     volumes:       - .\/app\/public:\/var\/www\/app\/public       - .\/log:\/var\/www\/log       - .\/.docker\/nginx\/default.conf:\/etc\/nginx\/includes\/default.conf       - .\/.docker\/nginx\/templates\/http.conf.template:\/etc\/nginx\/templates\/website.conf.template     environment:       - APP_NAME=${APP_NAME}     networks:       - frontend       - backend  networks:   frontend:     driver: bridge   backend:     driver: bridge  volumes:   database: <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>compose-https.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   webserver:     volumes:       - .\/.docker\/certbot\/conf:\/etc\/letsencrypt       - .\/.docker\/certbot\/www:\/var\/www\/.docker\/certbot\/www       - .\/.docker\/nginx\/templates\/https.conf.template:\/etc\/nginx\/templates\/website.conf.template    certbot:     image: certbot\/certbot     container_name: certbot     restart: \"no\"     volumes:       - .\/log\/letsencrypt:\/var\/www\/log\/letsencrypt       - .\/.docker\/certbot\/conf:\/etc\/letsencrypt       - .\/.docker\/certbot\/www:\/var\/www\/.docker\/certbot\/www <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>compose-cloud.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   cloudStorage:     image: efrecon\/s3fs     container_name: cloudStorage     restart: unless-stopped     cap_add:       - SYS_ADMIN     security_opt:       - 'apparmor:unconfined'     devices:       - \/dev\/fuse     environment:       AWS_S3_BUCKET: ${AWS_S3_BUCKET}       AWS_S3_ACCESS_KEY_ID: ${AWS_S3_ACCESS_KEY_ID}       AWS_S3_SECRET_ACCESS_KEY: ${AWS_S3_SECRET_ACCESS_KEY}       AWS_S3_URL: ${AWS_S3_URL}       AWS_S3_MOUNT: '\/opt\/s3fs\/bucket'       S3FS_ARGS: -o use_path_request_style       GID: ${SYSTEM_GROUP_ID}       UID: ${SYSTEM_USER_ID}     volumes:       - ${AWS_S3_LOCAL_MOUNT_POINT}:\/opt\/s3fs\/bucket:rshared <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>compose-production.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">version: '3' services:   db:     restart: always    app:     restart: always    webserver:     restart: always    cloudStorage:     restart: always<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <em>.env<\/em><\/p>\n<details class=\"spoiler\">\n<summary>.env<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">COMPOSE_FILE=compose-app.yml:compose-cloud.yml:compose-https.yml:compose-production.yml SYSTEM_GROUP_ID=1000 SYSTEM_USER_ID=1000  APP_NAME=example.local ADMINISTRATOR_EMAIL=example@gmail.com  DB_HOST=db DB_DATABASE=example_db DB_USER=example DB_USER_PASSWORD=example DB_ROOT_PASSWORD=example  AWS_S3_URL=http:\/\/storage.example.net AWS_S3_BUCKET=storage AWS_S3_ACCESS_KEY_ID=#YOU_KEY# AWS_S3_SECRET_ACCESS_KEY=#YOU_KEY_SECRET# AWS_S3_LOCAL_MOUNT_POINT=\/mnt\/s3backups  MAIL_SMTP_HOST=smtp.gmail.com MAIL_SMTP_PORT=587 MAIL_SMTP_USER=example@gmail.com MAIL_SMTP_PASSWORD=example <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043d\u0443\u0436\u0435\u043d \u043d\u0430\u043c \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 &#8212; \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c  \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <strong>COMPOSE_FILE<\/strong> \u043d\u0430\u0431\u043e\u0440 compose-*.yml \u0444\u0430\u0439\u043b\u043e\u0432<\/p>\n<p>\u0412 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <em>.docker\/<\/em> \u0445\u0440\u0430\u043d\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0422\u0443\u0442 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c 2 \u0438\u0437 \u043d\u0438\u0445:<\/p>\n<ul>\n<li>\n<p>\u0414\u043b\u044f nginx \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 <em>.docker\/nginx\/default.conf<\/em> \u0438 \u0434\u0432\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 (<em>.docker\/nginx\/templates\/http.conf.template<\/em> \u0438 <em>.docker\/nginx\/templates\/https.conf.template<\/em>). \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c &#8212; \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 nginx. \u041e \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043e\u0431\u0440\u0430\u0437\u0430 <a href=\"https:\/\/hub.docker.com\/_\/nginx\" rel=\"noopener noreferrer nofollow\">nginx<\/a>;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f msmtp \u0432 \u0444\u0430\u0439\u043b\u0435 <em>.docker\/msmtp\/msmtp<\/em> \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043f\u043b\u0430\u0442\u043a\u0438 \u0432\u0438\u0434\u0430 <strong>#PASSWORD#<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u044b \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u043e\u0431\u0440\u0430\u0437\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>.docker\/msmtp\/msmtprc<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\"># Set default values for all following accounts. defaults auth           on tls            on logfile        \/var\/www\/log\/msmtp\/msmtp.log timeout 5  account        docker host           #HOST# port           #PORT# from           #EMAIL# user           #EMAIL# password       #PASSWORD#  # Set a default account account default : docker <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <em>Dockerfile<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0436\u0435\u043c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u0438, \u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u0434\u043b\u044f msmtp \u0437\u0430\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f:<\/p>\n<details class=\"spoiler\">\n<summary>Dockerfile<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">FROM php:8.1-fpm  ARG GID ARG UID ARG SMTP_HOST ARG SMTP_PORT ARG SMTP_EMAIL ARG SMTP_PASSWORD  USER root  WORKDIR \/var\/www  RUN apt-get update -y \\     &amp;&amp; apt-get autoremove -y \\     &amp;&amp; apt-get -y --no-install-recommends \\     msmtp \\     zip \\     unzip \\     &amp;&amp; rm -rf \/var\/lib\/apt\/lists\/*  COPY .\/.docker\/msmtp\/msmtprc \/etc\/msmtprc  RUN sed -i \"s\/#HOST#\/$SMTP_HOST\/\" \/etc\/msmtprc \\         &amp;&amp; sed -i \"s\/#PORT#\/$SMTP_PORT\/\" \/etc\/msmtprc \\         &amp;&amp; sed -i \"s\/#EMAIL#\/$SMTP_EMAIL\/\" \/etc\/msmtprc \\         &amp;&amp; sed -i \"s\/#PASSWORD#\/$SMTP_PASSWORD\/\" \/etc\/msmtprc  COPY --from=composer \/usr\/bin\/composer \/usr\/bin\/composer  RUN getent group www || groupadd -g $GID www \\     &amp;&amp; getent passwd $UID || useradd -u $UID -m -s \/bin\/bash -g www www  USER www  EXPOSE 9000  CMD [\"php-fpm\"] <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>\u0411\u044d\u043a\u0430\u043f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0430\u0441\u0442\u0435\u0439: \u0430\u0440\u0445\u0438\u0432 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0438 \u0434\u0430\u043c\u043f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0425\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u043b\u0438\u0431\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u043a\u043e. \u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <em>cgi-bin\/create-backup.sh<\/em>.<br \/>\u0414\u043b\u044f \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f &#8212; <em>cgi-bin\/restore-backup.sh<\/em> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 &#8212; \u0442\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043c \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0438\u0437 \u043d\u0435\u0433\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>create-backup.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash  BASEDIR=$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\/..\/\" &amp;> \/dev\/null &amp;&amp; pwd)  source \"$BASEDIR\/.env\"  cd \"$BASEDIR\/\"  # If run script with --local, then don't send backup to remote storage moveToCloud=\"Y\" while [ $# -gt 0 ] ; do     case $1 in         --local) moveToCloud=\"N\";;     esac     shift done  # If backups storage is not mounted, then anyway store backups local if ! [[ $COMPOSE_FILE == *\"compose-cloud.yml\"* ]]; then     moveToCloud=\"N\" fi  # Current date, 2022-01-25_16-10 timestamp=`date +\"%Y-%m-%d_%H-%M\"` backups_local_folder=\"$BASEDIR\/.backups\/local\" backups_cloud_folder=\"$AWS_S3_LOCAL_MOUNT_POINT\"  # Creating local folder for backups mkdir -p \"$backups_local_folder\"  # Creating backup of application tar \\ --exclude='vendor' \\     -czvf $backups_local_folder\/\"$timestamp\"_app.tar.gz \\ -C $BASEDIR \"app\"  # Creating backup of database docker exec database sh -c \"exec mysqldump -u root -h $DB_HOST -p$DB_ROOT_PASSWORD $DB_DATABASE\" > $backups_local_folder\/\"$timestamp\"_database.sql gzip<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-334364","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334364","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=334364"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334364\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=334364"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=334364"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=334364"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}