Error during parsing when using imports

I’m trying to set up my caddyfiles in a more reusable way, so I had a look at the documentation and saw that the import keyword is probably what I’m looking for.

Everything seemed to work fine until I introduced some proxy blocks into the file.
I don’t know if it’s the proxy blocks themselves that are causing the issue, or if this is just a problem with import in general, but as soon as I did that I got this error:

2017/09/22 08:53:29 foo.caddyfile:3 - Error during parsing: Unexpected ‘}’ because no matching opening brace

My folder structure looks like this:

caddy
  |__ 0.10.9
  |  |__ caddy.exe
  |  |__ ...
  |
  |__ conf
  |  |__ common.caddyfile
  |  |__ app.caddyfile
  |
  |__ sites
  |  |__ foo.caddyfile
  |
  |__ caddy.bat
  |__ Caddyfile

caddy.bat just contains a simple command to start the server:

%_caddy%\caddy.exe -conf l:\path\to\Caddyfile

Where %_caddy% is just a variable set to the directory of whichever version of Caddy I’m using; in this case 0.10.9.

Caddyfile contains a line to import all files in sites:

import "sites/*"

common.caddyfile just has some directives in it that are common to all of my applications for local development:

tls self_signed

header / {
    X-XSS-Protection "1; mode=block"
    X-Content-Type-Options "nosniff"
    X-Frame-Options "DENY"
}

app.caddyfile contains some directives that are specific to that application:

import "common.caddyfile"

proxy / localhost:3001 {
    transparent
}

And then finally, I just import the application specific caddy file for the domain I want in the foo.caddyfile file:

https://local.foo.co.uk {
    import "../conf/app.caddyfile"
}

Doing this produces the error pasted in at the beginning of this post.
If however I move the proxy block out of app.caddyfile and into foo.caddyfile like this:

https://local.foo.co.uk {
    import "../conf/app.caddyfile"

    proxy / localhost:3001 {
        transparent
    }
}

Meaning the app.caddyfile now only contains the line import "common.caddyfile", the server will then start up without any errors.
Is this just a bug in Caddy itself or am I doing something wrong?

Hmm. I’m struggling to find anything wrong, per se…

How many sites are you running at the moment? I wonder if it would be feasible to test with a foo.caddyfile without a definition block, just to see what it does - i.e:

https://local.foo.co.uk
import "../conf/app.caddyfile"

I only have the one site running locally since this is a new setup for me.

Interestingly when I get rid of the block like you said it works fine with the proxy blocks being in app.caddyfile.

It also works if I put all of the proxy blocks in the app.caddyfile as it is in my original post, but then comment out the last curly brace, like this:

import "common.caddyfile"

proxy / localhost:3001 {
    transparent
# }

That seemed a bit more like a symptom rather than the actual problem though, so after a bit of playing around with the caddyfiles and trying out different combinations I’ve narrowed it down a little further.

This does seem strange to me because I have the exact same setup working correctly on an actual server with live sites on it.
The only real difference between the two is that on the live server I use a block for the tls directive to set the protocols. With exception to that small change in the tls directive becoming self_signed locally, the live server is running the exact same configuration as the one I posted in my original post.
It’s also serving multiple sites without problem.

Because of that I changed the foo.caddyfile on my local machine to explicitly start the site on port 80 like this:

http://local.foo.co.uk {
    import "../conf/app.caddyfile"
}

That allowed me to remove the tls directive from common.caddyfile entirely.
Doing this got rid of all errors and the site successfully started on port 80.
Adding the tls directive back in as tls off made the error reappear again.

So it seems like with this particular setup, if I use a block with actual settings in it for the tls directive then everything is fine, but if I try to use an empty block or just leave it without a block then it throws the parse error.

Having said that I don’t think this is a problem specific to the tls directive, since I also tried using the log directive without a block too and it made the server throw the same error again.

Because of that I wonder if this is a problem that appears when mixing blocks with no blocks in files being brought into other files with import?

1 Like

This looks like a bug. Could you file an issue on GitHub so we can keep track of it?

I’ve actually managed to narrow this down even further.
It now looks like it’s not an issue with directives with or without blocks at all anymore.

In my examples in my posts above I used placeholder names like foo and app, but if you were to try and reproduce the problem using the example I provided it would probably work fine.

Locally however I have files in different folders, but two of the files have the same name.
If I change one of their names to something different the whole thing then works.

So it looks like this is more of an issue with just the import directive rather than mixing blocks with non-blocks.

I’ll find a simple reproducible example and post an issue.

2 Likes

It looks like you’ve already solved the issue on GitHub.
I don’t want to clutter up the GitHub issues so I’ll just respond here.

I just wanted to say thanks for looking into it so quickly, and I look forward to whenever the next release will be :slight_smile:

2 Likes

:+1:

For reference, the now-closed issue:

https://github.com/mholt/caddy/issues/1892

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.