# Images

Ce qu’une machine démarre : une image Arrakis avec SSH et les outils habituels, ou votre propre image, publique ou privée.

## Images Arrakis

Une machine démarre sur une image Arrakis, sauf si vous en choisissez une autre. Chacune repose sur une image de base officielle, à laquelle s’ajoutent SSH, une bannière de connexion et des outils courants : git, git-lfs, tmux, htop, nvtop, rsync, curl, wget, jq et un éditeur. Python est dans le PATH de chaque session SSH.

| Image | Contenu | Image Docker |
|---|---|---|
| PyTorch 2.14 (par défaut) | PyTorch 2.14.1, CUDA 13.0, Python 3.12, Ubuntu 24.04 | `goodailabs/arrakis:pytorch-2.14.1-cuda13.0` |
| PyTorch 2.14 avec le toolkit CUDA | Idem, plus nvcc, les en-têtes CUDA et un compilateur | `goodailabs/arrakis:pytorch-2.14.1-cuda13.0-devel` |
| Toolkit CUDA 13.0 | CUDA 13.0.3, cuDNN 9, nvcc, Python 3.12, Ubuntu 24.04 | `goodailabs/arrakis:cuda-13.0.3-devel` |
| Ubuntu 26.04 | Python 3.14. Le pilote du GPU provient de la machine | `goodailabs/arrakis:ubuntu-26.04` |

CUDA 13.0 est la version que fournit `pip install torch` : les wheels compilées pour PyTorch sont donc compatibles. Elle fonctionne sur toutes les machines d’Arrakis, Blackwell compris : chacune dispose d’un pilote NVIDIA de la série 580 ou plus récent. Les images sont publiques sur Docker Hub : vous pouvez donc récupérer la même sur votre propre ordinateur. `goodailabs/arrakis:latest` est l’image par défaut.

À la connexion, la machine affiche ses GPU, l’image et l’espace disque libre :

```text
  6 × NVIDIA RTX A4000, 16 GB each
  PyTorch 2.14.1, CUDA 13.0, Python 3.12.3, Ubuntu 24.04.5 LTS
  32 CPU cores, 125 GB memory, 412 GB free in /workspace
```

Travaillez dans `/workspace`. Tout ce qui se trouve sur une machine, `/workspace` compris, est supprimé quand elle s’arrête.

## Vos propres images

Toutes les images fonctionnent : vLLM, SGLang, les conteneurs NVIDIA NGC ou l’image de votre équipe, publique ou privée.

- Dans **Images**, choisissez **Add an image** et collez l’image telle que `docker pull` l’accepte, par exemple `vllm/vllm-openai:v0.11.0`. Pour une image publique, vous pouvez aussi choisir **Your own image** au moment de louer.
- Arrakis interroge d’abord le registre de l’image : l’image doit exister, être téléchargeable et disposer d’une version linux/amd64. Une faute de frappe ou un jeton erroné est refusé avant tout débit.
- Registres : Docker Hub, GitHub (`ghcr.io`), Amazon ECR et ECR Public, Google (Artifact Registry et `gcr.io`), Azure (`azurecr.io`), NVIDIA NGC (`nvcr.io`), Quay, GitLab et Microsoft (`mcr.microsoft.com`), ou le vôtre : Harbor, Artifactory, Nexus, un GitLab ou un Quay auto-hébergé, ou tout registre accessible par son nom DNS public, comme `registry.example.com:5000/team/app:v1`.
- SSH est ajouté à toute image au démarrage : vous vous connectez donc en root de la même manière. L’image doit contenir un shell.
- Le premier démarrage sur une machine télécharge l’image. Les images volumineuses prennent plus de temps : une image de 12 Go peut demander 10 à 20 minutes sur un réseau lent.

### Images privées

Cochez **It's private: log in to pull it** quand vous ajoutez l’image, et saisissez les identifiants que `docker login` demanderait. Arrakis vérifie l’image avec ces identifiants avant de l’enregistrer, les conserve chiffrés et ne s’en sert que pour récupérer cette image quand vous louez. Le mot de passe n’est plus jamais affiché.

