Redis in docker-compose: any way to specify a redis.conf file? - redis

my Redis container is defined as a standard image in my docker_compose.yml
redis:
image: redis
ports:
- "6379"
I guess it's using standard settings like binding to Redis at localhost.
I need to bind it to 0.0.0.0, is there any way to add a local redis.conf file to change the binding and let docker-compose to use it?
thanks for any trick...

Yes. Just mount your redis.conf over the default with a volume:
redis:
image: redis
volumes:
- ./redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "6379"
Alternatively, create a new image based on the redis image with your conf file copied in. Full instructions are at: https://registry.hub.docker.com/_/redis/
However, the redis image does bind to 0.0.0.0 by default. To access it from the host, you need to use the port that Docker has mapped to the host for you which you find by using docker ps or the docker port command, you can then access it at localhost:32678 where 32678 is the mapped port. Alternatively, you can specify a specific port to map to in the docker-compose.yml.
As you seem to be new to Docker, this might all make a bit more sense if you start by using raw Docker commands rather than starting with Compose.

Old question, but if someone still want to do that, it is possible with volumes and command:
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf

Unfortunately with Docker, things become a little tricky when it comes to Redis configuration file, and the answer voted as best (im sure from people that did'nt actually tested it) it DOESNT work.
But what DOES WORK, fast, and without husles is this:
command: redis-server --bind redis-container-name --requirepass some-long-password --maxmemory 256mb --maxmemory-policy allkeys-lru --appendonly yes
You can pass all the variable options you want in the command section of the yaml docker file, by adding "--" in the front of it, followed by the variable value.
Never forget to set a password, and if possible close the port 6379.
Τhank me later.
PS: If you noticed at the command, i didnt use the typical 127.0.0.1, but instead the redis container name. This is done for the reason that docker assigns ip addresses internally via it's embedded dns server. In other words this bind address becomes dynamic, hence adding an extra layer of security.
If your redis container is called "redis" and you execute the command docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis (for verifying the running container's internal ip address), as far as docker is concerned, the command give in docker file, will be translated internally to something like: redis-server --bind 172.19.0.5 --requirepass some-long-password --maxmemory 256mb --maxmemory-policy allkeys-lru --appendonly yes

Based on David awnser but a more "Docker Compose" way is:
redis:
image: redis:alpine
command: redis-server --include /usr/local/etc/redis/redis.conf
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
That way, you include the .conf file by docker-compose.yml file and don't need a custom image.

mount your config /usr/local/etc/redis/redis.conf
add command to execute redis-server with your config
redis:
image: redis:7.0.4-alpine
restart: unless-stopped
volumes:
- ./redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
########################################
# or using command if mount not work
########################################
command: >
redis-server --bind 127.0.0.1
--appendonly no
--save ""
--protected-mode yes

It is an old question but I have a solution that seems elegant and I don't have to execute commands every time ;).
1 Create your dockerfile like this
#/bin/redis/Dockerfile
FROM redis
CMD ["redis-server", "--include /usr/local/etc/redis/redis.conf"]
What we are doing is telling the server to include that file in the Redis configuration. The settings you type there will override the default Redis have.
2 Create your docker-compose
redisall:
build:
context: ./bin/redis
container_name: 'redisAll'
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- ./config/redis:/usr/local/etc/redis
3 Create your configuration file it has to be called the same as Dockerfile
//config/redis/redis.conf
requirepass some-long-password
appendonly yes
################################## NETWORK #####################################
# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 loopback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.*
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1
// and all configurations that can be specified
// what you put here overwrites the default settings that have the
container

I had the same problem when using Redis in docker environment that the Redis could not save data to disk on dump.rdb.
The problem was the Redis could not read the configurations redis.conf , I solve it by sending the required configurations with the command in docker compose as below :
redis19:
image: redis:5.0
restart: always
container_name: redis19
hostname: redis19
command: redis-server --requirepass some-secret --stop-writes-on-bgsave-error no --save 900 1 --save 300 10 --save 60 10000
volumes:
- $PWD/redis/redis_data:/data
- $PWD/redis/redis.conf:/usr/local/etc/redis/redis.conf
- /etc/localtime:/etc/localtime:ro
and it works fine.

I think it will be helpful i am sharing working code in my local
redis:
container_name: redis
hostname: redis
image: redis
command: >
--include /usr/local/etc/redis/redis.conf
volumes:
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf
ports:
- "6379:6379"

Related

How to stop anonymous access to redis databases

I run redis image with docker-compose
I passed redis.conf (and redis says "configuration loaded")
In redis.conf i added user
user pytest ><password> ~pytest/* on #set #get
And yet I can communicate with redis as anonymous
even with uncommented string
requirepass <password>
Redis docs about topics: Security and ACL do not answer how to restrict access to everyone. Probably I do not understand something fundamentally.
my docker-compose.yaml:
version: '3'
services:
redis:
image: redis:latest
ports:
- 6379:6379
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 6000s
timeout: 30s
retries: 50
restart: always
volumes:
- redis-db:/data
- redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf" ]
volumes:
redis-db:
redis.conf:
And yet I can communicate with redis as anonymous even with uncommented string
Because there's a default user, and you didn't disable it. If you want to totally disable anonymous access, you should add the following to your redis.conf:
user default off
Secondly, the configuration for user 'pytest' is incorrect. If you want to only allow user 'pytest' to have set and get command on the given key pattern, you should configure it as follows:
user pytest ><password> ~pytest/* on +set +get
You also need to ensure that the docker-compose is using your config file.
Assuming you have the redis.conf in the same directory as your docker-compose.yml the 'volumes' section in the service declaration would be.
- ./redis.conf:/usr/local/etc/redis/redis.conf
and also remove the named volume declaration in the bottom
redis.conf:
The users would be able to connect to Redis but without AUTH they can't perform any action if you enable
requirepass <password>
The right way to restrict GET, SET operations on the keys pytest/* would be
user pytest ><password> ~pytest/* on +set +get

Redis Docker image using ACL

I am trying to test the new Redis 6 ACL configuration.
I want to run a test with the simplest configuration possible to get acquainted with the configuration.
My Redis will run as a Docker container. Please, consider that I am a Redis complete newbie.
My Dockerfile:
FROM redis:6.2.1
COPY redis.conf /usr/local/etc/redis/redis.conf
COPY users.acl /etc/redis/users.acl
EXPOSE 6379
My redis.conf file:
aclfile /etc/redis/users.acl
My users.acl file:
user test on >password ~* &* +#all
I am able to run a container without errors, but it seems that the container is not loading the ACL configuration: in fact, when I run redis-cli into the container and I execute ACL LIST, I get as output:
1) "user default on nopass ~* &* +#all"
which is clearly not as intended.
I fear I am missing something in the Dockerfile, but I cannot find a documentation suited for my needs.
Does someone have hints?
Thanks in advance.
As here clearly stated:
# Redis configuration file example.
#
# Note that in order to read the configuration file, Redis must be
# started with the file path as first argument:
#
# ./redis-server /path/to/redis.conf
In the Dockerfile is missing one last line:
CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]

Can I have Redis available in my DDEV container?

I use DDEV as a development environment for a TYPO3 project. I want to have Redis server available (for cache).
How can I achieve that?
In order to have Redis available for TYPO3 you need to have:
Redis server
To create redis server for your project, just create a file
.ddev/docker-compose.redis.yaml with following
content:
# ddev redis recipe file
#
version: '3.6'
services:
redis:
container_name: ddev-${DDEV_SITENAME}-redis
image: redis:4
restart: always
ports:
- 6379
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_APPROOT
environment:
- VIRTUAL_HOST=$DDEV_HOSTNAME
- HTTP_EXPOSE=6379
volumes: []
web:
links:
- redis:$DDEV_HOSTNAME
Configure your application to use Redis
Use redis as a host, and port 6379.
FYI! DDEV added PHP-Redis to the web container, as of DDEV v1.1.0 on 15 Aug.
https://www.drud.com/ddev-local/ddev-v1-1-0/
"More services! We’ve added PHP-Redis to the web container. We heard repeatedly that not having Redis was a major hurdle for people who wanted to use DDEV. We hope this helps!"
You can get redis with ddev get drud/ddev-redis. There's also ddev get drud/ddev-redis-commander for use with the ddev redis service.
https://ddev.readthedocs.io/en/latest/users/extend/additional-services/

Restoring redis running on docker from dump.rdb

What I want to do is to use a dump.rdb that I've taken from a production server, and use it in my development environment, that is defined by a very simple compose file.
For simplicity, assume that my app is the same as this compose example from the docker docs for redis and flask, so the docker-compose.yml looks like:
version: '2'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
depends_on:
- redis
redis:
image: redis
This persists redis data between restarts, but you just cannot access the redis files as there is no volume mounted for redis in the docker-compose.yml.
So I change my compose file to mount a volume for redis, and I also want to force redis to persist data and the official redis image docs say that happens if I use 'appendonly'.
redis:
image: redis
command: redis-server --appendonly yes
volumes:
- ./redis:/data
If I do this, my data are persisted, as they were in the original example, and I can now see a dump.rdb and and appendonly.aof in the /redis path. The problem is, if I want to restore from a dump.rdb I need to turn off appendonly (for example, see digital ocean's how-to-back-up-and-restore-your-redis-data-on-ubuntu-14-04), and without append-only I cannot see how to get the compose file to write to the volume.
How can I produce a docker compose that will persist redis in a volume where I can switch the dump.rdb files, and therefore insert the production snapshot into my development environment?
Update
The following compose works, but be patient when testing, as the creation of the dump.rdb is not instant (hence it seeming like it failed). Also the redis official image doc, implies you have to use appendonly when you don't:
redis:
image: redis
volumes:
- ./redis:/data
The appendonly part is just to make sure that you don't lose data, but since you already have the dump.rdb from your server you don't need to worry about that: you can either remove the append only flag or remove 'command' entirely since it will then fall back to the image default which is just 'redis-server'.
I have a similar setup here and it writes/loads the dump.rdb files fine. (404)

Expose and publish a port with specified host port number inside Dockerfile

Suppose for example that I want to make an SSH host in Docker. I understand that I can EXPOSE 22 inside Dockerfile. I also understand that I can use -p 22222:22 so I can SSH into that Docker container from another physical machine on my LAN on port 22222 as ssh my_username#docker_host_ip -p 22222:22. But suppose that I'm so lazy that I can't be bothered to docker run the container with the option -p 22222:22 every time. Is there a way that the option -p 22222:22 can be automated in a config file somewhere? InDockerfile` maybe?
You can use docker compose
You can defind listening port in docker-compose.yml file as below:
version: '2'
services:
web:
image: ubuntu
ssh_service:
build: .
command: ssh ....
volumes:
- .:/code
ports:
- "22222:22"
depends_on:
- web