caddy-docker icon indicating copy to clipboard operation
caddy-docker copied to clipboard

"Not working" (lol)

Open STaRDoGG opened this issue 5 years ago • 8 comments

Anyone able to point out what I'm doing wrong? This is the first time I've ever built my own Docker image. (well, built it with abio's template).

After starting the container, I just can't connect to the site that I've setup for a reverse proxy.

Here's my slightly altered Dockerfile:

#
# Builder
#
FROM abiosoft/caddy:builder as builder

ARG version="0.11.5"
ARG *plugins="dyndns,service,authz,cache,cgi,cors,expires,filebrowser,filter,forwardproxy,geoip,git,gopkg,grpc,ipfilter,jwt,locale,login,mailout,minify,nobots,proxyprotocol,ratelimit,realip,reauth,upload,webdav,net,cloudflare"
*ARG enable_telemetry="false"

# process wrapper
RUN go get -v github.com/abiosoft/parent

RUN VERSION=${version} PLUGINS=${plugins} /bin/sh /usr/bin/builder.sh

#
# Final stage
#
FROM alpine:3.8
LABEL maintainer "Abiola Ibrahim <[email protected]>"

ARG version="0.11.5"
LABEL caddy_version="$version"

# PHP www-user UID and GID
ARG PUID="1000"
ARG PGID="1000"

# Let's Encrypt Agreement
*ENV ACME_AGREE="true"

*#CloudFlare
*ENV CLOUDFLARE_API_KEY="1234"
*ENV CLOUDFLARE_EMAIL="[email protected]"

RUN apk add --no-cache openssh-client git tar php7-fpm curl

# essential php libs
RUN apk add --no-cache \
  php7-bcmath \
  php7-ctype \
  php7-curl \
  php7-dom \
  php7-fileinfo \
  php7-gd \
  php7-iconv \
  php7-json \
  php7-mbstring \
  php7-mysqli \
  php7-openssl \
  php7-pdo \
  php7-pdo_mysql \
  php7-pgsql \
  php7-phar \
  php7-session \
  php7-sqlite3 \
  php7-tokenizer \
  php7-xml \
  php7-xmlreader \
  php7-xmlwriter \
  php7-zip

# symblink php7 to php
RUN ln -sf /usr/bin/php7 /usr/bin/php

# symlink php-fpm7 to php-fpm
RUN ln -sf /usr/bin/php-fpm7 /usr/bin/php-fpm

# add a php www-user instead of nobody
RUN addgroup -g ${PGID} www-user && \
  adduser -D -H -u ${PUID} -G www-user www-user && \
  sed -i "s|^user = .*|user = www-user|g" /etc/php7/php-fpm.d/www.conf && \
  sed -i "s|^group = .*|group = www-user|g" /etc/php7/php-fpm.d/www.conf

# composer
RUN curl --silent --show-error --fail --location \
  --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" \
  "https://getcomposer.org/installer" \
  | php -- --install-dir=/usr/bin --filename=composer

# allow environment variable access.
RUN echo "clear_env = no" >> /etc/php7/php-fpm.conf

# install caddy
COPY --from=builder /install/caddy /usr/bin/caddy

# validate install
RUN /usr/bin/caddy -version
RUN /usr/bin/caddy -plugins

*EXPOSE 80 443 2015 1234
VOLUME /root/.caddy /srv
WORKDIR /srv

COPY Caddyfile /etc/Caddyfile
*ADD index.php /srv/index.php
*ADD mitm.php /srv/mitm.php
*ADD phpinfo.php /srv/phpinfo.php
*ADD /css /srv/css

# install process wrapper
COPY --from=builder /go/bin/parent /bin/parent

ENTRYPOINT ["/bin/parent", "caddy"]
CMD ["--conf", "/etc/Caddyfile", "--log", "stdout", "--agree=$ACME_AGREE"]

It builds fine (docker build . -t myname/caddy). Then I run it with:

docker run -p 1234:1234-e CLOUDFLARE_API_KEY=23432432432432432432434 -e [email protected] -d --name caddy myname/caddy

It starts up fine, the main log shows:

Activating privacy features... 2019/04/20 08:52:07 [INFO][FileStorage:/root/.caddy] Started certificate maintenance routine

2019/04/20 08:52:07 [INFO] acme: Registering account for [email protected]

2019/04/20 08:52:07 [INFO] [my.domain.rocks] acme: Obtaining bundled SAN certificate

2019/04/20 08:52:08 [INFO] [my.domain.rocks] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/FzIlX6gfdhdfhdgfrhjNIEU-cD4PLtfX0xIcg

2019/04/20 08:52:08 [INFO] [my.domain.rocks] acme: Could not find solver for: tls-alpn-01

2019/04/20 08:52:08 [INFO] [my.domain.rocks] acme: Could not find solver for: http-01

2019/04/20 08:52:08 [INFO] [my.domain.rocks] acme: use dns-01 solver

2019/04/20 08:52:08 [INFO] [my.domain.rocks] acme: Preparing to solve DNS-01

2019/04/20 08:52:08 [INFO] cloudflare: new record for my.domain.rocks, ID 911ac603fe1427

2019/04/20 08:52:08 [INFO] [my.domain.rocks] acme: Trying to solve DNS-01

2019/04/20 08:52:08 [INFO] [my.domain.rocks] acme: Checking DNS record propagation using [10.0.2.3:53]

2019/04/20 08:52:08 [INFO] Wait for propagation [timeout: 2m0s, interval: 2s]

2019/04/20 08:52:09 [INFO] [my.domain.rocks] acme: Waiting for DNS record propagation.

2019/04/20 08:52:11 [INFO] [my.domain.rocks] acme: Waiting for DNS record propagation.

2019/04/20 08:52:18 [INFO] [my.domain.rocks] The server validated our request

2019/04/20 08:52:18 [INFO] [my.domain.rocks] acme: Cleaning DNS-01 challenge

2019/04/20 08:52:19 [INFO] [my.domain.rocks] acme: Validations succeeded; requesting certificates

2019/04/20 08:52:20 [INFO] [my.domain.rocks] Server responded with a certificate.

done.

Serving HTTPS on port 1234

https://my.domain.rocks:1234

2019/04/20 08:52:37 [INFO] Serving https://my.domain.rocks:1234 

Serving HTTP on port 80 

http://my.domain.rocks

2019/04/20 08:52:37 [INFO] Serving http://my.domain.rocks 

2019/04/20 08:52:37 [INFO] Nonblocking Command "php-fpm7 " with ID ce428524-4a26-4a75-a8e5-865a841ebc52

So then I try to load up https://my.domain.rocks:1234 and nothing. "ERR_CONNECTION_TIMED_OUT", "This site can’t be reached".

I SSH into the container and do:

/srv # curl -l 127.0.0.1:1234
Client sent an HTTP request to an HTTPS server.
/srv # curl 127.0.0.1:1234
Client sent an HTTP request to an HTTPS server.
/srv # curl https://my.domain.rocks:1234
curl: (7) Failed to connect to my.domain.rocks port 1234: Operation timed out

My Caddyfile in the container looks like this:

(CommonSettings) {

  ext .html .htm .php
  gzip

  header / {
    X-Content-Type-Options nosniff
    X-XSS-Protection "1; mode=block"
    # X-Frame-Options "allow-from https://my.domain.rocks"
    # X-Frame-Options "sameorigin"
    Strict-Transport-Security "max-age=31536000;"
  }

  timeouts 30s

  on startup php-fpm7 &
  fastcgi / localhost:9133 php

  # Render any found .md files as markdown
  markdown /
}

(Certs) {

 tls {
    dns cloudflare
  }

 # Email for Let's Encrypt Verification
  tls [email protected]
}

(ProxiesDockerized) {
  # < snipped all of these proxies for the sake of clarity >
}

(Security) {

  reauth {

    path /sonarr

    failure redirect target=my.domain.rocks:1234/Organizr/
    upstream url=my.domain.rocks:1234/Organizr/auth.php?admin,cookies=true
  }
}

(Caches) {
  push /Organizr {
  }
}

(Rewrites) {

  rewrite / {

    regexp ^/[^/]+$
    if {path} starts_with /nzbhydra
    if {path} starts_with /monitorr
    if {path} starts_with /organizr
    if {path} starts_with /portainer
    if_op or
    to {path}/
  }
}

(Redirects) {
    redir /pms https://app.plex.tv/desktop 301
}

(Filters) {
  # Snippet: Replacement Filters
  # Requires: http.filter

  # Add Dark CSS Theme to Deluge WebUI
  filter rule {
      path /delugedoc
      content_type text/html.*
      search_pattern "</head>"
      replacement "<link rel='stylesheet' type='text/css' href='https://stardogg.github.io/Deluge-Dark/deluge.css'>\n</head>"
  }

}

###########################
# Web Domain Server Block #
###########################

my.domain.rocks:1234 {

  root /srv

  templates {
    ext .php
  }

  log stdout
  errors stderr

  import CommonSettings
  import Certs
  import Filters
  import Rewrites
  import Redirects
  import ProxiesDockerized
}

Not really much of a Linux guru, and still pretty new to Docker, so not sure why it's not connecting. I use the same caddyfile minus the way that PHP is called, on a non-docker Caddy and it works fine, so it seems like it should be working, but doesn't.

STaRDoGG avatar Apr 20 '19 13:04 STaRDoGG

Since you're not changing anything other than plugins, why not just

export PLUGINS="dyndns,service,authz,cache,cgi,cors,expires,filebrowser,filter,forwardproxy,geoip,git,gopkg,grpc,ipfilter,jwt,locale,login,mailout,minify,nobots,proxyprotocol,ratelimit,realip,reauth,upload,webdav,net,cloudflare"
# build 
docker build --name myname/caddy --build-arg \
    plugins="$PLUGINS" \
    github.com/abiosoft/caddy-docker.git

abiosoft avatar Apr 20 '19 15:04 abiosoft

@abiosoft I've done a few other things to the Dockerfile as well. I went back to my original post and put an asterisk in front of all my changes.

STaRDoGG avatar Apr 21 '19 04:04 STaRDoGG

@abiosoft Any ideas? I'm still wrassling with this, lol.

STaRDoGG avatar Apr 24 '19 13:04 STaRDoGG

It's been a few months so I don't suppose you're struggling with this/a "noob" anymore, but if you still need help (I'm curious too)

