docker icon indicating copy to clipboard operation
docker copied to clipboard

Enable HTTPS in dockerized Wallabag

Open j0k3r opened this issue 8 years ago • 54 comments

From @Suncatcher on July 11, 2017 15:49

Issue details

How can I enable HTTPS on Docker installation on Wallabag? Didn't find any decent documentation on that. I see that Docker container uses nginx for Wallabag. Should I enable HTTPS in nginx config inside container?

Environment

  • wallabag version that exhibits the issue: 2.2.2
  • How did you install wallabag: Docker
  • Last wallabag version that did not exhibit the issue: None
  • php version: 7.0.16
  • OS: AWS AMI Linux 2017.03
  • type of hosting (shared or dedicated): AWS EC2 T2 Micro
  • which storage system you choose at install (SQLite, MySQL/MariaDB or PostgreSQL): Postgre 9.6.2

Steps to reproduce/test case

Trying to enable HTTPS on Docker Wallabag

Copied from original issue: wallabag/wallabag#3275

j0k3r avatar Jul 31 '17 15:07 j0k3r

From @Suncatcher on July 31, 2017 12:51

Wow!!! Almost a month and no answers. Nobody can say how to set up a HTTPS?

j0k3r avatar Jul 31 '17 15:07 j0k3r

From @Suncatcher on July 31, 2017 12:52

Is it Docker-specific setting or the way is the same for all versions?

j0k3r avatar Jul 31 '17 15:07 j0k3r

I think Google will be your best friend for that case. Few links:

  • https://github.com/docker-library/wordpress/issues/46#issuecomment-311275059
  • https://tech.acseo.co/sites-https-docker-nginx-lets-encrypt/
  • https://github.com/MarvAmBass/docker-nginx-ssl-secure

j0k3r avatar Jul 31 '17 15:07 j0k3r

From @Suncatcher on July 31, 2017 13:15

The first link is about Apache, and the latter is about securing separate nginx Docker container. In our case nginx is included in wallabag image. Is it?

j0k3r avatar Jul 31 '17 15:07 j0k3r

From @Suncatcher on July 31, 2017 15:20

I see here on Dockerhub we have SSL settings sample for nginx:

server {
        listen 443;
        server_name wallabag.foo.bar;

    ssl on;
        ssl_certificate /etc/letsencrypt/live/wallabag.foo.bar/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/wallabag.foo.bar/privkey.pem;

    location / {
        proxy_pass http://wallabag;
        proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Forwarded-Proto https;
                proxy_set_header X-Forwarded-For $remote_addr;
    }

}

However, where should we put it? In Docker-file? In docker-compose? Somewhere inside wallabag container? In running state or in stopped? HTTPS thing should be somehow highlighted in documentation.

j0k3r avatar Jul 31 '17 15:07 j0k3r

This should goes to the docker-composer of wallabag/docker. In fact, I'll move that issue in the correct repo.

j0k3r avatar Jul 31 '17 15:07 j0k3r

I use traefik as reverse proxy on top of my containers and it is in charge of ssl termination (it supports letsencrypt). Between traefik and containers it's basic http connection on the docker network interface only.

nsteinmetz avatar Jul 31 '17 16:07 nsteinmetz

Do you have many containers? What is the advantage of traefic?

Suncatcher avatar Jul 31 '17 18:07 Suncatcher

Yes, a dozen at least.

Traefik is interesting as it integrates docker containers (but also other such as kubernetes, consul, etc) on the fly and provides ssl endpoint (letsencrypt or traditional certificates) and can even be used as traditional reverse proxy.

nsteinmetz avatar Jul 31 '17 21:07 nsteinmetz

@j0k3r this should go into a nginx configuration. this is only for the reverse proxy. making wallabag public is a thing of a reverse proxy using a plain http connection to the container in my opinion. but lets discuss it :)

xsteadfastx avatar Aug 02 '17 08:08 xsteadfastx

in a Wallabag Docker container nginx acts like a reverse proxy by default?

Suncatcher avatar Aug 02 '17 08:08 Suncatcher

@Suncatcher nope... you should use a reverse proxy for accessing the wallabag container... if you really want to make it public available. there you can you traefik or nginx or something for ssl and stuff. the wallabag image is just for accepting the connection.

xsteadfastx avatar Aug 02 '17 16:08 xsteadfastx

I highly recommend you Traefik for this as reverse proxy: https://docs.traefik.io/user-guide/docker-and-lets-encrypt/

kedare avatar Mar 24 '18 15:03 kedare

I highly recommend you Traefik for this as reverse proxy: https://docs.traefik.io/user-guide/docker-and-lets-encrypt/

