-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Running hasura console via CLI in docker container #2824
Comments
This is a known issue and we have some potential solutions. The console served by CLI is designed to be run from a developers machine and not from any sort of webserver. Will you be able to elaborate on what the use case here is, where you're unable to run the hasura cli locally? |
We have packages that don't install/build under windows, which is why we develop in linux docker containers. |
Are you saying the hasura CLI doesn't work on Windows? |
Or it is just a matter of convenience where you'd prefer everything to be inside docker containers? |
It's a matter of convenience. We wouldn't use Hasura/Postgres if they weren't available in official docker images. Development has to be done in a linux based container anyways, because parts of it don't work on windows. We could possibly run the hasura CLI on windows, but that'd be a pain to do (no automatic installation, having it connect to graphql-engine running in a container, being forced to link files into the dev container etc). Aside from that, we get "An attempt was made to access a socket in a way forbidden by its access permissions" by the windows executable and i can't tell why. Might be a windows/network/firewall configuration thing - which i might be able to fix, but which might also be company wide settings? |
Got it. We'll ideate on how we can make the experience smoother. 😀 For migrations you'd have to mount the directory inside the container anyway. Do let us know if there's an ideal workflow that you would like see. Helps in our ideation/brainstorming 😄 |
It'd probably be okay if there were additional options for the URLs the console's javascript is connecting to, something like I know the naming is off, but you get the idea 😉 |
Thanks @codepunkt. We have an implementation at #1780 and we should get to merging it soon. |
I'm having a similar issue as well. In my case, it's the ServiceWorker (/sw.js) that the console is trying to fetch, but the hasura is upstream on a different path, so it 404s. I haven't delved into it yet, but from some quick searching on this repo, it looks like the console is using CRA? If so, then you should be able to inject the appropriate PUBLIC_URL environment variable (although I can't remember off the top of my head if this only happens during build-time or if applies at run-time as well). Another option would be to let nginx configure a header using proxy_set_header, and then read that in hasura and pass it onto CRA. This approach is more flexible since it keeps that config where it's relevant, in nginx.conf. Anyway, just my $0.02. Not a show stopper in my case because it's just the service worker that's not loading, and from the looks of it, it's not mandatory. |
I'd like to chime in and say I'd love to be able to serve the console from the same docker-compose file as I do the hasura instance itself. |
is there a workaround to do this without this pull request or creating a new container by my own?
The port 8081 is binded for my container, but I receive in my browser.
I have this configuration for docker-compose
|
We're ideating on a simpler solution for this where all CLI APIs are protected by admin secret and all that needs to be done is to expose them correctly. |
Same as @Sevensidedmarble - for convenience we'd love to just run the console and track migrations from docker-compose, instead of introducing the Hasura CLI tool. The CLI tool itself has its uses obviously, but for some colleagues and responsibilities it'd be great to have one less boundary here. Regardless, great work on this and thanks! Super useful service. |
It looks like #3570 is pretty close, will that add the feature we want? And if so what's the time table on merging? |
@Sevensidedmarble Yes, #3570 will address this issue. We're blocked on some console related changes for this to go in. Expecting to be in 1.3 or 1.4 release. |
@kevintelford What is your current workaround for this? Make migrations on a local instance and sync with version control? |
Hello, any idea on when it will be solved? Or a workaround while waiting? |
What's the status on this? We're running hasura inside kubernetes, and would like to avoid exposing our hasura endpoint publicly but still access the console. To access the console in such a situation, we would like to run hasura console \
--endpoint 'http://localhost:8001/api/v1/namespaces/staging/services/hasura/proxy' \
--admin-secret '<our-special-secret>' Right now this works in that the cli program is able to auth correctly ( I see that from above the plan to proxy requests through the cli (#1440) was abandoned in favor of #3570, which also seems to have been abandoned as of July of this year. What do you recommend we do? I would really like to not publicly expose our hasura instance if at all possible (in our own webapp we proxy requests to it through our backend). |
If you're running the console in a docker container, you can work around it by installing socat TCP-LISTEN:8080,fork TCP:host.docker.internal:8080 & hasura console --console-port 8081 Assuming you published port That's my temporary workaround. |
I'm also searching for a solution to this. |
Based on your example and with some modifications it has worked for me.
FROM ubuntu:20.04
RUN apt-get update -y && apt-get install -y curl socat
RUN curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash
WORKDIR /usr/src/hasura
COPY . .
RUN chmod +x ./start.sh
CMD "./start.sh"
#!/bin/bash
cd /usr/src/hasura || {
echo "Hasura folder '/usr/src/hasura' not found"
exit 1
}
# temporal fix to workaround: https://github.com/hasura/graphql-engine/issues/2824#issuecomment-801293056
socat TCP-LISTEN:8080,fork TCP:ext_graphql:8080 &
socat TCP-LISTEN:9695,fork,reuseaddr,bind=svc_hasura_console TCP:127.0.0.1:9695 &
socat TCP-LISTEN:9693,fork,reuseaddr,bind=svc_hasura_console TCP:127.0.0.1:9693 &
{
# Apply migrations
hasura migrate apply || exit 1
# Apply metadata changes
hasura metadata apply || exit 1
# Run console if specified
if [[ -v HASURA_RUN_CONSOLE ]]; then
echo "Starting console..."
hasura console --log-level DEBUG --address "127.0.0.1" --no-browser || exit 1
else
echo "Started without console"
tail -f /dev/null
fi
}
version: "3.7"
volumes:
database-data:
services:
ext_db:
image: postgres:12
volumes:
- database-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
ext_graphql:
image: hasura/graphql-engine:v1.3.3
ports:
- "8080:8080"
depends_on:
ext_db:
condition: service_healthy
environment:
HASURA_GRAPHQL_DATABASE_URL: "postgres://postgres:${POSTGRES_PASSWORD}@ext_db:5432/postgres"
HASURA_GRAPHQL_ENABLE_CONSOLE: "false"
HASURA_GRAPHQL_DEV_MODE: "true"
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8080/healthz || exit 1"]
interval: 5s
timeout: 3s
retries: 5
svc_hasura_console:
build:
context: .
ports:
- "9693:9693"
- "9695:9695"
environment:
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
HASURA_GRAPHQL_ENDPOINT: http://localhost:8080
HASURA_RUN_CONSOLE: "true"
volumes:
- ./metadata:/usr/src/hasura/metadata
- ./migrations:/usr/src/hasura/migrations
depends_on:
ext_graphql:
condition: service_healthy Thansk! |
I am happy to confirm that this works with the latest version of hasura. Here's a working example of a You should be able to access the console at version: '3.9'
services:
db:
image: postgres:14.2
healthcheck:
test: ['CMD', 'pg_isready', '-d', 'komodo', '-U', 'postgres']
environment:
POSTGRES_INITDB_ARGS: --data-checksums
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
hasura:
image: hasura/graphql-engine:v2.19.0.cli-migrations-v3
volumes:
- ./migrations:/hasura-migrations
- ./metadata:/hasura-metadata
healthcheck:
test: timeout 1s bash -c ':> /dev/tcp/127.0.0.1/8080' || exit 1
depends_on:
db:
condition: service_healthy
environment:
HASURA_GRAPHQL_ENABLE_CONSOLE: 'false'
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgres@db:5432/postgres
HASURA_GRAPHQL_ADMIN_SECRET: secret
ports:
- '8080:8080'
hasura_console:
image: hasura/graphql-engine:v2.19.0.cli-migrations-v3
volumes:
- .:/app
healthcheck:
test: timeout 1s bash -c ':> /dev/tcp/127.0.0.1/9695' || exit 1
working_dir: /app
command: hasura-cli console
--no-browser
--endpoint http://hasura:8080
--admin-secret secret
--address 0.0.0.0
--console-port 9695
--api-port 9693
--console-hge-endpoint http://localhost:8080
ports:
- '9695:9695'
- '9693:9693'
depends_on:
hasura:
condition: service_healthy
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgres@db:5432/postgres |
Thanks @27medkamal for this. I can't seem to get the above working. The console will launch but it can't find the server. The following error is thrown inside the console.
Any idea why this may be? I also had to add a health check to prevent the console from starting too early |
@samfweb You're on the right track. I've added the healthchecks to my comment above which should now work. I initially tested it with the healthchecks but thought I'd remove them in order not to bloat the snippet, but I've added them and it should now work. |
@samfweb Also I'd suggest running this with a blank hasura project created using |
@samfweb could you please check if the admin secret is correct? The error seems to be hinting towards it: |
@27medkamal I've created a completely blank project and I'm still running into a heap of errors. It seems like some of the flags aren't making their way into the console properly. In the screenshot below, you can see it's trying to reach Thanks for the tip @m-Bilal, somehow my local storage was overwriting the request headers. Clearing my local storage helped fix that error. |
@m-Bilal It looks like |
@27medkamal You're right, the errors are unrelated to running the console from inside a container. @samfweb, could you please try using the console from another browser and checking if it works fine? |
@m-Bilal thanks for the update on this. I have a use case where we're using Gitpod. As such the publically accessible addresses are all port 443, e.g. Edit: and yes I know we can use the companion for local port forwarding, but that's a workaround and only when I'm working on my PC. |
Apologies for the delayed response @m-Bilal I tried it on both Chrome and Brave with the same result. |
Running hasura console in a docker-container on windows (using docker-desktop in WSL2 configuration) has multiple issues for us. Passing It seems that maybe the reason for why these tabs does not work is that the console tries to fetch data from http://0.0.0.0:9693/apis/migrate/settings, but this yields an |
@andoks I am facing exactly the same issue, did you figure out how to fix it ? |
@badis No, the GraphiQL tab worked on Windows for us, while the rest of the tabs also works on Linux, so we are just making do with that for now. I hope it eventually gets fixed though, or else we might have to consider a different approach than putting the hasura cli in a docker image. |
I might have a solution! I have been running into this same/similar issue, trying to launch the console from a VS Code SSH session. I found that VSC was porting 9695 automatically when the command was run, but was not porting 9693. I manually added that port to the forwarding, and now the call to It seems like this is new, either 9693 was getting automatically added to forwarded ports before, or the calls to the above URL were on 9695. |
Sorry folks, I lost track of this. I'll be looking into these and getting back to you in the next couple weeks. |
I am facing the exact same problem, but in Linux. Using Ubuntu 18:04. Hasura Console: 2.28.0 # entrypoint.sh
hasura console \
--endpoint $HASURA_GRAPHQL_ENDPOINT \ # http://hasura:8080 graphq engine container
--admin-secret $HASURA_GRAPHQL_ADMIN_SECRET \
--address 0.0.0.0 \
--console-hge-endpoint http://localhost:8080 \ # not sure localhost is right here but it is the only way to run the console, otherwise the container crashes
--log-level $HASURA_CLI_LOG_LEVEL \
--no-browser || exit 1 |
Instead of listening on address '0.0.0.0', you can set the console server to listen on the container's IP as shown below: version: "3.8"
services:
graphql-engine:
image: hasura/graphql-engine:v2.30.1-ce.cli-migrations-v3
ports:
- 8080:8080
environment:
## postgres database to store Hasura metadata
HASURA_GRAPHQL_METADATA_DATABASE_URL: <POSTGRES_CONNECTION_STRING>
## this env var can be used to add the above postgres database to Hasura as a data source. this can be removed/updated based on your needs
PG_DATABASE_URL: <POSTGRES_CONNECTION_STRING>
## enable the console served by server
HASURA_GRAPHQL_ENABLE_CONSOLE: "false" # set to "false" to disable console
## enable debugging mode. It is recommended to disable this in production
HASURA_GRAPHQL_DEV_MODE: "true"
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
## uncomment next line to run console offline (i.e load console assets from server instead of CDN)
HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: /srv/console-assets
## uncomment next line to set an admin secret
HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
healthcheck:
test: nc -z localhost 8080
interval: 5s
timeout: 5s
start_period: 10s
console:
depends_on:
graphql-engine:
condition: service_healthy
image: hasura/graphql-engine:v2.30.1-ce.cli-migrations-v3
ports:
- 9695:9695
- 9693:9693
volumes:
- ./hasura:/hasura
working_dir: /hasura
entrypoint:
[
'sh',
'-c',
'hasura-cli console --no-browser --address `hostname -i` --endpoint http://graphql-engine:8080 --console-hge-endpoint http://localhost:8080',
]
environment:
HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey I think the problem can be solved by updating the following: graphql-engine/cli/commands/console.go Line 139 in 4d86cd3
- apiServer, err := console.NewAPIServer(o.APIHost.Host, o.APIPort, o.EC)
+ apiServer, err := console.NewAPIServer(o.Address, o.APIPort, o.EC) |
@ranjan-purbey: Do you know if this will work when running on docker-desktop for windows, which runs the docker containers on what is essentially a linux VM? |
@andoks I have updated my comment to work without having to use the 'host' network driver. Now it should work on all docker distributions including windows |
@ranjan-purbey : I tried to get it working locally with docker+docker-compose (I did not test your config literally, but copied the console service config and adapted it), but failed. What I observed that seemed really weird, is that when opening the console in my browser (firefox) localhost:9695, what I assume is the index html loaded ok, but the console instructs the browser to fetch further resources (like console/assets/versioned/main.css.gz) from the address I gave to the --console-hge-endpoint flag, which is wrong (assuming my understanding of --console-hge-endpoint flag being right: the URL where the console loaded in the browser can reach the HGE API) - the api does not have any of the console static resources. When I removed the --console-hge-endpoint flag, the console html page then tried to load the resources from the address I specified to the --endpoint flag (which if I have understood it correctly should be the address the hasura CLI tool, now running inside a docker-compose system, can reach the HGE API), which is if anything even more wrong, since this address is an address only reachable from within the docker-compose system, and even if it was reachable, would not serve the static resources for the hasura console. |
@andoks can you please share the compose file you used for this? |
@ranjan-purbey do you mean the full setup? Unfortunately I cannot share that, and will have to make minimal reproduction at some point if you want me to reproduce it. This is the service file with some redactions that I used for the console testing it with my system. But is it expected of the hasura console feature that the --endpoint and --console-hge-endpoint changes where the console attempts to retrieve the static assets from? I would assume you could reproduce that just by changing the value you pass to --console-hge-endpoint in your own example, and if when you open the console in your browser and open the developer console, the console does not attempt to fetch resources from the address you passed to --console-hge-endpoint, then something is wrong with my setup, but if it does so on your setup too, then it might be a bug unless it is intended to to this (in which case I have misunderstood what the --console-hge-endpoint flag is used for entirely) version: "3.6"
# context and file paths are specified starting at PWD, and PWD is required to
# be repository root
services:
console:
depends_on:
project-hasura:
condition: service_healthy
image: hasura/graphql-engine:v2.30.1-ce.cli-migrations-v3
ports:
- 9695:9695
- 9693:9693
volumes:
- ${PWD}/hasura-server:/hasura
working_dir: /hasura
entrypoint:
[
'sh',
'-c',
'hasura-cli console --no-browser --address `hostname -i` --endpoint http://hasura:8080 --console-hge-endpoint http://192.168.202.102:9695',
]
environment:
HASURA_GRAPHQL_ADMIN_SECRET: "<some secret>" |
Hello!
I'm trying to run
hasura console
in docker container no#1 and then access the console on port9695
on my host machine.The JavaScript of the hasura console application needs access to both the graphql engine (running in docker container no#2) and the migration service spun up by running
hasura console
in docker container no#1.The URLs that the JavaScript tries to talk to are based on two things:
endpoint
configuration ofconfig.yaml
in docker container no#1--address
flag used to starthasura console
with in docker container no#1, which defaults to localhost when not set.Because the hasura console application is only available inside docker container no#1 when started with the default
--address
of "localhost", but is not available on the host machine of docker container no#1, i need to start it with--address 0.0.0.0
to have it bind to all available interfaces so it's not only reachable inside of container no#1, but also on the host machine.Because the graphql engine is running in docker container no#2, which happens to be set up in a
docker-compose.yml
with docker container no#1 and a third run running postgres, i need to configure theendpoint
inconfig.yaml
to the docker compose service name of the second container, which isendpoint: http://graphql-engine:8080
.This is the only configuration where the console actually starts, because it can access docker container no#2 from docker container no#1 and where the started console is then actually reachable by my docker host, because it is bound to all available interfaces.
The problem:
The console web application now tries to talk to both
http://graphql-engine:8080
andhttp://0.0.0.0
when accessed from the browser of my host machine - both of which are not available.You can work around the first of those requests by having both container no#1 and container no#2 on the same network, so the graphql engine can be reached with
endpoint: http://localhost:8080
- which also works on the docker host when port8080
is exposed to the host.I did not find any workarounds for the
--address
and the resulting requests to0.0.0.0
though. Is there anything that i'm missing?Would it be possible to add another configuration option to differentiate between the interfaces the graphql engine is actually served on and the URL that the clientside javascript uses to access it?
The text was updated successfully, but these errors were encountered: