Repository navigation
fix: entrar no painel deixa de ser um enigma, e as portas deixam de colidir #7
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,8 +37,89 @@ request; a push to `master` republishes the wiki automatically. | |
|
|
||
| --- | ||
|
|
||
| --- | ||
|
|
||
| ## 🔑 Como entrar no painel | ||
|
|
||
| | | | | ||
| | :--- | :--- | | ||
| | **Endereço** | `http://localhost:9092` | | ||
| | **Usuário** | `admin` — ou o que você definir em `DASHBOARD_USER` | | ||
| | **Senha** | o valor de `DASHBOARD_PASSWORD` no seu `.env` | | ||
|
|
||
| **Não existe senha de fábrica**, e isso é deliberado: uma senha fixa publicada | ||
| na imagem vira credencial pública no instante em que a imagem é publicada. Você | ||
| escolhe a sua uma vez, num lugar só: | ||
|
|
||
| ```bash | ||
| cp .env.example .env | ||
| # edite o .env: | ||
| DASHBOARD_USER=admin | ||
| DASHBOARD_PASSWORD=<a senha que voce escolher> | ||
| ``` | ||
|
|
||
| Suba a stack em seguida. Esse usuário e essa senha são o que o painel aceita. | ||
|
|
||
| ### Subiu sem definir senha e agora não entra? | ||
|
|
||
| No primeiro boot com `DASHBOARD_PASSWORD` vazio, o container gera uma | ||
| **credencial de recuperação** e a grava dentro do diretório de dados. Leia com: | ||
|
|
||
| ```bash | ||
| docker exec ominirtksync cat /app/data/.dashboard_recovery | ||
| ``` | ||
|
|
||
| Entre como `admin` com esse valor e defina a sua senha pela tela. A credencial | ||
| de recuperação continua valendo depois disso — ela é o arrombamento de vidro, e | ||
| uma que parasse de funcionar assim que você define uma senha seria inútil | ||
| justamente quando é necessária. | ||
|
|
||
| > **English:** the panel asks for user and password. The user is `admin` (or | ||
| > whatever `DASHBOARD_USER` says) and the password is the one **you** set in | ||
| > `DASHBOARD_PASSWORD` — there is no factory password, because a fixed value | ||
| > shipped in an image is a public credential. If you brought the stack up | ||
| > without setting one, use the command above to read the recovery credential. | ||
|
|
||
| ## Como Executar via Docker | ||
|
|
||
| ### Configuração: `.env` a partir do exemplo | ||
|
|
||
| A configuração inteira vem de variáveis de ambiente, lidas de um `.env` ao lado | ||
| do `docker-compose.yml` — o Compose o encontra sozinho, sem nenhuma flag. | ||
|
|
||
| ```bash | ||
| make setup # cria o .env a partir do .env.example, sem sobrescrever um existente | ||
| ``` | ||
|
|
||
| O alvo lista, ao final, exatamente quais variáveis ficaram em branco e precisam | ||
| ser preenchidas. Preencha e suba a stack. | ||
|
|
||
| O `.env` **nunca** é versionado, e o `.env.example` não carrega nenhum valor de | ||
| segredo — um valor publicado num arquivo de exemplo é, por definição, uma | ||
| credencial pública. Um teste garante que toda variável exigida por um compose | ||
| existe no exemplo, para que `cp .env.example .env` nunca produza um `.env` | ||
| incompleto. | ||
|
|
||
| ### Portas, e por que cada uma é diferente | ||
|
|
||
| Os três sincronizadores escutam na **mesma porta dentro do container** (`9090`) | ||
| e publicam em portas diferentes no host, para que os três possam rodar lado a | ||
| lado. O mesmo vale para os gateways: cada um tem a sua. | ||
|
|
||
| | Serviço | Porta interna | Publicada no host | | ||
| | :--- | :--- | :--- | | ||
| | 9Router | `20128` | `20128` | | ||
| | OmniRoute | `20128` | `20129` | | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The new table says OmniRoute is published on Useful? React with 👍 / 👎. |
||
| | LiteLLM | `4000` | `20130` | | ||
| | 9RTKSync (painel) | `9090` | `9091` | | ||
| | OminiRTkSync (painel) | `9090` | `9092` | | ||
| | LiteLlmRTKSync (painel) | `9090` | `9093` | | ||
|
|
||
| Tudo preso a `127.0.0.1`: o gateway carrega credenciais reais e não deve ficar | ||
| acessível na rede local. Para mudar qualquer uma, altere o lado esquerdo do | ||
| mapeamento no compose — o lado direito é a porta interna, que o processo escuta. | ||
|
|
||
|
|
||
| O pacote Docker oficial do OminiRTKSync é distribuído via GitHub Container Registry (GHCR): | ||
|
|
||
| ```bash | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| """Toda variável que um compose exige precisa existir no .env.example. | ||
|
|
||
| O fluxo documentado é `cp .env.example .env`, preencher e subir. Se o compose | ||
| usa uma variável que o exemplo não menciona, esse fluxo produz um `.env` | ||
| incompleto: ou a stack recusa subir com `variable is not set`, ou — pior — sobe | ||
| com um default silencioso que ninguém escolheu. | ||
|
|
||
| Foi exatamente o que aconteceu com o painel: o compose de teste não passava | ||
| `DASHBOARD_PASSWORD`, e não havia como definir a senha pelo `.env`. | ||
| """ | ||
|
|
||
| import os | ||
| import re | ||
| import unittest | ||
|
|
||
| RAIZ = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ||
|
|
||
| # ${VAR}, ${VAR:-default}, ${VAR:?mensagem} | ||
| RX_USO = re.compile(r"\$\{([A-Z][A-Z0-9_]*)[:}?-]") | ||
| RX_DECLARA = re.compile(r"^\s*#?\s*([A-Z][A-Z0-9_]*)=", re.M) | ||
|
|
||
|
|
||
| def composes(): | ||
| for nome in os.listdir(RAIZ): | ||
| if nome.startswith("docker-compose") and nome.endswith((".yml", ".yaml")): | ||
| yield os.path.join(RAIZ, nome) | ||
|
|
||
|
|
||
| def declaradas_no_exemplo(): | ||
| caminho = os.path.join(RAIZ, ".env.example") | ||
| with open(caminho, encoding="utf-8") as f: | ||
| return set(RX_DECLARA.findall(f.read())) | ||
|
|
||
|
|
||
| class TestExemploCobreOsComposes(unittest.TestCase): | ||
| def test_every_variable_a_compose_needs_exists_in_the_example(self): | ||
| declaradas = declaradas_no_exemplo() | ||
| faltando = {} | ||
| for c in composes(): | ||
| with open(c, encoding="utf-8") as f: | ||
| usadas = set(RX_USO.findall(f.read())) | ||
| ausentes = sorted(usadas - declaradas - {"HOME", "PWD", "USER"}) | ||
| if ausentes: | ||
| faltando[os.path.basename(c)] = ausentes | ||
| self.assertEqual( | ||
| faltando, | ||
| {}, | ||
| "variáveis exigidas por um compose e ausentes do .env.example: " + str(faltando), | ||
| ) | ||
|
|
||
| def test_the_panel_credentials_are_offered_by_the_example(self): | ||
| # O caminho de entrada no painel tem de estar no exemplo, senão quem | ||
| # copia o arquivo não descobre que essas variáveis existem. | ||
| declaradas = declaradas_no_exemplo() | ||
| for v in ("DASHBOARD_USER", "DASHBOARD_PASSWORD"): | ||
| self.assertIn(v, declaradas, f"{v} precisa aparecer no .env.example") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
make setupis used withdocker-compose.example.yml, this copiesOMNIROUTE_URL=http://127.0.0.1:20128from.env.example; Compose then substitutes it instead of the service-name defaulthttp://omniroute:20128. Inside theominirtksynccontainer,127.0.0.1refers to that container rather than OmniRoute, so the gateway probe fails and/healthzreturns 503. The generated configuration needs a Compose-safe gateway URL, or the Compose service should not consume this host-only value.Useful? React with 👍 / 👎.