Operations 9 min read

How to Fix Docker Volume Permissions for Redis and Redis Insight with an Init Container

This guide explains why Redis and Redis Insight containers fail to start due to mismatched host directory ownership, and provides a step‑by‑step solution using a dedicated permissions‑init container, Docker Compose configuration, and a Bash script to correct the permissions safely and idempotently.

Tech Musings
Tech Musings
Tech Musings
How to Fix Docker Volume Permissions for Redis and Redis Insight with an Init Container

Problem Background and Cause

Redis 8.x introduced stricter security checks that validate data‑directory permissions, while the Redis Insight image runs as user 1000:1000. The host‑mounted directories are owned by root, so both containers cannot access their data directories.

uid=1000(node) gid=1000(node) groups=1000(node)
uid=999(redis) gid=999(redis) groups=999(redis)

Debug tip: Use docker exec <em>container_name</em> id to discover the UID/GID a container runs as.

The Docker volume mount mechanism preserves the host directory's ownership inside the container. When the host owner does not match the container's runtime user, the service fails with permission errors.

Solution Architecture

A dedicated permissions‑init container is introduced to adjust host directory ownership before the main services start.

Docker Compose Implementation

version: '3.3'

services:
  # Permission‑initialisation container
  permissions-init:
    image: registry.cn-chengdu.aliyuncs.com/jxd134/redis:8.4.0-bookworm
    container_name: permissions-init
    entrypoint: ["/bin/bash", "/scripts/fix-permissions.sh"]
    volumes:
      - ./data:/redis-data
      - ./redisinsight:/redisinsight-data
      - ./conf:/redis-conf
      - ./fix-permissions.sh:/scripts/fix-permissions.sh:ro
    restart: "no"
    user: root
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  redis8:
    image: registry.cn-chengdu.aliyuncs.com/jxd134/redis:8.4.0-bookworm
    container_name: redis8
    network_mode: host
    restart: unless-stopped
    command: redis-server /usr/local/etc/redis/redis.conf
    volumes:
      - ./data:/data
      - ./conf/redis.conf:/usr/local/etc/redis/redis.conf:ro
      - ./conf/users.acl:/usr/local/etc/redis/users.acl
    # Note: official docs say the container runs as redis, but we observed root; we therefore set the user explicitly
    user: "redis:redis"
    depends_on:
      - permissions-init
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  redis-insight:
    image: registry.cn-chengdu.aliyuncs.com/jxd134/redisinsight:3.0.2-amd64
    container_name: redis-insight
    network_mode: host
    restart: unless-stopped
    volumes:
      - ./redisinsight:/data
    environment:
      - REDISINSIGHT_HOST=0.0.0.0
      - REDISINSIGHT_PORT=5540
    depends_on:
      - permissions-init
    user: "1000:1000"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Permission Fix Script

#!/bin/bash
set -e

echo "Starting permission fix script..."

# Define directories and desired owners
declare -A dirs=(
    ["/redis-data"]="redis:redis"
    ["/redisinsight-data"]="1000:1000"
)

# Process each directory
for dir in "${!dirs[@]}"; do
    if [ -d "$dir" ]; then
        if [ ! -f "$dir/.permissions_fixed" ]; then
            echo "Fixing $dir permissions (owner: ${dirs[$dir]})..."
            chown -R "${dirs[$dir]}" "$dir"
            chmod -R 755 "$dir"
            touch "$dir/.permissions_fixed"
            chown "${dirs[$dir]}" "$dir/.permissions_fixed"
            chmod 644 "$dir/.permissions_fixed"
            echo "$dir permissions fixed successfully"
        else
            echo "$dir permissions already fixed, skipping..."
        fi
    else
        echo "Warning: $dir not found"
    fi
done

# Fix Redis ACL file permissions if present
if [ -f "/redis-conf/users.acl" ]; then
    echo "Fixing users.acl permissions..."
    chown redis:redis /redis-conf/users.acl
    chmod 644 /redis-conf/users.acl
    echo "users.acl permissions fixed"
fi

echo "Permission fix completed successfully"

Solution Summary

The core of the approach is the permissions‑init container, which acts as a "permission coordinator" before the Redis and Redis Insight services start.

Pre‑permission coordination: Using depends_on in Docker Compose, the init container runs first with root privileges to modify host directory ownership.

Scripted permission fixing: fix-permissions.sh maps each mounted path to the required UID:GID (e.g., /redis-data → redis:redis, /redisinsight-data → 1000:1000) and applies chown and chmod accordingly.

Idempotency guarantee: The script creates a hidden .permissions_fixed flag file after fixing a directory, preventing repeated changes on subsequent deployments.

Exact ownership matching: The Redis service is configured with user: "redis:redis" and Redis Insight with user: "1000:1000", ensuring each container can read/write its data after the init step.

This centralized initialization decouples permission management from the service containers, improving security and deployment reliability.

DockerLinuxComposePermissionsInit Container
Tech Musings
Written by

Tech Musings

Capturing thoughts and reflections while coding.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.