caddygit
caddygit copied to clipboard
Support for Caddyfile
Hey @rigon This looks pretty good. I’ll try it out once and merge it today! Thanks for the PR
Wow, that's awesome. Quite the PR! :smile:
I would be onboard with testing this! I am completely new to Caddy and I need this plugin to replace my existing setup on my Apache server.
Hey @joeworkman ! Definitely go for it :)
I am a super n00b with Caddy. How would I take the source to compile it into a custom Caddy build? I have used xcaddy. Although I learned that I need to get it installed on my linux server in order to get a custom build working on that server.
I am happy to test if you can help me figure out how to build it.
You don't need to install it on your Linux server in order to use a custom build there... Where did you learn that?
You can compile caddy from any machine, for any machine. Instructions are on this page: https://caddyserver.com/docs/build
I thought that I would need to use xcaddy to build this on my linux server. When I built a custom build on my Mac earlier today, it would not run on my server (you helped me with that).
Its 1am now though. I'll check back in the morning.
I thought that I would need to use xcaddy to build this on my linux server. When I built a custom build on my Mac earlier today, it would not run on my server (you helped me with that).
You can do what's called a cross-build on any machine, to build for a different OS/architecture. You just need to set the GOOS and GOARCH environment variables to the appropriate one for the target machine you're building for. (It's also how the https://caddyserver.com/download page works, you choose the OS/arch from the selection and the build server will make you a build for that platform)
Assuming your Linux server is x86 (not ARM) and 64-bit, then you would do:
GOOS=linux GOARCH=amd64 xcaddy build --with ...
Caddy works on almost every platform combination. There's a list of all the OSes and architectures Go supports here: https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63
I would love to test this today. How can I use xcaddy to build with the version from this PR?
I think this should work:
$ xcaddy build --with github.com/vrongmeal/caddygit=github.com/rigon/caddygit
@mholt Thanks. That got me close. That errored out saying that I needed a local directory. I clone the other repo and an built it like this...
xcaddy build --with github.com/vrongmeal/caddygit=./caddygit
I build caddy like this on my local Mac. Server is running Ubuntu.
GOOS=linux GOARCH=amd64 xcaddy build --with github.com/caddy-dns/cloudflare --with github.com/vrongmeal/caddygit/module/git=./caddygit
Here is my Caddyfile
{
email [email protected]
acme_dns cloudflare API_KEY_HERE
order git before file_server
}
aspecthq.com {
redir https://www.aspecthq.com{uri}
}
www.aspecthq.com {
git /update "https://gitlab.com/joeworkman/aspecthq.com" /var/www/aspecthq.com
root * /var/www/aspecthq.com
log {
output file /var/log/caddy/aspecthq.com/access.log {
roll_size 3MiB
roll_keep 5
roll_keep_for 48h
}
format console
}
encode gzip zstd
php_fastcgi unix//run/php/php8.1-fpm.sock
file_server
push
}
When I try to run caddy, I am getting the following error that the git directive is not registered.
adapting config using caddyfile: parsing caddyfile tokens for 'order': /etc/caddy/Caddyfile:13 - Error during parsing: git is not a registered directive
Make sure you run the binary you built, not another version.
Yes. I have verified that it's the server being used.

I don't know what that is, but it looks like there are two there that look the same.
That is from the update-alternatives command from the Caddy docs...
https://caddyserver.com/docs/build#package-support-files-for-custom-builds-for-debianubunturaspbian
It does mean that /usr/bin/caddy is pointing to my version that is compile with Cloudflare and Git modules.
Taking my server out of the mix...
- I built caddy just as above for my Mac
- I saved the above Caddyfile to my Mac
- Then I started the newly compiled caddy on my Mac pointing to that config file.
caddy run --config Caddyfile
Here is the error that it produces.
2022/01/10 23:40:37.377 INFO using provided configuration {"config_file": "Caddyfile", "config_adapter": ""}
run: adapting config using caddyfile: parsing caddyfile tokens for 'order': Caddyfile:4 - Error during parsing: git is not a registered directive
That's odd. And that's the only Caddy binary on your Mac? I'd feel more sure with a direct path like ./caddy instead of PATH usage, i.e. caddy.
If that's not it, I'm not sure... never seen that happen before. And you have verified the output of caddy list-modules?
It's not my only caddy binary. However, if I run it with ./ it's the same results.
The list-modules command does not list git.
admin.api.load
admin.api.metrics
admin.api.reverse_proxy
caddy.adapters.caddyfile
caddy.config_loaders.http
caddy.listeners.tls
caddy.logging.encoders.console
caddy.logging.encoders.filter
caddy.logging.encoders.filter.delete
caddy.logging.encoders.filter.ip_mask
caddy.logging.encoders.filter.replace
caddy.logging.encoders.json
caddy.logging.encoders.single_field
caddy.logging.writers.discard
caddy.logging.writers.file
caddy.logging.writers.net
caddy.logging.writers.stderr
caddy.logging.writers.stdout
caddy.storage.file_system
http
http.authentication.hashes.bcrypt
http.authentication.hashes.scrypt
http.authentication.providers.http_basic
http.encoders.gzip
http.encoders.zstd
http.handlers.acme_server
http.handlers.authentication
http.handlers.encode
http.handlers.error
http.handlers.file_server
http.handlers.headers
http.handlers.map
http.handlers.metrics
http.handlers.push
http.handlers.request_body
http.handlers.reverse_proxy
http.handlers.rewrite
http.handlers.static_response
http.handlers.subroute
http.handlers.templates
http.handlers.vars
http.matchers.expression
http.matchers.file
http.matchers.header
http.matchers.header_regexp
http.matchers.host
http.matchers.method
http.matchers.not
http.matchers.path
http.matchers.path_regexp
http.matchers.protocol
http.matchers.query
http.matchers.remote_ip
http.matchers.vars
http.matchers.vars_regexp
http.precompressed.br
http.precompressed.gzip
http.precompressed.zstd
http.reverse_proxy.selection_policies.cookie
http.reverse_proxy.selection_policies.first
http.reverse_proxy.selection_policies.header
http.reverse_proxy.selection_policies.ip_hash
http.reverse_proxy.selection_policies.least_conn
http.reverse_proxy.selection_policies.random
http.reverse_proxy.selection_policies.random_choose
http.reverse_proxy.selection_policies.round_robin
http.reverse_proxy.selection_policies.uri_hash
http.reverse_proxy.transport.fastcgi
http.reverse_proxy.transport.http
pki
tls
tls.certificates.automate
tls.certificates.load_files
tls.certificates.load_folders
tls.certificates.load_pem
tls.certificates.load_storage
tls.handshake_match.remote_ip
tls.handshake_match.sni
tls.issuance.acme
tls.issuance.internal
tls.issuance.zerossl
tls.stek.distributed
tls.stek.standard
Standard modules: 83
dns.providers.cloudflare
Non-standard modules: 1
Unknown modules: 0
Is this command correct?
xcaddy build --with github.com/caddy-dns/cloudflare --with github.com/vrongmeal/caddygit=./caddygit
Ah... no, it's not. After looking closely at the structure of this repo, it turns out the module registration is NOT in the root of this repository. My bad for assuming.
The module is registered in github.com/vrongmeal/caddygit/module/git: https://github.com/vrongmeal/caddygit/blob/main/module/git/app.go
That's a bit unusual, so I didn't think to check for it.
OK. This command works...
xcaddy build --with github.com/vrongmeal/caddygit/module/git
But this does not...
xcaddy build --with github.com/vrongmeal/caddygit/module/git=./caddygit
I need to reference the local folder since it contains this PR.
Try:
xcaddy build --with github.com/vrongmeal/caddygit/module/git=./caddygit/module/git
Edit: never mind...
github.com/vrongmeal/caddygit/module/git: module /Users/mohammed/caddygit/module/git: reading ../caddygit/module/git/go.mod: open /Users/mohammed/caddygit/module/git/go.mod: no such file or directory
The replace directive works on Go modules, not on packages, which is where the issue. We need to import github.com/vrongmeal/caddygit/module/git but replace github.com/vrongmeal/caddygit, which is tricky with xcaddy. Just a sec...
Got it. Try:
xcaddy build --with github.com/vrongmeal/caddygit/module/git --with github.com/vrongmeal/caddygit=./caddygit
This will underscore-import github.com/vrongmeal/caddygit/module/git and github.com/vrongmeal/caddygit (the latter of which is harmless), but replaces github.com/vrongmeal/caddygit with the local directory.
I build caddy like this on my local Mac. Server is running Ubuntu.
GOOS=linux GOARCH=amd64 xcaddy build --with github.com/caddy-dns/cloudflare --with github.com/vrongmeal/caddygit/module/git=./caddygitHere is my Caddyfile
{ email [email protected] acme_dns cloudflare API_KEY_HERE order git before file_server } aspecthq.com { redir https://www.aspecthq.com{uri} } www.aspecthq.com { git /update "https://gitlab.com/joeworkman/aspecthq.com" /var/www/aspecthq.com root * /var/www/aspecthq.com log { output file /var/log/caddy/aspecthq.com/access.log { roll_size 3MiB roll_keep 5 roll_keep_for 48h } format console } encode gzip zstd php_fastcgi unix//run/php/php8.1-fpm.sock file_server push }When I try to run caddy, I am getting the following error that the git directive is not registered.
adapting config using caddyfile: parsing caddyfile tokens for 'order': /etc/caddy/Caddyfile:13 - Error during parsing: git is not a registered directive
Adapter result (removing cloudflare):
{
"logging": {
"logs": {
"default": {
"exclude": [
"http.log.access.log0"
]
},
"log0": {
"writer": {
"filename": "/var/log/caddy/aspecthq.com/access.log",
"output": "file",
"roll_keep": 5,
"roll_keep_days": 2,
"roll_size_mb": 3
},
"encoder": {
"format": "console"
},
"include": [
"http.log.access.log0"
]
}
}
},
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"www.aspecthq.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "vars",
"root": "/var/www/aspecthq.com"
},
{
"encodings": {
"gzip": {},
"zstd": {}
},
"handler": "encode",
"prefer": [
"gzip",
"zstd"
]
},
{
"handler": "push"
}
]
},
{
"handle": [
{
"handler": "static_response",
"headers": {
"Location": [
"{http.request.uri.path}/"
]
},
"status_code": 308
}
],
"match": [
{
"file": {
"try_files": [
"{http.request.uri.path}/index.php"
]
},
"not": [
{
"path": [
"*/"
]
}
]
}
]
},
{
"handle": [
{
"handler": "rewrite",
"uri": "{http.matchers.file.relative}"
}
],
"match": [
{
"file": {
"split_path": [
".php"
],
"try_files": [
"{http.request.uri.path}",
"{http.request.uri.path}/index.php",
"index.php"
]
}
}
]
},
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"protocol": "fastcgi",
"split_path": [
".php"
]
},
"upstreams": [
{
"dial": "unix//run/php/php8.1-fpm.sock"
}
]
}
],
"match": [
{
"path": [
"*.php"
]
}
]
},
{
"handle": [
{
"commands_after": [
{}
],
"handler": "git",
"hook": null,
"repo": {
"path": "/var/www/aspecthq.com",
"url": "https://gitlab.com/joeworkman/aspecthq.com"
}
}
],
"match": [
{
"path": [
"/update"
]
}
]
},
{
"handle": [
{
"handler": "file_server",
"hide": [
"./Caddyfile"
]
}
]
}
]
}
],
"terminal": true
},
{
"match": [
{
"host": [
"aspecthq.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "static_response",
"headers": {
"Location": [
"https://www.aspecthq.com{http.request.uri}"
]
},
"status_code": 302
}
]
}
]
}
],
"terminal": true
}
],
"logs": {
"logger_names": {
"www.aspecthq.com": "log0"
},
"skip_hosts": [
"aspecthq.com"
]
}
}
}
},
"tls": {
"automation": {
"policies": [
{
"subjects": [
"www.aspecthq.com",
"aspecthq.com"
],
"issuers": [
{
"email": "[email protected]",
"module": "acme"
},
{
"email": "[email protected]",
"module": "zerossl"
}
]
}
]
}
}
}
}
That seems to have worked! I never would have guessed to try that.
Thanks @mohammed90.
@joeworkman It's a nuance of how Go modules does replacements, I guess.
@vrongmeal Most Caddy modules have their registrations in the root of the repo, that does simplify some things. Please consider that, if you would :)
So should this module not be using github.com/vrongmeal/caddygit/module/git? I assume that changing it to be github.com/vrongmeal/caddygit/ would break some backward compatibility? Or not since it's built into static binaries anyways.
I have been trying to figure out the configuration here. I tried to look through the code of the plugin to figure out what is going on. I am completely new to Caddy and Go so it's a bit of overload. Here is what I have so far...
www.aspecthq.com {
root * /var/www/aspecthq.com
encode gzip zstd
php_fastcgi unix//run/php/php8.1-fpm.sock
file_server
push
git /update {
url https://gitlab.com/joeworkman/aspecthq.com
path /var/www/aspecthq.com
branch master
}
}
I thought that this may mean that if you go to URL https://aspecthq.com/update that it would simply trigger a git pull. That is not happening. This site is currently on GitLab but can easily move it to Github if I need to.
I see this error in syslog
Jan 10 21:15:03 **** caddy[120153]: {"level":"error","ts":1641867303.8984256,"logger":"http.handlers.git","msg":"repository not setup","error":"cannot setup repository: worktree contains unstaged changes","path":"/var/www/aspecthq.com"}
It says that there are unstaged changes. However, there aren't any changes in /var/www/aspecthq.com