Do you have the log output from these 3 requests?

/srv # curl -l 127.0.0.1:1234
Client sent an HTTP request to an HTTPS server.
/srv # curl 127.0.0.1:1234
Client sent an HTTP request to an HTTPS server.
/srv # curl https://my.domain.rocks:1234
curl: (7) Failed to connect to my.domain.rocks port 1234: Operation timed out

I'm guessing the first two will say something like "hostname not served on this port", but I'm curious to see why the last one is timing out.

jeslinmx avatar Sep 19 '19 08:09 jeslinmx

@jeslinmx thanks for showing an interest. :)

I ended up throwing in the towel on Caddy (underneath it's 'easy' facade, it's a real PITA to get everything up and running quickly, smoothly, and reliably), and went with Nginx (in the Linuxserver.io's LetsEncrypt container), and it's been smooth sailing ever since. They even have pre-built reverse-proxy configs for a all of the common services built right into the container; you just have to rename a file and it'll work.

If I do ever revisit this issue, (and you're still interested at that point), I'll post a follow-up here.

STaRDoGG avatar Sep 19 '19 15:09 STaRDoGG

Ah. I figured as much. Out of curiosity, how do you find nginx as a reverse proxy compares to, say, caddy and traefik in terms of learning curve? Especially if you want to do something beyond just proxying (for instance, basic auth).

Also, FWIW I believe that caddyV2 is currently in the works. Seems like they did away partially with the "easy" facade, although I have yet to read the docs enough to see whether it was accompanied with greater reliability and configurability. Perhaps when it releases, you might be interested to revisit caddy.

jeslinmx avatar Sep 19 '19 16:09 jeslinmx

@jeslinmx To be honest, I've never used Traefik at all (yet, but I've been curious about it), so I can't really say how that fits in, but compared to Caddy, the Caddy syntax is slightly easier to grasp, but not really that much if you're even just moderately experienced in coding. And for the most part, there's been very little actual coding (myself) involved when using the LinuxServer container; they've done such an excellent job with it, it's all almost ready to go right out of the box. Not much of a learning curve, IMO. I think that's probably the biggest difference; with Caddy, you're still left to hand code everything in your caddyfile, while in this Nginx container, It's all pretty much ready to go out of the box. You just go into it's reverse proxy folder, which is full of a ton of configs for services, and rename whichever ones you need. Restart the container, and you're ready to go. (Assuming you've already setup your other service containers; i.e. Ombi, Tautulli, etc.)

Regarding basic auth, I've never done that with nginx either (yet), I've just not had any need to as of yet. Though, I don't think it would be very tricky at all.

STaRDoGG avatar Sep 20 '19 00:09 STaRDoGG

Thanks, cheers!

jeslinmx avatar Sep 20 '19 08:09 jeslinmx