# Secure Dense-Mem on Vultr with Traefik

**Summary:** A nontechnical walkthrough for launching Dense-Mem on a Vultr cloud server with Traefik, HTTPS, private control-portal access, and shared memory for personal, family, or work AI tools.

- Canonical: https://markhuang.ai/blog/secure-dense-mem-vultr-traefik
- Language: en
- Author: [Mark Huang](https://markhuang.ai/about)
- Published: 2026-05-30
- Section: Tutorials
- Tags: dense-mem, vultr, traefik, docker, mcp, ai-memory
- License: https://creativecommons.org/licenses/by-nc/4.0/

---

![A cloud VPS protected by an HTTPS edge gateway and a private Dense-Mem vault](https://cdn.markhuang.ai/blog/secure-dense-mem-vultr-traefik/hero.webp)

*A cloud VPS protected by an HTTPS edge gateway and a private Dense-Mem vault*

## Quick Answer

The secure cloud version uses one public HTTPS endpoint and keeps the admin surface private.

| Public                                          | Private                                                       |
| ----------------------------------------------- | ------------------------------------------------------------- |
| `https://memory.example.com/mcp` for AI clients | `127.0.0.1:8090` control portal through SSH tunnel            |
| Ports `80` and `443` for Traefik                | Postgres, Neo4j, and the portal stay off the public internet  |
| API keys protect memory access                  | Teams and profiles separate family, personal, and work memory |

Running Dense-Mem locally is the easiest start. Running it on a small cloud server is how you make the same memory reachable from your laptop, desktop, work machine, and remote AI clients.

This tutorial builds a secure beginner setup:

```text
Your AI client -> https://memory.example.com/mcp -> Traefik -> Dense-Mem
```

The public internet sees only the HTTPS Dense-Mem endpoint. The control portal stays private.

> **Info:**
>
> The Vultr link in this guide is a referral link: <https://www.vultr.com/?ref=8310459>. Use it if you want to support the project while creating your server.

## What You Are Building

| Piece          | Job                                                      |
| -------------- | -------------------------------------------------------- |
| Vultr VPS      | The small cloud computer that runs Dense-Mem             |
| Docker Compose | Starts Dense-Mem, Postgres, Neo4j, and Traefik           |
| Traefik        | Handles HTTPS, certificates, headers, and public routing |
| Dense-Mem      | Stores shared AI memory                                  |
| Control portal | Creates and rotates keys, but stays private              |

This setup is for normal users, families, and small teams who want one memory server without building a platform from scratch.

## Step 1: Create The Vultr Server

Open Vultr with the referral link:

[Create a Vultr account or server](https://www.vultr.com/?ref=8310459)

Create a new Cloud Compute instance:

| Setting  | Beginner choice                                                            |
| -------- | -------------------------------------------------------------------------- |
| Location | Pick the region closest to you                                             |
| Image    | Ubuntu 24.04 LTS                                                           |
| Size     | Use enough RAM for Docker, Postgres, and Neo4j; 4 GB is a calmer first run |
| SSH key  | Add your SSH key instead of using password login                           |
| Firewall | Allow SSH, HTTP, and HTTPS only                                            |

For the firewall:

| Port  | Allow from                  | Why                                 |
| ----- | --------------------------- | ----------------------------------- |
| `22`  | Your IP address if possible | SSH admin access                    |
| `80`  | Anywhere                    | Lets Traefik get HTTPS certificates |
| `443` | Anywhere                    | Public Dense-Mem HTTPS endpoint     |

Do not open these ports to the public:

```text
8080, 8090, 5432, 7474, 7687
```

Those are internal or local admin/database surfaces.

## Step 2: Point A Domain To The Server

![A domain path pointing through DNS to a secure cloud server](https://cdn.markhuang.ai/blog/secure-dense-mem-vultr-traefik/dns-domain.webp)

*A domain path pointing through DNS to a secure cloud server*

You need a domain or subdomain, such as:

```text
memory.example.com
```

Create an `A` record:

| DNS field | Value                       |
| --------- | --------------------------- |
| Name      | `memory`                    |
| Type      | `A`                         |
| Value     | Your Vultr server public IP |

Wait until DNS resolves:

```bash
ping memory.example.com
```

If the ping shows your Vultr IP, continue.

## Step 3: SSH Into The Server

From your computer:

```bash
ssh root@YOUR_SERVER_IP
```

Update Ubuntu:

```bash
apt update
apt upgrade -y
```

Install Docker using Docker's official Ubuntu instructions. The short version is:

```bash
apt install -y ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
​
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" \
  > /etc/apt/sources.list.d/docker.list
​
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

Check:

```bash
docker compose version
```

## Step 4: Download The Expert Compose File

Create the app folder:

```bash
mkdir -p /opt/dense-mem
cd /opt/dense-mem
```

Download the Traefik-ready compose file:

```bash
curl -fsSLo docker-compose.yml \
  https://raw.githubusercontent.com/markhuangai/dense-mem/main/examples/docker-compose.expert.yml
```

Create `.env`:

```bash
cat > .env <<'EOF'
POSTGRES_PASSWORD=replace-with-a-long-random-password
NEO4J_PASSWORD=replace-with-a-long-random-password
CONTROL_PORTAL_TOKEN=replace-with-a-long-random-token
AI_API_URL=https://api.openai.com/v1
AI_API_KEY=your-ai-provider-api-key
AI_API_EMBEDDING_MODEL=text-embedding-3-large
AI_API_EMBEDDING_DIMENSIONS=3072
​
DENSE_MEM_DOMAIN=memory.example.com
ACME_EMAIL=you@example.com
CONTROL_PORTAL_BIND=127.0.0.1
CONTROL_PORTAL_PORT=8090
EOF
```

Edit it:

```bash
nano .env
```

Replace:

- `memory.example.com` with your real domain
- `you@example.com` with your email
- every placeholder password/token with a real secret
- `your-ai-provider-api-key` with your provider API key
- `AI_API_URL` with your OpenAI-compatible provider base URL if you are not using OpenAI
- `AI_API_EMBEDDING_MODEL` and `AI_API_EMBEDDING_DIMENSIONS` with a matching embedding model and dimension

You can create random secrets with:

```bash
openssl rand -base64 32
```

The example uses OpenAI's `text-embedding-3-large`, which returns `3072` dimensions. If you use `text-embedding-3-small`, set `AI_API_EMBEDDING_DIMENSIONS=1536`. Pick the embedding model before storing important memory; changing model or dimensions later requires rebuilding or re-embedding memory data.

## Step 5: Start Dense-Mem With Traefik

![Public HTTPS traffic passing through a secure edge gateway before reaching private Dense-Mem](https://cdn.markhuang.ai/blog/secure-dense-mem-vultr-traefik/traefik-edge.webp)

*Public HTTPS traffic passing through a secure edge gateway before reaching private Dense-Mem*

Start the public HTTPS stack:

```bash
docker compose --profile traefik up -d
```

Check the containers:

```bash
docker compose ps
```

Check the public health endpoint:

```bash
curl https://memory.example.com/health
```

If this returns JSON with a healthy or degraded status, your public HTTPS route is working. A degraded status can still happen when optional Redis is disabled; for a single-server setup, that is expected.

## Step 6: Create A Team And API Key

Create your first shared memory team:

```bash
docker compose exec server /app/provision-team --name "primary-memory"
```

Save the printed API key somewhere private.

Set it locally on any machine that will connect:

```bash
export DENSE_MEM_API_KEY="dm_default-prof_..."
```

## Step 7: Connect Claude Code To The Public Server

```bash
claude mcp add --transport http dense-mem https://memory.example.com/mcp \
  --header "Authorization: Bearer $DENSE_MEM_API_KEY"
```

Ask Claude Code:

```text
Remember that this Dense-Mem server is my shared AI memory.
```

Then open a new session and ask:

```text
What do you remember about my Dense-Mem setup?
```

## Step 8: Connect Codex To The Same Server

Add this to `~/.codex/config.toml`:

```toml
[mcp_servers.dense_mem]
url = "https://memory.example.com/mcp"
bearer_token_env_var = "DENSE_MEM_API_KEY"
tool_timeout_sec = 60
enabled = true
```

Restart Codex.

Now Claude Code and Codex are connected to the same memory brain.

## Step 9: Keep The Control Portal Private

![A private SSH tunnel leading to the control portal while public HTTPS reaches only the memory API](https://cdn.markhuang.ai/blog/secure-dense-mem-vultr-traefik/private-control-portal.webp)

*A private SSH tunnel leading to the control portal while public HTTPS reaches only the memory API*

The control portal manages teams, profiles, keys, and security settings. Do not expose it publicly.

The expert compose file publishes it only on `127.0.0.1:8090` on the server. To use it from your computer, make an SSH tunnel:

```bash
ssh -L 8090:127.0.0.1:8090 root@YOUR_SERVER_IP
```

Then open:

```text
http://127.0.0.1:8090/
```

Use your `CONTROL_PORTAL_TOKEN` from `.env`.

## Share Memory With Family Or Work Teams

Dense-Mem can support more than one shared memory boundary.

| Group      | Practical setup                                                |
| ---------- | -------------------------------------------------------------- |
| Personal   | One team named `primary-memory`                                |
| Family     | One team named `family-memory`, with separate profiles         |
| Work       | One team per work group or project                             |
| Automation | Read-only profile keys when a tool should search but not write |

Use the same team when people should share memory. Use separate teams when memory should not mix.

That is the product idea: one memory brain when you want continuity, clear walls when you need privacy.

## Security Checklist

Before you invite anyone else:

- keep the control portal private
- keep API keys private
- use read-only keys for tools that should not write memory
- rotate keys when a machine is lost or a teammate leaves
- do not store passwords, seed phrases, or private keys as memories
- back up Docker volumes if the memory matters
- remember that hosted AI providers can receive memory text for embeddings and verification

Dense-Mem makes AI memory more durable. It does not remove your duty to protect sensitive information.

## Why This Matters

The best AI setup is not one chat window. It is a connected workspace.

Claude Code can learn your coding rules. Codex can recall the same rules. A family assistant can remember travel preferences. A work team can preserve decisions from last month instead of rediscovering them every sprint.

Dense-Mem gives those tools a shared memory layer you own.

Try it, share it, and star the repo if you want more people to find it:

[github.com/markhuangai/dense-mem](https://github.com/markhuangai/dense-mem)