I followed the instruction in your link. But unfortunately I was not able to make it work. I am a newbie with docker as well... thanks for your help. There is no real error message. In the browser I get 'gateway timeout'.

version: '3'

networks:
  web:

volumes:
  traefik-acme:
  wallabag-maria-db:

services:
  wallabag:
    image: wallabag/wallabag
    networks:
      - web
      - default
    expose:
      - "80"
    labels:
          traefik.backend: "wallabag"
          traefik.docker.network: "traefik_default"
          traefik.docker.network: "web"
          traefik.frontend.rule: "Host:my.domain.com"
          traefik.enable: "true"
          traefik.port: "80"
          traefik.default.protocol: "http"
    volumes:
      - /opt/wallabag/images:/var/www/wallabag/web/assets/images
    environment:
      - MYSQL_ROOT_PASSWORD=wallaroot
      - SYMFONY__ENV__DATABASE_DRIVER=pdo_mysql
      - SYMFONY__ENV__DATABASE_HOST=db
      - SYMFONY__ENV__DATABASE_PORT=3306
      - SYMFONY__ENV__DATABASE_NAME=wallabag
      - SYMFONY__ENV__DATABASE_USER=wallabag
      - SYMFONY__ENV__DATABASE_PASSWORD=pass
      - SYMFONY__ENV__MAILER_HOST=127.0.0.1
      - SYMFONY__ENV__MAILER_USER=~
      - SYMFONY__ENV__MAILER_PASSWORD=~
      - [email protected]
      - SYMFONY__ENV__FOSUSER_REGISTRATION=false
      - SYMFONY__ENV__DOMAIN_NAME=my.domain.com
  db:
    image: mariadb
    environment:
      - MYSQL_ROOT_PASSWORD=wallaroot
    volumes:
      - /opt/wallabag/data:/var/lib/mysql
  redis:
    image: redis:alpine

rinokeros avatar Oct 12 '18 20:10 rinokeros

You need to add traefik to the related network

See https://docs.traefik.io/configuration/backends/docker/#using-docker-compose and the message at the end of the page:

When running inside a container, Træfik will need network access through:

docker network connect <network> <traefik-container>

nsteinmetz avatar Oct 12 '18 21:10 nsteinmetz

@nsteinmetz I also use traefik for all of my containers. But with wallabag I encountered an issue, when I try: curl -I https://my.domain I get:

HTTP/2 302 cache-control: no-cache, private content-type: text/html; charset=UTF-8 date: Wed, 05 Dec 2018 11:51:54 GMT location: http://my.domain server: nginx set-cookie: PHPSESSID=71a90d0ec85a887982f2adb7785f4770; path=/; HttpOnly strict-transport-security: max-age=315360000; includeSubdomains; preload vary: Accept-Encoding x-content-type-options: nosniff x-frame-options: DENY x-powered-by: PHP/7.2.10 x-xss-protection: 1; mode=block

This is also giving me headaches with the android app telling me: "wallabag service not found -- check url". Any idea on why this is happening?

rbcolom avatar Dec 05 '18 12:12 rbcolom

@rbcolom

Seems you have a redirect from https to http ?!

Can you share your docker-compose.yml for wallabag and/or traefik and your traefik.toml so that I can review and compare it to mine ?

Is your service available on the http url ?

nsteinmetz avatar Dec 05 '18 12:12 nsteinmetz

@nsteinmetz

Certainly, here is the docker-compose:

  wallabag:
    image: wallabag/wallabag
    container_name: wallabag
    healthcheck:
      test: ["CMD", "curl" , "-f", "http://localhost:80"]
      interval: 30s
      timeout: 10s
      retries: 5
    environment:
      - TZ=it-IT
      - PUID=1000
      - PGID=1000
      - "SYMFONY__ENV__FOSUSER_REGISTRATION=false"
      - "SYMFONY__ENV__DOMAIN_NAME=https://my.domain"
      - "SYMFONY__ENV__MAILER_HOST=~"
      - "SYMFONY__ENV__MAILER_USER=~"
      - "SYMFONY__ENV__MAILER_PASSWORD=~"
      - "SYMFONY__ENV__FROM_EMAIL=~"
    
    networks:
      - traefik_proxy
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /home/roberto/DockerConf/wallabag/images:/var/www/wallabag/web/assets/images
      - /home/roberto/DockerConf/wallabag/data:/var/www/wallabag/data
    labels:
      - "traefik.enable=true"
      - "traefik.backend=wallabag"
      - "traefik.frontend.rule=Host:my.domain"
      - "traefik.port=80"
      - "traefik.protocol=http"
      - "traefik.docker.network=traefik_proxy"
      - "traefik.frontend.headers.SSLRedirect=true"
      - "traefik.frontend.headers.STSSeconds=315360000"
      - "traefik.frontend.headers.browserXSSFilter=true"
      - "traefik.frontend.headers.contentTypeNosniff=true"
      - "traefik.frontend.headers.forceSTSHeader=true"
      - "traefik.frontend.headers.SSLHost=my.domain"
      - "traefik.frontend.headers.STSIncludeSubdomains=true"
      - "traefik.frontend.headers.STSPreload=true"
      - "traefik.frontend.headers.frameDeny=true"
      - "traefik.frontend.redirect.entryPoint=https"

