Writing data from within Kubernetes Pod to host - redis

I have a Kubernetes redis Pod, which I need to backup/restore its data through dump.rdb. When restore, I put dump.rdb under /data and launch the pod with this config:
containers:
- name: redis
volumeMounts:
- mountPath: /data/
name: data-volume
volumes:
- name: data-volume
hostPath:
path: /data/
type: Directory
It can see the dump.rdb from host's /data dir, but when Redis saves any changes in the Pod, it only updated the /data dir within the Pod not the host. My goal is to be able to backup the dump.rdb on the host, so I need the dump.rdb on the host to get updated too. What am I missing here?

Const`s question helps to find the solution for Joe.
Joe missed the place where the file was stored.
My suggestion: try to use NFS volume for storing and restoring backups, it may be easier than using the hostPath

Related

How to give full permissions to a shared volume in kubernetes

I have a container which is using shared volume with host. I want to give it a full permissions. At present, it is:
ls -l
drwxr-xr-x 8 user user 4096 Aug 9 04:47 Data
But I want it to be:
ls -l
drwxrwxrwx 8 user user 4096 Aug 9 04:47 Data
I have a below deployment file:
----
----
spec:
containers:
- name: logger
image: logger_image
volumeMounts:
- mountPath: /Data
name: Data-files
securityContext:
privileged: true
volumes:
- name: Data-files
hostPath:
path: /home/user/Documents/Data
----
----
I have even set it as privileged but still, the volumes do not have full permissions. What should I add in deployment file to make the volume full permissions?
Thanks
Your permissions on /home/user/ or /home/user/Documents/ folders don't allow the process' owner (of logger_image) to access the folder and write.
Try to create /Data (on your root) and set the proper permissions.
I resolved this issue by mentioning the appropriate commands to give full permissions to that directory in the Dockerfile itself.
In the dockerfile:
RUN mkdir -p /Data
RUN chmod 777 -R Data/
and then later used the same kubernetes deployment file and it worked fine with full permissions.
Thanks

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/

Apache on Docker: set file permissions in a shared web hosting environment

I'm new to docker. I'm trying to switch from a traditional VMs setup to a dockerized one for a bunch of websites I manage. I tried with Docker Compose and Wordpress, this is my docker-compose.yml file:
version: "3"
services:
blog2:
image: wordpress:4.9.6-apache
volumes:
- blog2:/var/www/html
environment:
WORDPRESS_DB_PASSWORD:
depends_on:
- mysql
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD:
volumes:
blog2:
It works and it creates a blog2 volume I can access on the main filesystem from /var/lib/docker/volumes/blog2. I can also connect with SFTP and edit files, everything works.
Files in the /var/www/html directory are owned by www-data user. If I edit them it's ok but if I add a new file... it is owned by the user I'm using on the server (in my test case it's root, but it can be any other user). So they cannot be modified by www-data, if the webserver need to edit or delete them.
How can I fix this problem? My idea is to add a user to every Docker container, add him to the www-data group and chown the entire /var/www/html to this user, so that initial and future files can be red or written by both, no matter if they are created by www-data or this user.
Can it work? And can I write it in the docker-compose.yml file to have this set up when I do docker-compose up -d at container creation? :)
Thank you in advance.
One solution to your problem is to start the wordpress container using a different user. This is documented under Running as an arbitrary user on the dockerhub page for the wordpress image.
Inside the docker compose file you can set the user that will be running inside the container. For instance, you can specify user 1000 which will map to user 1000 on the machine.
Thus you can find the uid of user www-data and use that uid to start the container:
...
services:
blog2:
image: wordpress:4.9.6-apache
user: 1000:1000
volumes:
- blog2:/var/www/html
environment:
WORDPRESS_DB_PASSWORD:
depends_on:
- mysql
...

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)

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

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"