| Registre | Nom d’utilisateur | Mot de passe ou jeton |
|---|---|---|
| Docker Hub | Votre nom d’utilisateur Docker Hub | Un jeton d’accès personnel en lecture seule |
| GitHub (`ghcr.io`) | Votre nom d’utilisateur GitHub | Un jeton classique avec uniquement `read:packages` |
| Amazon ECR (`<account>.dkr.ecr.<region>.amazonaws.com`) | Un ID de clé d’accès | Sa clé d’accès secrète |
| Google (`<region>-docker.pkg.dev`, `gcr.io`) | `_json_key` | La clé JSON d’un compte de service doté du rôle Artifact Registry Reader |
| Azure (`<name>.azurecr.io`) | Un jeton de dépôt ou un principal de service | Son mot de passe, avec un accès en lecture seule (pull) |
| NVIDIA NGC (`nvcr.io`) | `$oauthtoken` | Votre clé d’API NGC |
| GitLab (`registry.gitlab.com`) | Le nom d’utilisateur d’un jeton de déploiement | Le jeton de déploiement, avec `read_registry` |
| Quay | Un compte robot | Son jeton |
| Votre propre registre | Le nom d’utilisateur qu’il attend | Son mot de passe ou son jeton |

- **Amazon ECR** : utilisez un utilisateur AWS qui peut seulement récupérer des images (la stratégie `AmazonEC2ContainerRegistryReadOnly`). À chaque location, Arrakis échange la clé contre des identifiants valables 12 heures, ceux qu’affiche `aws ecr get-login-password` : la machine ne voit donc jamais la clé elle-même.
- **Votre propre registre** : les machines y récupèrent les images directement, où qu’elles se trouvent. Il doit donc répondre sur l’internet public en HTTPS, avec un certificat émis par une autorité publique (comme Let's Encrypt). Un registre derrière un VPN ou une liste d’adresses IP autorisées est injoignable ; un registre avec un certificat auto-signé est refusé.
- Utilisez un jeton en lecture seule. La machine s’en sert pour récupérer l’image, et l’image peut rester en cache sur cette machine après la fin de votre location : ne mettez donc aucun secret dans l’image, et transmettez-les au moment de l’exécution.
- Pour changer de jeton, choisissez **Change login** à côté de l’image, ou enregistrez de nouveau la même image avec le nouveau jeton. Supprimer l’image efface ses identifiants partout où Arrakis les conservait.

### Au démarrage

| Choix | Ce qui s’exécute | À utiliser pour |
|---|---|---|
| Wait for me to log in (par défaut) | Rien : la machine vous attend | Entraînement, notebooks, tout ce que vous lancez via SSH |
| Run the image's command | Le point d’entrée et la commande propres à l’image | Des serveurs comme vLLM, TGI ou SGLang |
| Run a command | Une simple ligne que vous fournissez, comme `python -m http.server 8000` | Un job qui démarre tout seul |

Si la commande se termine, la machine n’est plus joignable. Dans le doute, choisissez **Wait for me to log in**.

Accédez à un serveur de la machine via SSH :

```sh
ssh -L 8000:localhost:8000 root@<host> -p <port>
curl localhost:8000/v1/models
```

### Variables d’environnement

Ajoutez des paires `KEY=value` à une image, une par ligne. Elles sont stockées avec l’image : n’y mettez aucun secret, et définissez plutôt ceux-ci via SSH, par exemple `export HF_TOKEN=...` dans votre session.

## Depuis la CLI, l’API et les agents

```sh
arrakis images list
arrakis images add vllm/vllm-openai:v0.11.0 --start image
arrakis instances create --node-id <node> --image vllm/vllm-openai:v0.11.0 --start image --termination-hours 2
```

Une image privée prend ses identifiants, avec le jeton sur stdin, comme le fait `docker login` :

```sh
echo "$GITHUB_TOKEN" | arrakis images add ghcr.io/acme/trainer:v3 --username acme-bot --password-stdin
arrakis instances create --node-id <node> --template-id <image id> --termination-hours 2
```

```sh
curl -X POST $ARRAKIS_URL/v1/instances -H "Authorization: Bearer $ARRAKIS_TOKEN" -H "Content-Type: application/json" \
  -d '{"node_id": "<node>", "name": "vllm", "termination_hours": 2, "ssh_public_key": "ssh-ed25519 AAAA...",
       "image": "vllm/vllm-openai:v0.11.0", "start": "image"}'
```

- `GET /v1/templates` liste les images Arrakis et les vôtres ; `POST /v1/templates` en enregistre une (`image`, `start`, `command`, `environment` et, pour une image privée, `registry_username` et `registry_password`). Le mot de passe est en écriture seule : les réponses indiquent `private` et `registry_username`. `PATCH /v1/templates/{id}` avec les deux remplace les identifiants.
- `POST /v1/instances` démarre `template_id`, ou n’importe quelle `image` publique avec un `start`.
- Via MCP, `list_images` les liste, en signalant les images privées, et `rent_gpu` accepte `template_id` ou `image`.

Plus : [toute la documentation](/fr/docs.md) · [OpenAPI](/openapi.json) · [llms.txt](/fr/llms.txt)
