Deploy Seafile-Docker with Caddy from Repo

1. Caddy version (caddy version):

v.2.4.6.

2. How I run Caddy:

Installed with the caddy instructions for Debian Bullseye, with repository.

a. System environment:

DietPi aarch64 Debian Bullseye on Rock64 - Pine SBC.
Caddy runs on systemd but my server “Seafile for ARM” is running in a Docker-Container.

b. Command:

sudo systemctl start caddy

c. Service/unit/compose file:

version: '3.3'

services:
  seafile:
    image: franchetti/seafile-arm
    restart: always
    environment:
      - PUID=1000
      - PGID=1000
      - SERVER_IP=my.domain
      - SEAFILE_ADMIN_EMAIL=mymail@domain
      - SEAFILE_ADMIN_PASSWORD=password
      - ENABLE_TLS=1
      - MYSQL_HOST=db
      - MYSQL_USER_PASSWD=db_pass
      - MYSQL_ROOT_PASSWD=db_pass
    volumes:
      - media:/shared/media
      - ./seafile/conf:/shared/conf
      - ./seafile/logs:/shared/logs
      - /mnt/back/seafile-data:/shared/seafile-data
      - ./seafile/seahub-data:/shared/seahub-data
    depends_on:
      - db

  db:
    image: linuxserver/mariadb
    restart: always
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=db_pass
      - TZ=Europe/Berlin
    volumes:
      - ./db:/config

#  reverse-proxy:
#   image: linuxserver/swag
#   restart: always
#    cap_add:
#     - NET_ADMIN
#    environment:
#      - PUID=1000
#      - PGID=1000
#      - TZ=Europe/Berlin
#      - URL=my.domain
#      - VALIDATION=http
#    volumes:
#      - media:/shared/media
#      - ./seafile/seahub-data:/shared/seahub-data
#      - ./reverse-proxy:/config
#    ports:
#      - 443:443
#      - 80:80

volumes:
  media:

d. My complete Caddyfile or JSON config:

my.domain {
    reverse_proxy 127.0.0.1:8000
}
my.domain/seafhttp {
    reverse_proxy 127.0.0.1:8082
}
my.domain/media {
    root * /shared/media
    file_server
}

3. The problem I’m having:

GET / HTTP/1.1
> Host: my.domain
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://my.domain/
< Server: Caddy
< Date: Fri, 07 Jan 2022 21:16:07 GMT
< Content-Length: 0
< 
* Closing connection 0

Okay, what am I doing here, well first. Caddy is my favorite Proxy, but this Seafile-ARM compose file I am using the last months uses SWAG/Ngnix. So I try to put the SWAG Container down (it doesn`t run, I marked it out and did a docker-compose down and up -d). And installed Caddy through the repo.

My Caddyfile gave me a working SSL Cert. and I can see it in my browser, but the page is blank. Seafile isn`t running, and I think my error here is the way I try to include the file_server at the end.

here is the old swag conf, which runs good, but I dont find a solution to migrate it correctly to caddy.

server {
    listen       80;
    server_name  my.domain;
    rewrite ^ https://$http_host$request_uri? permanent;  
    server_tokens off;
}

server {
    listen 443;
    server_name my.domain;

    # all ssl related config moved to ssl.conf
        include /config/nginx/ssl.conf;

    server_tokens off;

    location / {
        proxy_pass         http://seafile:8000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        proxy_set_header   X-Forwarded-Proto https;

        proxy_read_timeout  1200s;

        client_max_body_size 0;
    }

    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://seafile:8082;
        client_max_body_size 0;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
        proxy_send_timeout  36000s;
        send_timeout  36000s;
    }

    location /media {
        root /shared;
    }
}

I struggle with these paths from system to container and from container to system, and I should be grateful that everything works with swag, but I really want it to run with caddy, because I run all my servers with it, and if it works, it will be easier for me to combine it with other services running on my network.

