Open VagyokC4 opened 1 year ago
I see now it's looking for webdis.prod.json
, not webdis.json
I'm glad you figured it out. By the way, it does use webdis.prod.json
because that's just what the command is set to in the Dockerfile
, but you can certainly replace it when you run Webdis.
The docker run
command you shared above uses the following mount:
-v d:/redis-data/webdis/webdis.json:/etc/webdis.json
This is the right way to inject the file, but you left the command (CMD
) to its default value, which also means that it will start a Redis instance in the container – although it won't be used for anything. See here: https://github.com/nicolasff/webdis/blob/f4efbfd3349fd94a3dfa1081f1537de99dadb510/Dockerfile#L21
To use your own config file, you just need to tell docker run
what command to start the container with, after giving it the name of the image. In your case, you can keep the injected file as /etc/webdis.json
and run Webdis with its path as a parameter, like this:
docker run -d --name Webdis --restart=unless-stopped -p 7379:7379 -v d:/redis-data/webdis/webdis.json:/etc/webdis.json nicolas/webdis /usr/local/bin/webdis /etc/webdis.json
I'll be adding a documentation page shortly that will provide detailed steps for how to run Webdis with an external Redis instance. This use case seems common enough that it's worth having a dedicated page for.
I'm glad you figured it out. By the way, it does use
webdis.prod.json
because that's just what the command is set to in theDockerfile
, but you can certainly replace it when you run Webdis.
Yeah I was going in circles for a min. trying to figure out why I was reading/writing from Postman, but nothing appeared in my redis instance. Once I saw it was using .prod.json all became clear and worked as expected.
I'll be adding a documentation page shortly that will provide detailed steps for how to run Webdis with an external Redis instance. This use case seems common enough that it's worth having a dedicated page for.
Maybe make an image that is ONLY Webdis (webdis-server), without the redis bits? For my use case we will create Pods that run this image so the lighter the better.
I could see a webdis (what you have now), a webdis-stack which would embed the redis stack, and a webdis-server which is only webdis. The only other suggestion is to maybe go though and add the all new Redis commands so that manually adding them to the config is not necessary. Thoughts?
Maybe make an image that is ONLY Webdis (webdis-server), without the redis bits?
Yes, I've thought about it too. I'll look into it next time I prepare a release. My goal with the Docker images was really to make it as simple as possible to try out Webdis, but I realize that this isn't really the image you'd want to use if you're using Webdis within an existing architecture.
Another benefit of this is that while the images are already tiny (Docker Hub says 8.23 MB for the current latest
) they would be even smaller without embedding Redis.
In the meantime I'll take a look at how other "connected" services build their images; by this I mean services/software that you would generally not run on its own but with the service connecting to other instances in the environment, instances it depends on. Docker Compose provides a reasonably simple way to do this, but I'm not sure whether it would be what Webdis users expect to use.
As for this point:
The only other suggestion is to maybe go though and add the all new Redis commands so that manually adding them to the config is not necessary.
I'm not sure what you mean here. By default Webdis disables the DEBUG
command (because of the baffling existence of DEBUG SEGFAULT
which was introduced before enable-debug-command
).
The default acl
config also provides an example of how to use basic auth for HTTP requests: https://github.com/nicolasff/webdis/blob/f4efbfd3349fd94a3dfa1081f1537de99dadb510/webdis.prod.json#L15-L24
If you want all commands to be allowed, just remove any entry under acl
that disables commands. This config lets you execute any command, for example:
"acl": [ ],
Disabling only DEBUG
should not affect FT.<something>
commands, they should be allowed. Now that enable-debug-command
exists, "acl": []
might be a better default value to use.
There is also a wildcard "*"
command to match all, if you want to create a super user for example. That said, the ACL feature in Webdis was added way back in 2011, when Redis didn't have an ACL
command. These days it might be better to configure all this within Redis itself.
Yes, I stand corrected. The issues I faced were purely the bad configuration. I can confirm that no commands needed to be enabled in the configuration for it to work.
Cool, I'm glad it worked.
By the way, I've made some final tweaks to the docs page I mentioned on the other GitHub issue and pushed it. I've listed it first in the docs README since it feels like a common use case, with the title "Running Webdis in Docker with an external Redis instance".
This is not the first GitHub issue in recent months where a question eventually led to a docs page; I hope these can be useful. I still need to make the docs more prominent on the repo's main page, but first need to review the README to see if it might make sense to extract more of it there. In any case, thanks for bringing this up! It made Webdis better :-)
Hi @nicolasff I was putting together a linqpad example for you and started running into some issues again.
using this config
{
"redis_host": "localhost",
"redis_port": 63791,
"verbosity": 8,
"logfile": "/dev/stdout",
"http_host": "0.0.0.0",
"http_port": 7379,
"threads": 5,
"pool_size": 20,
"daemonize": false,
"websockets": false,
"acl": [
{
"disabled": ["DEBUG", "FLUSHALL", "FLUSHDB"],
"http_basic_auth": "*:*"
}
]
}
I'm using this image
docker run -d --name Redis-Stack-7-AOF -v c:/redis-data/:/data/ --restart=unless-stopped -e REDIS_ARGS="--save --appendonly yes" -e REDISEARCH_ARGS="MAXSEARCHRESULTS -1 MAXAGGREGATERESULTS -1 MAXDOCTABLESIZE 3000000 TIMEOUT 0" -p 63791:6379 redis/redis-stack-server:latest
which I can connect to externally, no problem
But webdis is giving me 503 service unavailable.
However, I can connect to other instances and it works no problem.
And I can change the docker command above to use the default redis port 6379 and it all works as well.
I have verbose on 8, yet I'm not seeing anything that would tell me what the problem is (while pointing to 63791). Any ideas?
I'm wondering if the internal instance of Redis that webdis has is conflicting here.
I can confirm things work when I'm using a Redis not on my localhost. I can still reproduce the GET/POST issue, but my workaround seems to get me a result.
While using localhost instances, while I was able to PING the underlying redis, trying to execute some RedisStack commands give error
Which makes me think Webdis is pointing to it's internal instance even though from my outside host I can hit the redis stack instance using localhost:6379
. I think this also explains why when I wire up to 63791, it cannot find a redis sitting there, because inside the docker instance it can't get to 63791.
Were you able to put together a -server
image that does not include the internal Redis instance / internal network? That may help eliminate some of the not needed moving pieces.
Hey Charles, sorry I had missed this issue.
Which makes me think Webdis is pointing to it's internal instance even though from my outside host I can hit the redis stack instance using
localhost:6379
localhost
inside a Docker container is not the same host as on your computer. You can tell this by running Webdis with its default settings where it connects to Redis on localhost:6379
, notice how this works even when you don't have Redis running on your machine. What does this tell us? That it connects to the embedded Redis and not the one on the host machine, since localhost
in a container is a concept entirely limited to the scope of this container.
This is easy to validate, really. You can run Redis on your local machine and verify that it's listening on localhost:6379
:
$ redis-cli -h localhost -p 6379 PING
PONG
and then install redis-cli
in a simple container before trying the same command:
$ docker run --rm -ti alpine:3.18.3 /bin/sh
/ # apk add redis
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/community/x86_64/APKINDEX.tar.gz
(1/1) Installing redis (7.0.12-r0)
Executing redis-7.0.12-r0.pre-install
Executing redis-7.0.12-r0.post-install
Executing busybox-1.36.1-r2.trigger
OK: 10 MiB in 16 packages
/ # redis-cli -h localhost -p 6379 PING
Could not connect to Redis at localhost:6379: Connection refused
As expected, this fails since Redis is not running in this container (yes we've just installed it, but it's still not running).
So yes, if you tell Webdis to connect on localhost
, it will connect to its embedded Redis.
What you are trying to do seems common enough that there's a Stack Overflow post about it with thousands of votes: "From inside of a Docker container, how do I connect to the localhost of the machine?".
As for this part:
Were you able to put together a -server image that does not include the internal Redis instance / internal network?
As I mentioned in the other issue, publishing images of Webdis takes quite a while. I have a list of steps I go through which currently has 33 steps, and signing all the different images requires a custom script that's over 450 lines long. This part requires entering 5 different passwords – most of them multiple times – to pass an API token to Docker Hub, to sign images with the Trust Key, the Root Key, the Repository Key, and then to auth with AWS to publish the images there.
You can read about the complex relation between images and various keys in the docs, described in detail by this diagram.
So no, I really can't do one-off releases when all it would take for you to test a custom image would be to edit the Dockerfile
as you wish and then run docker build
like this:
docker build -t webdis:custom .
I'm trying to test this with your docker image, and I'm not having any luck getting it to talk to my Redis server instance.
The commands above work as expected, but I'm not sure where this data is being written because my redis database is empty, even though I get a result back from webdis
I started it with the following command:
using the following webdis.json
Where is this data being stored, and how can I get it to talk with my specific instance?