{
    "version": "https:\/\/jsonfeed.org\/version\/1",
    "title": "Максим Кузнецов: заметки с тегом deploy",
    "_rss_description": "Простыми словами о веб-разработке",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/maxkuznetsov.ru\/tags\/deploy\/",
    "feed_url": "https:\/\/maxkuznetsov.ru\/tags\/deploy\/json\/",
    "icon": "https:\/\/maxkuznetsov.ru\/user\/userpic@2x.jpg?1586398004",
    "author": {
        "name": "Максим Кузнецов",
        "url": "https:\/\/maxkuznetsov.ru\/",
        "avatar": "https:\/\/maxkuznetsov.ru\/user\/userpic@2x.jpg?1586398004"
    },
    "items": [
        {
            "id": "48",
            "url": "https:\/\/maxkuznetsov.ru\/all\/kak-deploit-proekt-cherez-deployer\/",
            "title": "[Инструкция] Как деплоить проект через Deployer",
            "content_html": "<p>(Инструкция, которую приходится копировать из проекта в проект, поэтому пусть будет и в блоге.)<\/p>\n<p>Предполагается, что Deployer доступен уже в проекте, либо как файл `.\/dep`, либо как установленный composer пакет через `.\/vendor\/bin\/dep`. Он добавляется и хранится в гит-репозитории.<\/p>\n<p>Также важно настроить конфиги, указав хост в `.\/deploy.php`. Они также хранятся в репозитории.<\/p>\n<h2>Обычные \/ регулярные деплои<\/h2>\n<p>`.\/dep deploy <host>`, где в качестве <host> можно выбрать любой хост из deploy.php файла. В этом файле у хоста указана нужная ветка. Однако, делать это обычно не нужно, так как на проекте настрое Gitlab CI (см файл `.gitlab-ci.yaml`), который зарелизит код по коммиту.<\/p>\n<h2>Как сменить деплой-ветку для хоста<\/h2>\n<p>Предположим, вы хотите сменить на `dev` ветку с `develop` на `feature\/TASK-82-history-mypractice`.<\/p>\n<h3>Простой и быстрый вариант для быстрых тестов<\/h3>\n<p>Вы можете это сделать, поменяв `→set(’branch’, ’feature\/TASK-82-history-mypractice’)` в deploy.php для хоста `dev`, а потом запустить `.\/dep deploy dev`.<\/p>\n<p>Этот способ хорош, если хочется быстро показать ветку, и мы не ожидаем, что будет много фиксов, так как Gitlab CI всё ещё останется настроен на `develop` ветку. И поэтому:<\/p>\n<ul>\n<li>при коммите в `develop` ветку, Gitlab CI запустит `.\/dep deploy dev` и задеплоит `feature\/TASK-82-history-mypractice` на `dev`. Но это неправильно, так как мы не хотим деплоить эту ветку на дев по коммиту в `develop`, мы хотим деплоить по коммиту в ветку `feature\/TASK-82-history-mypractice`<\/li>\n<li>при коммите в `feature\/TASK-82-history-mypractice` ветку CI ничего не сделает, так как в версии конфига `.gitlab-ci.yaml` из этой ветки нет никакого правила для ветки `feature\/TASK-82-history-mypractice`.<\/li>\n<\/ul>\n<h3>Правильный вариант с обновлением Gitlab CI правил<\/h3>\n<ol start=\"1\">\n<li>Переключиться в `develop` ветку, изменить branch в deploy.php для нужного хоста и в `.gitlab-ci.yaml` изменить параметр `only:` для этого же хоста.<\/li>\n<li>Закоммитить. CI теперь не запустит деплой на `dev`, так как мы поменяли ветку на `feature\/TASK-82-history-mypractice`.<\/li>\n<li>Переключиться в ветку `feature\/TASK-82-history-mypractice` в git и вмерджить в неё свежий `develop`. Вместе с develop придут изменения для `deploy.php` и `.gitlab-ci.yaml`. Поэтому если сразу закоммитить вмёрдженное, то Gitlab CI запустит деплой feature-ветки на `dev`.<\/li>\n<li>Важно! Перед мерджем ветки в `develop` нужно изменить `deploy.php` и `.gitlab-ci.yaml` и заменить feature-ветку в них обратно на `develop`. Потом смерджить и Gitlab CI, увидев этот коммит в develop, сразу продеплоит `develop` на `dev`.<\/li>\n<\/ol>\n<h3>Как переключить хост с feature1-ветки на другую feature-2 ветку:<\/h3>\n<ol start=\"1\">\n<li>Переключиться в develop ветку и изменить в ней `deploy.php` и `.gitlab-ci.yaml`, указав feature2 вместо feature1 для нужного хоста.<\/li>\n<li>Вмерджить develop ветку сначала в feature1 ветку, потом в feature2 ветку.<\/li>\n<\/ol>\n<h2>Удобные команды<\/h2>\n<ol start=\"1\">\n<li>`.\/dep ssh <host>` — команда подключится к хосту по конфигу из deploy.php и сделает перейдёт в папку current релиза.<\/li>\n<li>`.\/dep run «<command>»` — запускает команду на удалённых серверах. После запуска она спросит на каких серверах запустить.<\/li>\n<li>`.\/dep <task> <host>` — запускает любую определённую в deploy.php `task(’<name>’, <callback>)` на нужно сервере.<\/li>\n<li>Можно указать «теги» для серверов и запускать всё выше написанное сразу пачками.<\/li>\n<\/ol>\n<h2>Первый деплой \/ создание окружения<\/h2>\n<ol start=\"1\">\n<li>`.\/dep deploy develop2` — первый раз закончится с ошибкой, но Deployer создаст структуру файлов по пути из deploy.php для develop2. Он создаст папки\n<ol start=\"1\">\n  <li>`\/var\/www\/dev.project.name\/releases` — тут будут располагаться папки с каждым новым релизом и копиться последние N штук.<\/li>\n  <li>`\/var\/www\/dev.project.name\/shared` — тут хранятся файлы, которые должны быть сохранены и перенесены между релизами. Например, логи, web\/assets, storage, etc. Эти папки задаются в deploy.php как shared_folder и shared_files. Во время деплоя эти папки будут заменены на симлинки из shared папки.<\/li>\n  <li>`\/var\/www\/dev.project.name\/current` — симлинк на последний успешный релиз из папки releases.<\/li>\n<\/ol>\n<\/li>\n<li>После создания структуры нужно перенести\/создать файлы в shared:\n<ol start=\"1\">\n  <li>`.\/shared\/.env`<\/li>\n  <li>`.\/shared\/web\/XXXXXXX` — можно посмотреть, какие папки создадутся на сервере, либо какие папки указаны в shared_folder в deploy.php (с учётом тех, что указаны во фреймворк-специфичном recipe, подключённом в deploy.php).<\/li>\n<\/ol>\n<\/li>\n<li>Повторить деплой `.\/dep deploy develop2`<\/li>\n<li>Также нужно залить данные в БД \/ импортнуть из sql дампа по параметрам из `.env`.<\/li>\n<\/ol>\n",
            "date_published": "2025-07-15T10:54:36+03:00",
            "date_modified": "2025-07-15T10:56:42+03:00",
            "_date_published_rfc2822": "Tue, 15 Jul 2025 10:54:36 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "48",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": []
            }
        },
        {
            "id": "38",
            "url": "https:\/\/maxkuznetsov.ru\/all\/deployment-users\/",
            "title": "Deployment: настраиваем пользователей",
            "content_html": "<h3>Проблема<\/h3>\n<p>Под <tt>root<\/tt>-пользователем работать небезопасно, равно как и делать весь проект доступным <tt>www-data<\/tt>.<br \/>\nКроме того, во многих веб-приложениях пользователи имеют возможность загружать свои файлы. И очень часто с такими файлами возникают конфликты, так как пишутся они под <tt>www-data:www-data<\/tt>, а деплоим под другим пользователем. Даже если деплоить под <tt>root<\/tt>, то скорее всего права на папку перепишутся и <tt>www-data<\/tt> потеряет доступ к нужным файлам.<\/p>\n<h3>Решение<\/h3>\n<p>Создать нового пользователя deploy с правами на коннект к серверу по ssh, доступом только к папке с проектом и возможностью изменять файлы в <tt>.\/public\/uploads<\/tt> и <tt>.\/var<\/tt>.<\/p>\n<p>Создаём на сервере пользователя <tt>deploy<\/tt> из-под <tt>root<\/tt>:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">ssh root@вашсервер\r\nuseradd --create-home -s \/bin\/bash deploy<\/code><\/pre><p>Настроим доступ по ssh через ключи<\/p>\n<pre class=\"e2-text-code\"><code class=\"bash\">mkdir \/home\/deploy\/.ssh\r\ntouch \/home\/deploy\/.ssh\/authorized_keys<\/code><\/pre><p>Вставьте содержимое одного из публичного ключа своего локального пользователя в файл <tt>authorized_keys<\/tt> и сохраните. Вывести публичный ключ локально можно командой: <tt>cat ~\/.ssh\/id_rsa.pub<\/tt> (название ключа <tt>id_rsa.pub<\/tt> у вас может отличаться).<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">vim \/home\/deploy\/.ssh\/authorized_keys<\/code><\/pre><p>Меняем права на более строгие<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">chown -R deploy:deploy \/home\/deploy\r\nchmod 600 \/home\/deploy\/.ssh\/authorized_keys<\/code><\/pre><p>Определим пользователя нашего веб-сервера (в примере ниже это <tt>www-data<\/tt>)<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">ps axo user,comm | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\\  -f1\r\n&gt; www-data<\/code><\/pre><p>Добавляем пользователя <tt>deploy<\/tt> в группу <tt>www-data<\/tt> (группа веб-сервера)<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">usermod -a -G www-data deploy<\/code><\/pre><p>Выставляем права на папку проекта<\/p>\n<pre class=\"e2-text-code\"><code class=\"bash\">chown -R deploy:deploy \/var\/www\/project\r\nchmod -R 0775 \/var\/www\/project<\/code><\/pre><p>Проверим, есть ли setfacl в системе <tt>setfacl -h<\/tt> и установим, если его нет. Команда для Ubuntu:<\/p>\n<pre class=\"e2-text-code\"><code class=\"bash\">sudo apt-get install acl<\/code><\/pre><p>Выдадим права на папки с кэшем, логами и загруженными пользовательскими файлами<\/p>\n<pre class=\"e2-text-code\"><code class=\"bash\">sudo setfacl -dR -m u:www-data:rwX -m u:deploy:rwX \/var\/www\/project\/var \/var\/www\/project\/public\/uploads\r\nsudo setfacl -R -m u:www-data:rwX -m u:deploy:rwX \/var\/www\/project\/var \/var\/www\/project\/public\/uploads<\/code><\/pre><p>Готово.<\/p>\n<p>Для самого деплоймента я обычно использую <a href=\"deployer.org\">Deployer<\/a> c параметром <tt>writable_mode=acl<\/tt>.<\/p>\n",
            "date_published": "2020-11-27T04:17:56+03:00",
            "date_modified": "2020-11-27T04:17:45+03:00",
            "_date_published_rfc2822": "Fri, 27 Nov 2020 04:17:56 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "38",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        }
    ],
    "_e2_version": 3559,
    "_e2_ua_string": "E2 (v3559; Aegea)"
}