I tried some combinations with this line from the compose file in caddy to get the fileserver part: - /mnt/back/seafile-data:/shared/seafile-data because /mnt/back is a physical storage, connected via USB and stores all the files (seafile-data).

file_server /mnt/back/seafile-data for example.

tl:dr
The cert goes to the domain, and caddy looks like it works well. but there are some missing parts for the file_server.

I bet it is simple, but I dont see it. Thx for helping me out with this.

You’re using a path matcher here – in Caddy, path matching is exact, so only requests to exactly /seafhttp would match, and not /seafhttp/foo.

I strongly suggest not using path matchers in the site address, it’s pretty confusing. Best to use one site, and use handle blocks instead. It becomes clearer what’s going on, and has some other advantages. (I actually plan on deprecating paths in the site address soon, I think it’s bad).

Another thing here, the way Caddy assembles a path to a file on disk is by taking the request path, and appending it to the root. So in this case, a request to /media/example.txt would look for a file in /shared/media/media/example.txt. Note the doubled up /media. The fix is to use handle_path for this one.

So this is how I’d suggest writing it:

my.domain {
	handle /seafhttp* {
		reverse_proxy 127.0.0.1:8082
	}

	handle_path /media* {
		root * /shared/media
		file_server
	}

	handle {
		reverse_proxy 127.0.0.1:8000
	}
}

FYI looking at your docker-compose.yml, I’m not seeing any port mappings for seafile, but you’re running Caddy on the host machine. Caddy won’t be able to reach it unless you do.

Also, are you sure /shared/media is the right location of your files? That seems like the path inside the seafile container, and not the path of the files on the host machine. Is that wrong?

This looks really better, but has the same functionality. I got the certs but Page is blank and seafile not running. Anyway thx for the better structures. It helps and is more accurate.

I’m not seeing any port mappings for seafile, but you’re running Caddy on the host machine. Caddy won’t be able to reach it unless you do.

I have some understanding issues here. The only port mappings where at the old swag conf. 443 and 80. I thought they where useless now when there are no proxy’s in docker.

Also, are you sure /shared/media is the right location of your files? That seems like the path inside the seafile container, and not the path of the files on the host machine. Is that wrong?

I am definitely unsure about this. But that’s my fault, because I use docker without knowing how paths working. I have this mount with the seafile data on /mnt/back/seafile-data. But what did caddy need? The real path or the path docker uses to get to this mount?

You used to be running swag as a docker container, so it was part of the docker network where seafile was running.

But now you’re running Caddy outside of docker, which means you have to change how seafile exposes itself to be reached.

Or, you could just use the official docker image for Caddy instead of running it on your host machine, it’ll work more similarly to how you had it before.

Or, you could just use the official docker image for Caddy instead of running it on your host machine, it’ll work more similarly to how you had it before.

True. I really dislike docker, but if there are no other ways. I only used docker here, because i didnt found a working solution for seafile-arm without docker.

At the end, I got it working, and don’t want to miss adding my solution for a kind stranger who stumble over this thread.

  1. I added this to my docker-compose.yaml instead of the Swag part:
 caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - media:/shared/media
      - ./seafile/seahub-data:/shared/seahub-data
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:
  media:
  1. I purged caddy from repo and remove /etc/caddy/Caddyfile

  2. Added a new Caddyfile in the same folder where the compose.yaml is.

  3. Used this conf (same as above but I had to set the 127.0.0.1 to “seafile” because thats what docker used for the mapping.

my.domain {
        handle /seafhttp* {
                reverse_proxy seafile:8082
        }

        handle_path /media* {
                root * /shared/media
                file_server
        }

        handle {
                reverse_proxy seafile:8000
        }
}
  1. docker-compose up -d and it works flawless.

Thx. For pointing me to this solution @francislavoie, finally I have caddy running on all my servers. This was the last one.

1 Like

Docker really makes it easiest to install things without polluting the host machine, makes it easier to throw things away and start anew without having to do a fresh install etc. In this case it’s the best option for you since you’re already using Docker for something.

Glad you got it working!

:+1:

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.