yobasystems / alpine-caddy

Caddy running on Alpine Linux [Docker]
https://hub.docker.com/r/yobasystems/alpine-caddy/
21 stars 4 forks source link

Can't run ARM image - permission denied #1

Closed dzek69 closed 5 years ago

dzek69 commented 6 years ago

Running yobasystems/alpine-caddy:armhf ends with:

making user directory: mkdir /home/caddy: permission denied

On the container it seems that /home exists but it's empty and owned by root and the user running is caddy.

dominictayloruk commented 6 years ago

I've just run the following command and it's running fine docker run -d --name examplecaddy -p 2015:2015 yobasystems/alpine-caddy:armhf

I've also bind mounted a volume (into /srv) docker run -d --name examplecaddy -p 2015:2015 -v /data/caddy:/srv yobasystems/alpine-caddy:armhf

My host is a Asus Tinkerboard running Armbian (Debian 9) with a 4.14 kernel. My docker info for reference

Containers: 2
 Running: 2
 Paused: 0
 Stopped: 0
Images: 179
Server Version: 18.06.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e
runc version: 69663f0bd4b60df09991c08812a60108003fa340
init version: fec3683
Security Options:
 seccomp
  Profile: default
Kernel Version: 4.14.52-rockchip
Operating System: Debian GNU/Linux 9 (stretch)
OSType: linux
Architecture: armv7l
CPUs: 4
Total Memory: 1.958GiB
Name: tb01
ID: REDACTED
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false
dominictayloruk commented 6 years ago

Still facing this issue??

I cannot reproduce so will close this issue if no longer a problem.

dzek69 commented 6 years ago

I need some time, too busy now to get back into it for a while. You can close it and I'll try it again later and reopen.

dzek69 commented 5 years ago

@dominictayloruk Sorry it took so long, forgot a bit about that.

Anyway, the problem is that /home is owned by root and doesn't contain caddy directory, which should be owned by caddy user. Caddy stores Let's encrypt certs and other cert caches there. So if I enable auto ssl then I cannot use this image without tweaking it first to fix the issue.

Example:

Caddyfile

domain.you.own.com {
    tls {
       # staging env just for testing purposes
       ca https://acme-staging-v02.api.letsencrypt.org/directory
    }
}

Then run: docker run --name examplecaddy -v $(pwd)/Caddyfile:/etc/Caddyfile yobasystems/alpine-caddy:armhf

Result:

Activating privacy features...

Your sites will be served over HTTPS automatically using Let's Encrypt.
By continuing, you agree to the Let's Encrypt Subscriber Agreement at:
  https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
Please enter your email address to signify agreement and to be notified
in case of issues. You can leave it blank, but we don't recommend it.
  Email address: 2018/11/28 19:01:24 making user directory: mkdir /home/caddy: permission denied

(Caddy stops now)

dominictayloruk commented 5 years ago

Think i've sorted it.

The adduser for caddy had the -H switch which disables creating a home directory.

# adduser --help
BusyBox v1.27.2 (2017-12-12 10:41:50 GMT) multi-call binary.

Usage: adduser [OPTIONS] USER [GROUP]

Create new user, or add USER to GROUP

    -h DIR      Home directory
    -g GECOS    GECOS field
    -s SHELL    Login shell
    -G GRP      Group
    -S      Create a system user
    -D      Don't assign a password
    -H      Don't create home directory
    -u UID      User id
    -k SKEL     Skeleton directory (/etc/skel)
dzek69 commented 5 years ago

Okay, that seems to be fixed, but there's another problem, which disallows usage of auto-ssl inside container:

Caddy can't internally bind to 80 port.

error presenting token: presenting with standard HTTP provider server: Could not start HTTP server for challenge -> listen tcp :80: bind: permission denied

It works fine with default port (2015), because it's "high port" (over 1024). IIRC on Linux (thought it's only Debian-based distros thing, but looks like it's now) it is forbidden to bind to lower port until allowed with setcap (or run as root, but we don't want that).

Port 80 must be bound directly Caddy to let Let's Encrypt do its challenge to verify the host. You can't change challenge port, so you cannot just set it to whatever, like 3333 (even with Docker Host mapping 80 to 3333), because Caddy has no option for that (as written here: https://caddyserver.com/docs/automatic-https). Challenge via DNS is much harder to setup, requires "supported" DNS management to be used.

Looking at this post: https://github.com/gliderlabs/docker-alpine/issues/166#issuecomment-222490216

it looks like something like this should solve the problem, and let Caddy bind 80 port inside container:

apk add --no-cache libcap
setcap cap_net_bind_service=+ep `readlink -f /usr/bin/caddy`
apk del libcap
dominictayloruk commented 5 years ago

I've added the setcap section. When i had a look into the other Dockerfiles, this was already in the pp version and for some reason i had omitted it from the arm variants.

Have a look at https://github.com/yobasystems/alpine-caddy/commit/cf1a70361468f5ffebe062bcfa57092a83ecd157

I'll also re-open until fixed. I use the image behind a Haproxy load balancer so haven't had a use for auto https.

dzek69 commented 5 years ago

I use Caddy as a proxy/load balancer + autohttps, I found no use for another proxy, while Caddy can do the same and I won't go for millions of views per sec on a Raspberry anyway.

Anyway - it works now :) Thanks for taking care.