# Podman Login 登录信息重启后失效的处理


rootless Podman 里跑 `podman login`，命令显示成功，但机器重启后再拉私有镜像，又像没登录过一样。这个现象不是 registry token 突然过期，通常是登录信息写到了临时目录。

## 问题现象

最常见的操作是这样：

```bash
podman login docker.io
```

当时能正常 `podman pull`。重启系统后，拉镜像或者启动依赖私有镜像的 Quadlet 服务时，又出现未登录、认证失败之类的问题。

可以用 `--verbose` 看 Podman 实际用了哪个认证文件：

```bash
podman login --verbose docker.io
```

如果输出里有类似这一行，就说明登录信息写在运行时目录里：

```text
Used: /run/user/1000/containers/auth.json
```

## 原因

Podman 官方的 [podman-login(1)](https://docs.podman.io/en/latest/markdown/podman-login.1.html) 写得很明了：Linux 上 `podman login` 默认读写的认证文件是：

```text
${XDG_RUNTIME_DIR}/containers/auth.json
```

rootless 用户常见就是：

```text
/run/user/1000/containers/auth.json
```

`/run` 通常是临时文件系统，重启后会清空。Podman 文档里的示例也明确提到，默认凭据放在 `$XDG_RUNTIME_DIR`，它是 `/run` 下的目录，所以不会跨重启保留。

这就解释了为什么看起来像“登录过期”：不是登录流程失败，而是 `auth.json` 没了。

## 写入持久 authfile

把认证信息明确写到用户配置目录：

```bash
mkdir -p ~/.config/containers
podman login --authfile ~/.config/containers/auth.json docker.io
chmod 600 ~/.config/containers/auth.json
```

`--authfile` 是 `podman login` 的参数，用来指定认证文件路径。这里选 `~/.config/containers/auth.json`，因为它在用户家目录下，即使系统重启也会保留。

如果你用的是其他 registry，把 `docker.io` 换成对应地址：

```bash
podman login --authfile ~/.config/containers/auth.json quay.io
podman login --authfile ~/.config/containers/auth.json ghcr.io
podman login --authfile ~/.config/containers/auth.json registry.example.com
```

验证一下：

```bash
podman login --authfile ~/.config/containers/auth.json --get-login docker.io
```

能打印用户名就说明这个文件里有对应 registry 的登录信息。

## 设置 REGISTRY_AUTH_FILE

只在 `login` 时加 `--authfile` 还不够。后续 Podman 操作，尤其是 pull/run 和 Quadlet 自动拉镜像时，也要让 Podman 知道默认去读这个持久文件。

Podman 支持用 `REGISTRY_AUTH_FILE` 覆盖默认认证文件路径：

```bash
export REGISTRY_AUTH_FILE="$HOME/.config/containers/auth.json"
```

当前 shell 里可以直接测试：

```bash
podman pull docker.io/library/alpine:latest
```

想让交互式 shell 长期生效，可以写进 `~/.profile`、`~/.bashrc` 或 `~/.zshrc`，按你实际用的 shell 来。

```bash
export REGISTRY_AUTH_FILE="$HOME/.config/containers/auth.json"
```

如果镜像是由 rootless Quadlet / `systemctl --user` 服务拉取的，单纯写 shell rc 文件不一定会传给 systemd 用户管理器。可以直接在 Quadlet 文件里写 `[Service]` 环境变量，只影响这个容器服务：

```ini
[Service]
Environment=REGISTRY_AUTH_FILE=%h/.config/containers/auth.json
```

改完 Quadlet 后重新加载并重启服务：

```bash
systemctl --user daemon-reload
systemctl --user restart your-container.service
```


---

> 作者: Nite  
> URL: https://www.nite07.com/zh-cn/posts/podman-login-authfile/  

