Исходные данные

  • блог на hugo, исходник которго лежит на github
  • дроплет на DigitalOcean
  • веб сервер caddy

Задача: сделать так, чтобы при пуше на гитхаб, блог автоматически стягивался сервером, билдился и помещался в нужную директорию.

Настраиваем репозиторий

Сначала идем на гитхаб в настройки репа и добавляем вебхук. Роут выбираем произвольный, в моем слачае это /webhook, а полный адрес - https://rmuratov.ru/webhook. Также добавляем секрет, который нужен, чтобы сервер точно знал, что запрос пришел от гитхаба. Это произвольная строка, в моем случае 14 ASCII символов.

Настроенный на github вебхук

Есть еще опции, но я оставил все по умолчанию. После этого, когда в реп приедут изменеия, гитхаб отправит HTTP запрос на мой сервер.

Настраиваем веб сервер Caddy

Чтобы осуществить задуманное, серверу caddy нужен плагин http.git. Поскольку caddy - это один бинарник, доставить плагин в процессе не получится, надо изначально устанавливать с нужными плагинами.

Финальный Caddyfile:

rmuratov.ru {
    root /var/www/rmuratov.ru/
    gzip
    git github.com/rmuratov/rmuratov.ru {
        hook /webhook w0wSoCodeMuchSecurity
        hook_type github
        path ./github
        then hugo --destination=/var/www/rmuratov.ru/
        interval -1
    }
    tls blabla@example.com
    errors {
        404 404.html
        500 500.html
    }
    log stdout
}

Блок, который делает то, что нужно начинается с git.

На что обратить внимание:

  • git github.com/rmuratov/rmuratov.ru - адрес репозитория.
  • hook /webhook w0wSoCodeMuchSecurity
    • hook - встроенная директива
    • /webhook - это роут, на который принимается запрос от гитхаба
    • w0wSoCodeMuchSecurity - секрет, указанный при настройке хука на гитхабе. Если содержит спец. символы, надо взять в кавычки
  • hook_type github - тип репозитория. В доках написано, что определяется автоматически, но у меня почему-то не завелось, пришлось указать явно. Есть еще BitBucket и прочие.
  • path ./github - каталог, в который будет спуллен репозиторий.

Путь может быть абсолютным или относительным. Во втором случае путь указывается относительно пути, указанного в root для данного хоста. В моем случае, содержимое репозитория (не архив, не один каталог, а именно файлы и папки, находящиеся в репе) будет помещено в /var/www/rmuratov.ru/github.

При этом у caddy должны быть права на запись в эту директорию.

  • then hugo --destination=/var/www/rmuratov.ru/ - комнда, которая будет выполнена после успешного пулла, билд блога и помещение результата в root. Естественно, на сервере должен быть установен hugo.
  • interval -1 - интервал автоматических пуллов. -1 значит никогда. Зачем лишний раз дергать, если гитхаб сам сообщит, что есть изменения?

Получается так: корневой каталог хоста (он же сайт) - это /var/www/rmuratov.ru/. В нем есть файлик index.html для главной страницы сайта и все сопутствующие каталоги и файлы. Помимо прочего в этом же каталоге есть каталог github. В нем лежит репозитория git. При изменениях в гитхабе локальный репозиторий на моем сервере в папке github обновляется, затем в нем выполняется команда hugo --destination=/var/www/rmuratov.ru/, которая помещает сбилженные файлы на каталог выше относительно github, обновляя контент блога.