Cells: working docker-compose.yml with Traefik reverse proxy


If you are familiar with Traefik, the below configuration will get you up and running with persistent volumes and letsencrypt. Be sure you:

  1. setup a valid traefik.toml
  2. create the http_network required
  3. set 2 A or CNAME records in DNS for traefik.{PYDIO_FQDN} and {PYDIO_FQDN}.

When you go through the installation process, for the database replace “localhost” with mysql. The address for php is “php-fpm:9000”.

Also, I am using a .env file in the same directory as the docker-compose.yml, which holds key variables below like the ${PYDIO_FQDN} as well as the mysql credentials.

Once you finish the installation, you must go into Settings -> Configs Backends and replace “http://cells:8888” with an external URL (i.e. https://PYDIO_FQDN). Otherwise you’ll get “Origin is not allowed” / Access-Control-Allow-Origin issues.

version: '3'

    external: true


    image: traefik:1.6-alpine
    container_name: traefik
    restart: always
      - "80:80"
      - "443:443"
      - traefik.enable=true
      - traefik.backend=traefik
      - traefik.frontend.rule=Host:traefik.${PYDIO_FQDN}
      - traefik.port=8080
      - traefik.docker.network=http_network
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ${VOLUMES_ROOT_PATH}/traefik/traefik.toml:/traefik.toml:ro
      - ${VOLUMES_ROOT_PATH}/traefik/acme:/etc/traefik/acme
      - http_network

    image: pydio/cells:latest
    container_name: cells
    restart: always
      - "8888"
      - CELLS_BIND=
      - CELLS_EXTERNAL=cells:8888
      - CELLS_NO_SSL=1
      - traefik.enable=true
      - traefik.backend=cells
      - traefik.frontend.rule=Host:${PYDIO_FQDN}
      - traefik.port=8888
      - traefik.docker.network=http_network
      - ${VOLUMES_ROOT_PATH}/cells:/root/.config/pydio/cells/
      - mysql
      - php-fpm
      - http_network

    image: mysql:5.7
    container_name: mysql
    restart: always
    command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci]
      - "3306"
      - ${VOLUMES_ROOT_PATH}/cells/db:/var/lib/mysql
      - http_network

    image: pydio/cells-php-fpm:latest
    container_name: php-fpm
    restart: always
      - ${VOLUMES_ROOT_PATH}/cells:/root/.config/pydio/cells/
      - "9000"
      - http_network

Docker-compose.yml with nginx and letsencrypt for pydio cells

I can’t enter the installation when opening the PYDIO_FQDN adress in the browser.

Logs in the cells container reads:
cells | 2018-07-05T15:33:59.820Z INFO http: TLS handshake error from xxx.xx.x.x:51612: tls: first record does not look like a TLS handshake

Has Port 8888 to be opened on the docker host?


No only 80 and 443 for this to work. 8888 is the internal port which the cells container exposes for the Traefik contain to direct traffic to.

Maybe the problem is in your Traefik config traefik.toml … try looking at your log for the traefik container?

Let me know if I can help you further. I love pydio and traefik.


I have multiple services running successfully on the host. The traefik.toml is pretty basic. http redirection to https, acme and api. I’m fairly new to all this, so any help is appreciated. :slight_smile:

Traefik logs say this:
traefik | time=“2018-07-05T15:56:10Z” level=error msg=“Undefined backend ‘backend-cells’ for frontend frontend-Host-xxx-xxx-xxx-0”


Did you copy/paste the docket compose file? If not you may have a typo.


Copy pasted and modified slightly: Removed the traefik part since it’s already running on the host, changed the network to the already existing “web” network. As you said, this might be a traefik issue so i rather research in this direction. Thanks for your compose file anyway!

Weird enough the cells backend is showing up in the traefik dashboard.


Does the port you are exposing for cells container match the traefik.port under labels? In my example I had modified it to 8888 for both. Maybe one got changed back to 8080?


Yes. You can checkout my setup here: https://gist.github.com/bschulz87/fc1f6968ea97b1c034bfa4811b35e17d


The only thing that immediately comes to mind is both web and default network being used. Your traefik is on web network for sure? “docker network inspect web” should show both traefik and cells?

Sorry if I’m pointing to things obvious to you.


Traefik is on the web network, yes. I updated the gist to show the traefik settings.

No matter what i do, i only get TLS handshake errors in the cells container. I also disabled the redirection to https and tried to access the installation on http://cells.pydio.dev - still ‘http: TLS handshake error from xxx.xx.x.x:36528: tls: first record does not look like a TLS handshake’. Traefik does not show up anything so it’s unlikely a misconfiguration there (7 other services working well)

It is working now. I was using an image which did not have the CELLS_NO_SSL feature yet.


Thanks for the config.

I’m trying to get my pydio instance on a subdirectory (i.e. www.mysite.com/pydio/) using the same config but I’m having issues with the paths being served up being a mixture from the root directory and /pydio/.

I’ve modified the following in the configuration:

Environment variable - CELLS_EXTERNAL=mysite.com/pydio
Traefik Frontend Label - “traefik.frontend.rule=PathPrefix:/pydio;PathPrefixStrip:/pydio”

Other static resources are loading up fine so I’m wondering if there’s another configuration value that needs changing which isn’t exposed as an environment variable?

For reference, I’m getting the following errors from the chrome developer console when loading up the installer.

client.js:772 GET https://mysite.com/install/agreement 404 ()
client.js:425 Uncaught (in promise) Error: Unsuccessful HTTP response
    at Request.<anonymous> (client.js:425)
    at Request.Emitter.emit (index.js:133)
    at XMLHttpRequest.xhr.onreadystatechange (client.js:705)
client.js:772 GET https://mysite.com/install 404 ()
client.js:425 Uncaught (in promise) Error: Unsuccessful HTTP response
    at Request.<anonymous> (client.js:425)
    at Request.Emitter.emit (index.js:133)
    at XMLHttpRequest.xhr.onreadystatechange (client.js:705)
client.js:772 GET https://mysite.com/install/events?timeout=60&category=install 404 ()