Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using a custom traefik toml file or template #543

Closed
hMED22 opened this issue Mar 30, 2020 · 7 comments · Fixed by #582
Closed

Using a custom traefik toml file or template #543

hMED22 opened this issue Mar 30, 2020 · 7 comments · Fixed by #582
Labels
enhancement New feature or request

Comments

@hMED22
Copy link

hMED22 commented Mar 30, 2020

I'm trying with @jhadjar to change the proxy config in /opt/tljh/state/traefik.toml but it is overwritten by traefik.toml.tpl every time the proxy is reloaded, is there any way to set a custom file or template to be used instead?

@mskblackbelt
Copy link

Seconded. I'm currently restoring from a backup file each time, but it doesn't seem like the process should be that difficult. Alternately, is there a (supported) way to place some configuration values in jupyterhub_config.d to have some data appended to the existing TOML file?

@jhadjar
Copy link

jhadjar commented Apr 7, 2020

Adding more context to @hMED22's issue. The problem lies in https://github.com/jupyterhub/the-littlest-jupyterhub/blob/master/tljh/traefik.py#L90

def ensure_traefik_config(state_dir):
    """Render the traefik.toml config file"""
    config = load_config()
    config['traefik_api']['basic_auth'] = compute_basic_auth(
        config['traefik_api']['username'],
        config['traefik_api']['password'],
    )

    with open(os.path.join(os.path.dirname(__file__), "traefik.toml.tpl")) as f:
        template = Template(f.read())

The problematic line gives no way to pass the template programmatically:

    with open(os.path.join(os.path.dirname(__file__), "traefik.toml.tpl")) as f:

@GeorgianaElena
Copy link
Member

Indeed, traefik.toml.tpl is meant to be modified through tljh-config (to the extent of an option being configurable at all).

Can you please explain a bit what's your use-case and how would modifying traefik.toml.tpl help?

Some of the config in traefik.toml has to be there for TLJH and traefik-proxy to be functional. However, I think it is possible to add an escape hatch to extend the traefik.toml template, similarly with how we do for the juptyerhub_config.py.
WDYT about this @yuvipanda?

@mskblackbelt
Copy link

I'm trying to set the rules.toml file to look like so:

[frontends]
  [frontends.default]
  backend = "backend__2F"
  passHostHeader = true
  priority = 80
    [frontends.default.routes.test]
    rule = "Path:/;AddPrefix:/hub"
    data = "{\"hub\": true}"

  [frontends.frontend__2F]
  backend = "backend__2F"
  passHostHeader = true
  priority = 90
    [frontends.frontend__2F.routes.rule1]
    # rule = "PathPrefix:/hub"
    rule = "Host: jupyter.example.com"

  [frontends.webmo]
  backend = "webmo"
  passHostHeader = true
  priority = 100
    [frontends.webmo.routes.rule1]
    # rule = "PathPrefix:/webmo"
    rule = "Host: webmo.example.com"

[backends]
  [backends.backend__2F]
    [backends.backend__2F.servers.server1]
    url = "http://127.0.0.1:15001"

  [backends.webmo]
    [backends.webmo.servers.server1]
    url = "http://webmo.example.com:8080"

I'd like to pass all addresses at jupyter.example.com to TLJH and everything at webmo.example.com to Apache which is hosting a WebMO installation. With this rules.toml file, it works, but TLJH (or Traefik?) periodically overwrites the file, breaking the Apache proxy.

I believe these rules (at least the WebMO ones) could be placed in the Traefik template file, but I'd like to try to keep within the tljh-config framework as much as possible.

@aolney
Copy link

aolney commented May 1, 2020

AFAIK rules.toml only gets overwritten with tljh-config reload proxy or during installation. If you need to reload the proxy, systemctl restart traefik should do the trick. Another possibility that I haven't tried would be to set a cron job to overwrite rules.toml with the correct config periodically. If you have set watch, then the changes should be automatically loaded.

@yuvipanda
Copy link
Collaborator

@GeorgianaElena yeah, an escape hatch sounds great, especially for web proxy config. Maybe something along the lines of jupyterhub/zero-to-jupyterhub-k8s#1636?

@GeorgianaElena GeorgianaElena added the enhancement New feature or request label May 4, 2020
@jhadjar
Copy link

jhadjar commented May 4, 2020

Can you please explain a bit what's your use-case and how would modifying traefik.toml.tpl help?

Sure. The issues encountered serving JupyterLab static files on slow, unstable, internet connections lead us to look into two things:

    1. Compression
    1. Caching

We failed to enable compression at the jupyterhub_config.py level (Tornado settings), as per https://github.com/tornadoweb/tornado/blob/18d7026853900c56a1879141235c6b6bd51b0a6a/tornado/web.py#L2044

c.JupyterHub.tornado_settings = {
    'headers': {
        'Content-Security-Policy': f"frame-ancestors 'self' {os.getenv('XXX_URL', '*')}",
    },
    'compress_response': True,
    # 'gzip': True,
    # We have also tried the previouly supported parameter 'gzip'
}

This did not work, which lead us to enable compression at the Traefik level:

# traefik.toml

[entryPoints.https]
address = ":8080"
compress = true      # <--------- Add this line

tljh overrides this with the line we feel hard codes the template file and reduces flexibility at https://github.com/jupyterhub/the-littlest-jupyterhub/blob/master/tljh/traefik.py#L90:

    with open(os.path.join(os.path.dirname(__file__), "traefik.toml.tpl")) as f:

Is there a reason this is hard-coded? Given that the function ensure_traefik_config loads a config, is it not sensible to make the config it loads a parameter of the function before touching other parts of the system?

Something like this:

DEFAULT_TOML_TEMPLATE = os.path.join(os.path.dirname(__file__), "traefik.toml.tpl")
TRAEFIK_TOML_TEMPLATE = os.environ.get('TRAEFIK_TOML_TEMPLATE', DEFAULT_TOML_TEMPLATE)

def ensure_traefik_config(state_dir, traefik_toml_template=None):
    ...
    traefik_toml_template = traefik_toml_template or TRAEFIK_TOML_TEMPLATE
    with open(traefik_toml_template) as f:
        template = Template(f.read())
    ...

One way to do that according to @hMED22 is:

# jupyterhub_config.py
c.TraefikTomlProxy.toml_dynamic_config_file = dynamic_conf_file_path

and changing

-c {install_prefix}/state/traefik.toml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants