tavern/examples/linode
Nick Gerakines e4f3840531
Updated the linode example to include publisher. Updated the changelog.
2020-03-28 17:23:29 -04:00
..
README.md Updated the linode example to include publisher. Updated the changelog. 2020-03-28 17:23:29 -04:00

README.md

About

This is example configuration used to run https://tavern.town/.

Infrastructure

This example setup assumes you have a linode account with the following infrastructure configured:

  • One (1x) 4GB "standard" with private and and public IP4 and IP6 addresses.
  • One (1x) node balancer configured to forward TCP connections from ports 80 and 443 to the above node.
  • DNS A and AAA records for the bare domain (tavern.town) and www domain (www.tavern.town) to the load balancer IPs.

Node Setup

These steps assume you have created the node using Linode's default parameters using Fedora 31.

  1. Create the node
  2. Follow all of the steps outlined in https://www.linode.com/docs/getting-started/
  3. Install and setup docker as outlined on https://docs.docker.com/install/linux/docker-ce/fedora/
  4. Install and setup docker-compose as outlined on https://docs.docker.com/compose/install/
  5. Install caddy (dnf install caddy)

Have the following things ready:

  1. The private IP address of the host. This can be found in the linode dashboard or using the nmcli tool.

     $ nmcli | grep /17
       inet4 192.168.235.239/17
    

App setup

  1. In your user directory, create a directory for your website. (mkdir your-site && cd your-site)

  2. Create some env files used by db and web. (touch db.env web.env)

  3. Generate a somewhat random postgres password.

      $ < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32} | md5sum | cut -d' ' -f1
      SNIP
      $ echo POSTGRES_PASSWORD=SNIP >> db.env
      $ echo 'DATABASE=postgresql://postgres:SNIP@db:5432/tavern?sslmode=disable' >> web.env
    
  4. Generate a somewhat random secret key for cookies.

      $ < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32} | md5sum | cut -d' ' -f1
      SNIP
      $ echo SECRET=SNIP >> web.env
    
  5. Set the rest of your web config. Be sure to change the "DOMAIN" config.

      $ cat >> web.env <<EOF
      ENABLE_SVGER=true
      ENABLE_PUBLISHER=true
      DOMAIN=your.domain
      SVGER=http://svger:9100/
      LISTEN=0.0.0.0:9000
      ASSET_STORAGE_REMOTE_DENY=*
      PUBLISHER=http://publisher:9200/
      EOF
    
  6. Create the init SQL file used to create the database when postgres starts.

      $ cat >> init.sql <<EOF
      CREATE DATABASE tavern;
      CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
      EOF
    
  7. Create and populate the docker-compose.yml file. Be sure to change the "YOUR_PRIVATE_IP" value to the private IP address of the host.

      $ cat >> docker-compose.yml <<EOF
      version: '3'
      services:
    
        db:
          restart: on-failure
          image: postgres:12-alpine
          networks:
            - internal_network
          healthcheck:
            test: ["CMD", "pg_isready", "-U", "postgres"]
          volumes:
            - ./init.sql:/docker-entrypoint-initdb.d/10-init.sql
            - ./postgres:/var/lib/postgresql/data
          env_file:
            - ./db.env
    
        svger:
          image: ngerakines/svger:1.1.0
          restart: on-failure
          networks:
            - internal_network
          healthcheck:
            test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:9100 || exit 1"]
            interval: 5m
            timeout: 10s
          ports:
            - "9100:9100"
          environment:
            - PORT=9100
    
        publisher:
          image: ngerakines/tavern:0.1.0-rc2
          restart: on-failure
          networks:
            - internal_network
          healthcheck:
            test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:9200 || exit 1"]
            interval: 5m
            timeout: 10s
          ports:
            - "9200:9200"
          environment:
            - LISTEN=0.0.0.0:9200
            - PUBLISHER_CALLBACK=ttp://web:9000/webhooks/publisher
    
        web:
          image: ngerakines/tavern:0.1.0-rc2
          restart: on-failure
          networks:
            - external_network
            - internal_network
          healthcheck:
            test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:9000 || exit 1"]
            interval: 5m
            timeout: 10s
          ports:
            - "YOUR_PRIVATE_IP:9000:9000"
          depends_on:
            - db
            - svger
          env_file:
            - ./web.env
          volumes:
            - ./assets:/assets
    
      networks:
        external_network:
        internal_network:
          internal: true
      EOF
    
  8. Start the database and wait for it to become available.

     $ docker-compose up -d db svger publisher
     $ docker-compose logs -f db
    
  9. Run database migrations.

     $ docker-compose run web migrate
    
  10. Create the admin user. Be sure to change the "YOUR_EMAIL", "YOUR_NAME", and "YOUR_PASSWORD" values.

    $ docker-compose run web init --admin-email=YOUR_EMAIL --admin-password=YOUR_PASSWORD --admin-name=YOUR_NAME
    
  11. Start the web service.

    $ docker-compose up -d
    
  12. Test that the service is accessible on the private IP.

    $ curl http://PRIVATE_IP:9000/
    
  13. Set caddy config to verify the load balancer proxies node requests.

    $ cat > /etc/caddy/caddy.conf <<EOF
    http://your.site {
      log / syslog "{combined}"
      errors syslog
      gzip
      root /usr/share/caddy
    }
    EOF
    $ cat > /etc/rsyslog.d/caddy.conf <<EOF
    if $programname == 'caddy' then /var/log/caddy.log
    & stop
    EOF
    
  14. Restart the caddy service and verify the node balancer marks the node as "up".

    $ systemctl restart caddy
    $ systemctl status caddy
    $ tail /var/log/caddy.log
    $ curl http://your.site/
    
  15. Update the caddy config to proxy to tavern, and restart the caddy service.

    $ cat > /etc/caddy/caddy.conf <<EOF
    tavern.town {
      tls YOUR_EMAIL
      bind PRIVATE_IP
      log / syslog "{combined}"
      errors syslog
      gzip
      root /usr/share/caddy
      proxy / PRIVATE_IP:9000 {
        transparent
      }
    }
    www.tavern.town {
      tls YOUR_EMAIL
      bind PRIVATE_IP
      log / syslog "{combined}"
      errors syslog
      gzip
      root /usr/share/caddy
      redir https://your.site{uri}
    }
    EOF
    $ systemctl restart caddy
    
  16. Done! When caddy starts up, it'll take a brief moment for the cert to be retrieved. Once that is done, you can access your site through your browser and you are good to go.