and here is the relevant traefik.toml part:

# Force HTTPS
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  compress = true
    [entryPoints.https.tls]

For all of my services I use a http to https redirect. BTW thanks for the help, this is driving me nuts.

rbcolom avatar Dec 05 '18 13:12 rbcolom

@rbcolom take care about your environment variables - you should not have quotes - cf https://docs.docker.com/compose/compose-file/#environment

For my wallabag docker-compose.yml:

version: '2'
services:
  wallabag:
    image: wallabag/wallabag
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=XXX
      - POPULATE_DATABASE=False
      - SYMFONY__ENV__DATABASE_DRIVER=pdo_pgsql
      - SYMFONY__ENV__DATABASE_HOST=db
      - SYMFONY__ENV__DATABASE_PORT=5432
      - SYMFONY__ENV__DATABASE_NAME=wallabag
      - SYMFONY__ENV__DATABASE_USER=wallabag
      - SYMFONY__ENV__DATABASE_PASSWORD=XXX
      - SYMFONY__ENV__DOMAIN_NAME=https://wallabag.domain.tld
    labels:
      - "traefik.backend=steinmetz-wallabag"
      - "traefik.frontend.rule=Host:wallabag.domain.tld"
      - "traefik.port=80"
      - "traefik.protocol=http"
      - "traefik.frontend.entryPoints=http,https"
    depends_on:
      - db
      - redis
    restart: always
  db:
    image: postgres:9.6-alpine
    environment:
      - POSTGRES_PASSWORD=XXX
    volumes:
      - /srv/www/steinmetz.fr/w/db:/var/lib/postgresql/data
    labels:
      - "traefik.enable=false"
    restart: always
  redis:
    image: redis:alpine
    labels:
      - "traefik.enable=false"
    restart: always

How do you launch traeik ? I don't see the docker integration/activation ?

On my side, I deploy traefik as a binary - not as a docker container - managed by systemd and with follwoing traefik.toml:

defaultEntryPoints = ["http", "https"]
traefikLogsFile = "/var/log/traefik.log"
logLevel = "ERROR"

[accessLog]
filePath = "/var/log/traefik_access.log"

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

[...]

