I’ve been trying for a while to set up a Pydio server for trial. I’m coming over from Nextcloud (it has crashed on me for the last time) and trying to get this going, but even the Docker method isn’t working.
TL;DR:
The documentation is probably great for directly hosted configurations, but is no help when using a Docker nginx reverse proxy image. So far, binary image in VM or via the Docker image, I haven’t been able to get things working.
Setup:
I have a workstation running Centos 8. It’s running Docker in the base OS, but there are also VMs running. Per Nextcloud I’ve got nginx-proxy and nginx-proxy-letsencrypt running, which do a great job of automatically setting up web services (both VM and Docker based). I’ve since stopped using Nextcloud, it is deactivated and not occupying any ports. Short background of spinning up new web service:
- Create a Docker container, or docker-compose.yml and spin it up, feeding VIRTUAL_HOST, LETSENCRYPT_HOST, and VIRTUAL_PORT as environment variables (the first two being the external address, the last the port the container listens on from the host side)
- Spinning up the container (for testing I’ve created a proper website via plain ol’ httpd) with these set properly, the letsencrypt side properly acquires a certificate and registers it for the proxy side
- Access the appropriate address specified in VIRTUAL_HOST/LETSENCRYPT_HOST and you’ll see the server (ranging from “It works!”, the default, to a proper website) pretty much immediately if your DNS is already set up.
I’ve set up a pydio subdomain (for security not my real address: pydio.mydomain.ca), and my router allows access to the appropriate ports (I’ve been able to access test sites internally and externally, as per above). I did have no issues with Nextcloud with this same setup (different subdomain obviously), until an update, hence why I’m looking elsewhere now (I think 5 failures is enough abuse for this relationship). For the uninitiated, the nginx-proxy and nginx-proxy-letsencrypt containers work as a pair. If it isn’t clear by now, one does the routing and web serving (if I set it up to do that) while also automatically generating configurations for new containers that show up with a VIRTUAL_HOST environment variable, the other arranges for new SSL certificates automatically for any newly started containers that have LETSENCRYPT_HOST as an environment variable if there is no currently valid certificate. The two share the certificate directory between each other and handle the external SSL verification.
I’ve set up a docker-compose.yml as per below, which I think is more or less the default recommended, modified to access my appropriate external directories. Important note: I have a multi-terabyte RAID array for mass storage, so I want to reference that external directory for storing the data. The main drive the system OS is on doesn’t have much space (plenty remaining for day to day, not enough for videos, images, binaries, family stuff, etc. to be stored and shared).
version: '3.7'
services:
cells:
image: pydio/cells:latest
restart: unless-stopped
ports: ["8080:8080"]
environment:
- CELLS_LOG_LEVEL=production
- CELLS_BIND=0.0.0.0:8080
- CELLS_EXTERNAL=pydio.mydomain.ca
- CELLS_NO_SSL=1
- VIRTUAL_HOST=pydio.mydomain.ca
- LETSENCRYPT_HOST=pydio.mydomain.ca
- VIRTUAL_PORT=8080
volumes:
- /srv/storage/docker/pydio/data:/var/cells/data
- /srv/storage/docker/pydio:/var/cells
network_mode: "bridge"
mysql:
image: mysql:5.7
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: P@ssw0rd
MYSQL_DATABASE: cells
MYSQL_USER: pydio
MYSQL_PASSWORD: P@ssw0rd
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci]
volumes:
- /srv/storage/docker/mysql:/var/lib/mysql
network_mode: "bridge"
If I try to access the server, I’ll get one of four errors via my browser and the nginx-proxy logs, depending on how I’ve attempted to configure the CELLS_BIND and CELLS_EXTERNAL settings:
- 503 error
- Client sent an HTTP request to an HTTPS server.
- A 400 error which internally is shown via the logs as:
nginx.1 | pydio.mydomain.ca 1.2.3.4 - - [20/Jul/2021:01:59:08 -0400] "GET / HTTP/2.0" 400 48 "-" "Mozilla/5.0" "172.17.0.6:8080"
- Or a 502 error shown via the logs as:
nginx.1 | pydio.mydomain.ca 1.2.3.4 - - [20/Jul/2021:01:02:54 -0400] "GET / HTTP/2.0" 502 157 "-" "Mozilla/5.0" "172.17.0.6:8080"
nginx.1 | 2021/07/20 01:02:54 [error] 243#243: *301 connect() failed (111: Connection refused) while connecting to upstream, client: 1.2.3.4, server: pydio.mydomain.ca, request: "GET / HTTP/2.0", upstream: "http://172.17.0.6:8080/", host: "pydio.mydomain.ca"
I HAVE had the setup page load when I use localhost:8080 sometimes, but that doesn’t resolve my external access issue. The generated default.conf for nginx-proxy (created inside of the container) is as follows:
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
default $http_x_forwarded_port;
'' $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
# Set appropriate X-Forwarded-Ssl header based on $proxy_x_forwarded_proto
map $proxy_x_forwarded_proto $proxy_x_forwarded_ssl {
default off;
https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$upstream_addr"';
access_log off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
resolver 192.168.0.254;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
server_tokens off;
listen 80;
access_log /var/log/nginx/access.log vhost;
return 503;
}
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
server_tokens off;
listen 443 ssl http2;
access_log /var/log/nginx/access.log vhost;
return 503;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/default.crt;
ssl_certificate_key /etc/nginx/certs/default.key;
}
# pydio.mydomain.ca
upstream pydio.mydomain.ca-upstream {
## Can be connected with "bridge" network
# pydio_cells_1
server 172.17.0.6:8080;
}
server {
server_name pydio.mydomain.ca;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
# Do not HTTPS redirect Let'sEncrypt ACME challenge
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
auth_request off;
allow all;
root /usr/share/nginx/html;
try_files $uri =404;
break;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name pydio.mydomain.ca;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/pydio.mydomain.ca.crt;
ssl_certificate_key /etc/nginx/certs/pydio.mydomain.ca.key;
ssl_dhparam /etc/nginx/certs/pydio.mydomain.ca.dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/certs/pydio.mydomain.ca.chain.pem;
add_header Strict-Transport-Security "max-age=31536000" always;
include /etc/nginx/vhost.d/default;
location / {
proxy_pass http://pydio.mydomain.ca-upstream;
}
}
Now to be clear, I’m not 100% certain that my connection attempts are getting through to the Cells container because I don’t see any responses in the logs for that container, in spite of the multitude of errors I’m able to bring up with nginx-proxy. Since I get different error numbers, I feel the Cells web server is responding, it’s just not telling me what the errors are in the Cell container logs. At this point I’m lost. I’ve been at this for a few weeks now without success and will accept any advice possible.