1. Home
  2. Support

Self-hosted installation - docker containers guidance

By Dmitry Figol @dmfigol2018-05-05 15:23:49.032Z

Hi,
I think I am ready to move from Disqus comments to Talkyard comments for my blog. I would like to use self-hosted solution.
I don't want to run any scripts/compose file offered, mainly because I already have my website running using docker-compose with some customization to config files (like nginx).
I was trying to understand what every container in your compose file is doing, but without a description for every container it is not very straightforward.
For example, I don't need nginx and certbot, because I already have that.
Could you explain what every container is needed for and provide some guidance how to migrate to self-hosted comments in my case? Is there something else that can be excluded if I don't care about the forum portion?
Thanks in advance!

  • 3 replies
  1. KajMagnus @KajMagnus2018-05-08 05:08:56.263Z2018-05-08 05:22:24.580Z

    (Sorry for the late reply. This was more tricky than the other questions :- ))

    Your Nginx server run inside a Docker container or directly on the host?

    I don't want to run any scripts/compose file offered

    I think it'd be hard to do this in any other way, than using Talkyard's compose file & .env file and upgrade script. Talkyard's compose file uses a version number in the .env file in the same directory. And there's a script, supposed to be called daily from Cron, that checks fo new versions, upgrades the version number, downloads new images & restarts. — If one (for example) copy-pastes the docker-compose.yml contents to another compose file ... then the version number in the .env will thereafter be missing. Or if one copies the .env too — then, auto-upgrade won't work (it assumes Talkyard is installed in /opt/talkyard).

    If you have ideas / thoughts about how to do this, in a better way (& that doesn't break auto-upgrade) — that would be interesting to hear :- )

    Could you [...] provide some guidance how to migrate to self-hosted comments in my case?

    Ok. First, the only Talkyard container that can be removed, without breaking something, is the certgen container. (It's supposed to generate HTTPS certs, but it currently does nothing, not yet implemented.) If, however, you copy-paste the Talkyard Nginx config, to your own Nginx config files — then things will break, later when I make changes to the Nginx config, but your config files won't get auto-updated with those changes.

    Now. How to self-host. I think reverse-proxying all Talkyard stuff behind your Nginx, is the way to go. Here's how to reverse-proxy a Talkyard site, with the address talkyard.yourblog.com, behind a Nginx server on the host. (I haven't tested this myself though.)

    (First, note: If your Nginx is inside a Docker container, then, would be tricky to connect it to Talkyard — since Talkyard's containers are in a different docker-compose file on a different docker network. Probably you would instead need to add another Nginx server, directly on the host, then. )

    You edit Talkyard's docker-compose.yml file and change the public ports from 80 and 443 (which would collide with Nginx on the host), to 8080 and 8443, like so:

      web:
        ...
        ports:
          - '80:80'
          - '443:443'
    

    change to:

        ports:
          # This makes Talkyard's 'web' container listen on 8080 on the host,
          # and send to Nginx inside the container on port 80.
          - '8080:80'
          - '8443:443'
    

    Then, you configuring Nginx on the host, to reverse-proxy requests to talkyard.yourblog.com, to ports 8080 and 8443. Something like this: (in your Nginx config)

    server {
      listen 443 ssl;
      listen [::]:443 ssl;
    
      server_name talkyard.yourblog.com;
    
      # SSL config ...
    
      # Reverse proxy to Talkyard:
      location / {
        proxy_pass http://talkyard.yourblog.com:8080/;
        proxy_redirect http://talkyard.yourblog.com:8080/ https://talkyard.yourblog.com;
        proxy_http_version 1.1;
        proxy_set_header Host $http_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-Proto $scheme;
        proxy_read_timeout 120;
      }
    

    There's one thing I need to fix though. Talkyard's Nginx server in the Docker container, also does:

      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  $scheme;   <--- oops
    

    That means (I think) that the Talkyard Nginx server discards the X-... headers from your Nginx, so the Talkyard app server will (among other things) believe the request is insecure over HTTP, enven though it's HTTPS. This might make Talkyard's app server throw some security error. Seems I can fix that, as described here: https://serverfault.com/questions/515957/how-to-have-nginx-forward-the-http-x-forwarded-proto-header

    About the containers

    Could you explain what every container is needed

    Here're the different containers and what they do:

    • web = Nginx. Reverse-proxies the application server. Serves uploaded files (e.g. images) from disk, without passing through the app server. Websocket and Long polling, for real time things (like chat and notifications).
    • app = The application server: Play Framework, running in the JVM.
    • cache = In-memory cache: Redis.
    • certgen = In the future, is supposed to generate HTTPS certs automatically, via Let'sEncrypt.
    • rdb = Relational database: PostgreSQL.
    • search = Full text search database: ElasticSearch.

    Only for developers: (not included in the talkyard-prod-one repo, only in the talkyard repo)

    • gulp = Transpiles & minifies Javascript (well, Typescript) and CSS.
    • app-dev = A development build of the application server. Includes non-minified JS and CSS.
    1. DDmitry Figol @dmfigol2018-06-07 02:59:48.871Z

      Thanks for reply.
      Sounds a little bit more complicated than I would love to. So probably I will try some other service :(
      For your self-upgrade problem, I'd recommend taking a look on https://github.com/v2tec/watchtower
      For automatic lets encrypt certs - you have two options:

      1. set up cronjob on the server which will run certbot in webroot mode with proper webroot directory mounted or
      2. install certbot into the nginx image and run with --nginx. there should be a crontab installed with certbot installation that should be double-checked.
      1. KajMagnus @KajMagnus2018-06-08 03:11:16.834Z

        Ok, and thanks for the ideas :- )

        Watchtower. This project looks interesting. And also a bit dangerous, to me, if used by an app with many images and containers. Then, the containers might get upgraded independently of each other. Maybe the web server image, gets upgraded, and starts sending requests to new endpoints on the app server — slightly before the app server is done upgrading. That'd result in errors. (Having all images being compatible with the previous version of all other images = that can be problematic, in some cases ... and hard to test properly.)

        I'd like Watchtower to upgrade all images at once, not one at a time independently of each other.

        Another issue with W: Most images I push, are work-in-progress images, that people aren't supposed to use. (Only for me, on the servers I maintain.) Currently, the upgrade scripts looks in this file: https://github.com/debiki/talkyard-versions/blob/master/version-tags.log, upgrades to the latest version that is not a "WIP" or "test" or "beta" or something like that. ... Don't see any such functionality in Watchtower. (Creating different Docker image repos for "WIP", "tetst", "beta" etc — hmm, maybe ... or maybe there'd be a bit too many repos? hmm)

        Anyway could be nice to use a standard thing like W, instead of the scripts. I asked the Watchtower developers: Upgrade all images & restart containers at the same time?.

        Cron & Let'sEncrypt. Yes something like that is what I've been planning to do. I use certbot in webroot mode right now, on the servers I manage. I've installed certbot on the host.

        And I've been thinking, maybe it's better to have certbot in a container instead (like you mentioned in 2.: "install certbot into the nginx image"). — I'd prefer it if Talkyard didn't install any apps on the host, except for Docker. Maybe someone uses a Let'sEncrypt tool other than Certbot? And wouldn't want certbot too, directly on the host?

        In Talkyard's case, the tricky thing, with certs, is that there's SaaS hosting: The app server needs to automatically tell Certbot that a new site has been created at a custom domain, and Certbot then needs to automatically create & maintain a cert, for that new site. And eventually stop renewing it, if the domain gets changed again. — There needs to be a process, other than Cretbot, that talks with the app server and invokes Certbot. (Or maybe I could add Certbot in the app server image and call Certbot directly from Scala? Hmm)