[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "docker.localhost"
watch = true

nsteinmetz avatar Dec 05 '18 15:12 nsteinmetz

Pardon me, I cut out the wallabag section in the docker-compose file, traefik for me is a docker instance as well. I tried your configuration (but still using a traefik docker image) on a different machine and I still get the same results. Can you confirm me that you're able to use the android application?

rbcolom avatar Dec 05 '18 15:12 rbcolom

if you use a traefik docker image, you need to connect traefik to your wallabag network (or the opposite).

I use the android version without any issue.

nsteinmetz avatar Dec 05 '18 15:12 nsteinmetz

Sorry, I didn't explain myself properly. With my current configuration (the one in the comments above) wallabag is up and running, I can access it through my domain without any problem. What doesn't work is the android app. Investigating a bit, I found out that the POST request wallabag.domain/login ignores the reverse proxy and passing via http. so when I do: curl -I https://my.domain I get: location: http://my.domain/login

rbcolom avatar Dec 05 '18 23:12 rbcolom

I think the problem is that the Symfony setting for trusting the reverse proxy is not set. Instructions for that are here: https://symfony.com/doc/3.4/deployment/proxies.html

I manually added that in my Docker in the web/app.php and it works. That's probably not the best place to add it, but I'm not familiar with Symfony 3 code organization.

Also, what I've seen in other PHP projects is that they add an environment variable called trusted_proxies, which can be used to set this value dynamically (from Docker for example).

rolisz avatar Jan 30 '19 20:01 rolisz

I've upgraded to the 2.1.0 version of the wallabag android app and it is now working. I'm using the latest docker image of wallabag and the reverse proxy is traefik.

rbcolom avatar Jan 31 '19 07:01 rbcolom

But does the redirect from https://my.domain to http://my.domain/login still happen?

rolisz avatar Jan 31 '19 09:01 rolisz

@rolisz Yes, it still occurs, the response is the same. If you need any other info/data, I'll be glad to provide it to you.

rbcolom avatar Jan 31 '19 09:01 rbcolom

@rolisz this downgrading when redirecting is causing issues for anyone using the wallabag android app in android 9 FYI see https://github.com/wallabag/android-app/issues/756, https://github.com/wallabag/wallabag/issues/2273, and https://github.com/wallabag/docker/issues/110 and the only workaround is apparently deprecated by https://github.com/wallabag/wallabag/commit/80336f77fd6ef72dafe20b35b74d74d06592c06f

norweeg avatar Feb 03 '19 18:02 norweeg

Adding the following traefik frontend redirects via labels on my wallabag container worked for me. even though wallabag tries to downgrade to http on redirect, my frontend now upgrades it back to https.

      - "traefik.frontend.redirect.regex=^http://wallabag.example.com/(.*)"
      - "traefik.frontend.redirect.replacement=https://wallabag.example.com/$$1"
      - "traefik.frontend.redirect.permanent=true"

norweeg@my-pc$ curl -I https://wallabag.example.com 
HTTP/2 302  
cache-control: no-cache, private
content-type: text/html; charset=UTF-8
date: Sun, 03 Feb 2019 19:23:50 GMT
location: http://wallabag.example.com/login
referrer-policy: no-referrer 
server: nginx
set-cookie: PHPSESSID=574fb5e6fb8c7a092532a93c98294d2b; path=/; HttpOnly
strict-transport-security: max-age=15552000 
x-powered-by: PHP/7.2.13

norweeg@my-pc$ curl -I http://wallabag.example.com/login                                                                                                                                                                  
HTTP/1.1 307 Temporary Redirect 
Location: https://wallabag.example.com:443/login
Date: Sun, 03 Feb 2019 19:24:01 GMT
Content-Length: 18
Content-Type: text/plain; charset=utf-8

norweeg@my-pc$ curl -I https://wallabag.example.com:443/login                                                                                                                                                   
HTTP/2 200  
cache-control: no-cache, private
content-type: text/html; charset=UTF-8 
date: Sun, 03 Feb 2019 19:24:22 GMT
referrer-policy: no-referrer
server: nginx 
set-cookie: PHPSESSID=e5b601c4811270133e530c0d986e7280; path=/; HttpOnly
strict-transport-security: max-age=15552000
x-powered-by: PHP/7.2.13 

norweeg avatar Feb 03 '19 19:02 norweeg

@norweeg I still have the problem even with your suggestion. I found that traefik.frontend.headers.SSLRedirect have the same behaviour (308 + correct HTTPS URL), but in both cases the Android app keeps throwing the error message.

Chostakovitch avatar Feb 27 '19 14:02 Chostakovitch

@Chostakovitch huh.. that's strange because I don't touch that option, but I stopped getting the error once my wallabag frontend sent a http 301 redirect instead of 302 redirect from http to https (the redirect at the entrypoint level wasn't sufficient). I probably forgot something in my earlier post, so here's my docker-compose service template for my wallabag service that has worked for me:

version: '3.5'
services:
  wallabag:
    image: wallabag/wallabag:latest
    container_name: wallabag
    networks:
      - wallabag
    restart: unless-stopped
    env_file:
      - ../configs/wallabag.env
    expose:
      - "80"
    labels:
      - traefik.enable=true
      - traefik.backend=wallabag
      - traefik.frontend.rule=Host:${WALLABAG_DOMAIN}
      - "traefik.frontend.redirect.regex=^http://${WALLABAG_DOMAIN}/(.*)"
      - "traefik.frontend.redirect.replacement=https://${WALLABAG_DOMAIN}/$$1"
      - traefik.frontend.redirect.permanent=true
      - traefik.frontend.passHostHeader=true
      - traefik.frontend.whiteList.useXForwardedFor=true
      - traefik.frontend.headers.SSLProxyHeaders=X-Forwarded-Proto:https
      - traefik.docker.network=wallabag
      - traefik.port=80
      - com.centurylinklabs.watchtower.enable=true
    depends_on:
      - wallabag-db
      - wallabag-redis
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://wallabag:80/login > /dev/null || exit 1"]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 15s
    volumes:
      - wallabag-images:/var/www/wallabag/web/assets/images
      - wallabag-data:/var/www/wallabag/data
      - wallabag-logs:/var/www/wallabag/var/logs

edit: oops! I'm getting my threads on this issue mixed up. Was referring to an earlier post on https://github.com/wallabag/android-app/issues/756#issuecomment-462996975

norweeg avatar Feb 27 '19 18:02 norweeg