> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # Redis > Deploy Redis to Magic Containers This guide walks you through deploying Redis to Magic Containers, either as a standalone container or as part of a [multi-container](https://bunny.net/docs/magic-containers/multi-container.md) app alongside your application. > [!TIP] > > Don't have a bunny.net account yet? [Sign up](https://dash.bunny.net/auth/register) and enable Magic Containers to get started. ## Quickstart **1. Create a new app** Go to the [bunny.net dashboard](https://dash.bunny.net), select **Magic Containers**, and click **Add App**. Select **Single region deployment**. > [!WARNING] > > Databases should use single region deployment with a single instance. Each pod gets its own dedicated volume with no data replication — this applies both across regions and within the same region. Scaling to multiple pods or regions would result in separate, isolated databases each with their own data. **2. Add the Redis container** Click **Add Container** and configure the image: * **Registry**: Docker Hub * **Image**: `library/redis` * **Tag**: `7-alpine` Magic Containers will automatically detect the required endpoint and environment variables for the image. **3. Add a persistent volume** In the **Volumes** section of the container settings, add a volume: * **Name**: `redis-data` * **Mount path**: `/data` This ensures your data persists across restarts and redeployments. Without a volume, all data is lost when the container stops. See [persistent volumes](https://bunny.net/docs/magic-containers/persistent-volumes.md) for more details on volume behavior and pricing. **4. Deploy** Review your settings and click **Confirm and Create**. ## Redis 8+ volume permissions Redis 8 changed its default user from `root` to a non-root user (`uid 999`, group `redis`). When Magic Containers mounts a persistent volume at `/data`, the directory is owned by `root`. This means the Redis process cannot write its RDB/AOF persistence files to this directory, causing the container to fail on startup with an error like: ``` Failed opening the temp RDB file temp-26.rdb (in server root dir /data) for saving: Permission denied ``` To fix this, configure a **Startup Command** that changes the ownership of the `/data` directory before starting Redis. In your container settings, set the startup command as: ```json theme={null} ["sh", "-c", "chown -R 999:999 /data && exec /usr/local/bin/docker-entrypoint.sh redis-server"] ``` > [!WARNING] > > The startup command must be specified as a array, not a string. This ensures proper argument parsing and execution. This command: 1. Changes ownership of `/data` to the `redis` user (uid 999) 2. Executes the standard Redis entrypoint script > [!NOTE] > > Redis 7 and earlier versions run as `root` by default and do not have this issue. If you're using Redis 7 (e.g., `redis:7-alpine`), no startup command is needed. > [!NOTE] > > Redis has no authentication enabled by default. It's recommended to set a > password even if Redis is not exposed externally. Other containers in the same > pod can access the network. Set a password by configuring the container > command to `redis-server --requirepass YOUR_PASSWORD`, and update your > connection string to `redis://:YOUR_PASSWORD@127.0.0.1:6379`. > [!NOTE] > > Redis uses `/data` as its default data directory. The official image is > configured to use append-only file (AOF) persistence by default, which writes > every operation to disk in the mounted volume. ## Connect from your app In a [multi-container](https://bunny.net/docs/magic-containers/multi-container.md) setup, your app and Redis share the same localhost network. Connect using `127.0.0.1` and the default port `6379`. > [tab] Connection string > > ``` > redis://127.0.0.1:6379 > ``` > [tab] Node.js > > ```javascript theme={null} > import { createClient } from "redis"; > > const client = createClient({ > url: process.env.REDIS_URL, > }); > > await client.connect(); > await client.set("key", "value"); > const value = await client.get("key"); > ``` > [tab] Go > > ```go theme={null} > import ( > "context" > "os" > > "github.com/redis/go-redis/v9" > ) > > client := redis.NewClient(&redis.Options{ > Addr: "127.0.0.1:6379", > }) > > ctx := context.Background() > client.Set(ctx, "key", "value", 0) > val, err := client.Get(ctx, "key").Result() > ``` > [tab] Python > > ```python theme={null} > import redis > > r = redis.Redis(host="127.0.0.1", port=6379) > > r.set("key", "value") > value = r.get("key") > ``` > [tab] PHP > > ```php theme={null} > > $redis = new Redis(); > $redis->connect('127.0.0.1', 6379); > > $redis->set('key', 'value'); > $value = $redis->get('key'); > ``` ## Multi-container example A typical setup pairs Redis with your application. When configuring the app, add two containers: ### App container * **Image**: your app image (e.g. `ghcr.io//my-app:latest`) * **Endpoint**: the port your app listens on * **Environment variables**: * `REDIS_URL` = `redis://127.0.0.1:6379` ### Redis container * **Image**: `library/redis:7-alpine` * **Volume**: mount path `/data` > [!NOTE] > > Both containers share the same localhost network, so your app connects to > Redis at `127.0.0.1:6379`. See [multi-container > apps](https://bunny.net/docs/magic-containers/multi-container.md) for more details. ## External access To connect to Redis from outside Magic Containers (e.g. from your local terminal), add an [Anycast endpoint](https://bunny.net/docs/magic-containers/endpoints.md): 1. Go to your app's **Endpoints** tab and click **Add New Endpoint** 2. Select **Anycast** as the type 3. Set **Container Port** to `6379` 4. Set **Exposed Port** to `6379` 5. Click **Add Endpoint** Then connect using the Anycast IP and the **exposed port**: ```bash theme={null} redis-cli -h -p ``` > [!NOTE] > > The exposed port and container port may differ. When connecting externally, > always use the exposed port shown in your endpoint configuration. > [!WARNING] > > Redis has no authentication enabled by default. Exposing it to the internet > without a password is a serious security risk. Consider setting a password by > using the container command `redis-server --requirepass YOUR_PASSWORD`, and > removing the Anycast endpoint when external access is no longer needed. This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.