rapiz1 / rathole

A lightweight and high-performance reverse proxy for NAT traversal, written in Rust. An alternative to frp and ngrok.
Apache License 2.0
9.8k stars 488 forks source link

[Docker] Configure with env vars #218

Open williamhatcher opened 1 year ago

williamhatcher commented 1 year ago

Feature Proposed Is it possible to allow configuration via env vars in the docker image, or something other than a file?

Use Case Running rathole in a Portainer instance. Portainer doesn't allow you to attach files to a docker compose stack.

rapiz1 commented 1 year ago

This is a very interesting idea. But given the rathole configuration format is not trivial, how can you do that in env vars? Do you have any proposals? Maybe we can pass config string in a single env var but I wonder if there's a length limit for env var that renders many configurations unpractical.

I'm not familiar with Portainer. What does other software do? I think many software requires a configuration more than two lines of username and password to work.

Skaronator commented 1 year ago

A quick google search says that there is basically no length limit for this usecase. Some results say around 32k characters on Windows, while linux has over 256 MB per/for all? Environment variables. Basically, endless for this usecase.

I'd suggest that . is replaced by one _ and [header] and configBody seperated by two __:

[client]
remote_addr = "example.cm"
default_token = "xyz"

[client.transport]
type = "noise"

[client.transport.noise]
pattern = "Noise_KK_25519_ChaChaPoly_BLAKE2s"

[client.services.http]
local_addr = "ingress-nginx-public-controller:80"

[client.services.https]
local_addr = "ingress-nginx-public-controller:443"

CLIENT__REMOTE_ADDR = "example.cm"
CLIENT__DEFAULT_TOKEN = "xyz"

CLIENT_TRANSPORT__TYPE = "noise"

CLIENT_TRANSPORT_NOISE__PATTERN = "Noise_KK_25519_ChaChaPoly_BLAKE2s"

CLIENT_SERVICES_HTTP__LOCAL_ADDR = "ingress-nginx-public-controller:80"

CLIENT_SERVICES_HTTPS__LOCAL_ADDR = "ingress-nginx-public-controller:443"
jingkang99 commented 1 year ago

env var is a good idea, nice to have.

Skaronator commented 1 year ago

Just found this project. It is also written in rust and uses TOML as config file format but allows overwriting everything via environment variables. https://github.com/romanz/electrs/blob/master/doc/config.md#electrs-configuration

rapiz1 commented 1 year ago

A quick google search says that there is basically no length limit for this usecase. Some results say around 32k characters on Windows, while linux has over 256 MB per/for all?

In that case, can we have a single entry for the configuration? The format you propose looks very powerful and flexible but I'm afraid it can bother users

Skaronator commented 1 year ago

A single environment variable would be fine too. Gitlab Omnibus Image does that too and the config can get long as well.

rapiz1 commented 1 year ago

So we have a proposed solution here. Anyone is welcomed to implement this feature. I would like the env var is named as RATHOLE_CONFIG_STR or something alike

nemanjam commented 5 months ago

Can I pass keys and secret to .toml from .env file?

Skaronator commented 5 months ago

Nope

pauloromeira commented 3 months ago

I believe the most versatile solution is to use some sort of template syntax to insert env variable values into the config file, similar to what is implemented by frp. This makes it possible to bind any env variable to any config field.

Example:

[client]
remote_addr = "{{ env:RH_REMOTE_ADDR }}"
default_token = "{{ env:RH_DEFAULT_TOKEN }}"
export RH_REMOTE_ADDR="x.x.x.x"
export RH_DEFAULT_TOKEN="token"

rathole --client config.toml

With docker-compose you can bind mount the config file and add env variables in the "environment" section.

As for Portainer, I think development should not be oriented towards overcoming limitations of a third-party software.

rucciva commented 3 months ago

I believe the most versatile solution is to use some sort of template syntax to insert env variable values into the config file, similar to what is implemented by frp. This makes it possible to bind any env variable to any config field.

Example:

[client]
remote_addr = "{{ env:RH_REMOTE_ADDR }}"
default_token = "{{ env:RH_DEFAULT_TOKEN }}"
export RH_REMOTE_ADDR="x.x.x.x"
export RH_DEFAULT_TOKEN="token"

rathole --client config.toml

With docker-compose you can bind mount the config file and add env variables in the "environment" section.

As for Portainer, I think development should not be oriented towards overcoming limitations of a third-party software.

This is also how vector (which also made with rust) implements it

pauloromeira commented 2 months ago

This is also how vector (which also made with rust) implements it

@rucciva neat reference! thanks.

I found that vector uses one simple function to interpolate variables into a string - here is where it is called.

murlakatamenka commented 1 month ago

@pauloromeira good find about vector's interpolation! Ready implementation from reputable source with enough test cases :+1: