---
tags: [note opencode installation vps ia, OpenCode]
type: "note"
nature: documentation # Options : portrait, lieu, info, concept, script, process, tuto, none
ressource: true
univers: PERSO
projects:
  - "[[03_PROJETS/VPS-IA]]"
date: "[[01_JOURNAL/2026/2026-09-25]]"
priority: 10
description: "Procédure d'installation d'OpenCode : utilisateur système dédié, binaire global, service systemd."
---
# Installation OpenCode sur VPS OVH Perso

Paramètres :
* `[OPENCODE-PASSWORD]` : mot de passe du service OpenCode (cf. Keepass).


### Étape 1 : Créer un utilisateur système dédié à OpenCode

Créer un compte `opencode` sans shell interactif ni accès SSH direct pour y associer le service dédié :

```sh
sudo adduser --system --group --home /var/lib/opencode opencode
```


### Étape 2 : Installer OpenCode et le rendre global

**1. Télécharger et installer le binaire OpenCode :** 

Exécuter le script d'installation officiel :

```sh
curl -fsSL https://opencode.ai/v2/install | bash
```

**2. Déplacer l'exécutable dans le PATH système :**

Pour que l'utilisateur `opencode` puisse y accéder sans bloquer sur des permissions `/root` :

```sh
sudo mv ~/.opencode/bin/opencode /usr/local/bin/
```

**3. Accorder les permissions d'exécution en assurant la propriété à root :**

```sh
sudo chown root:root /usr/local/bin/opencode
sudo chmod 755 /usr/local/bin/opencode
```

Pour vérifier l'emplacement : `which opencode` (doit retourner `/usr/local/bin/opencode`).


### Étape 3 : Créer le service systemd

Créer le fichier de service systemd dédié :

```sh
sudo nano /etc/systemd/system/opencode.service
```

Coller la configuration suivante :

```toml
[Unit]
Description=OpenCode Server Background Service
After=network.target

[Service]
Type=simple
User=opencode
Group=opencode
WorkingDirectory=/var/lib/opencode
ExecStart=/var/lib/opencode/.opencode/bin/opencode-serve.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```

**Remarque (mise à jour 2026-10-26) :** le mot de passe n'est **plus** stocké en clair dans le fichier de service. `ExecStart` pointe vers `~/.opencode/bin/opencode-serve.sh`, un wrapper qui injecte les secrets depuis le coffre `pass` à l'exécution :

```bash
#!/usr/bin/env bash
# Lance le serveur OpenCode en injectant les secrets depuis le coffre pass.
set -euo pipefail
export HOME="${HOME:-/var/lib/opencode}"
source "$HOME/.opencode/bin/opencode-secrets-env.sh"
exec /usr/local/bin/opencode serve --service --port 49374 --hostname 127.0.0.1
```

- `opencode-secrets-env.sh` définit `OPENCODE_SERVER_PASSWORD`, `SB_AUTH_TOKEN`, `GRIST_API_KEY`, `OPENROUTER_API_KEY`… depuis `pass` (source de vérité), jamais en clair dans les fichiers.
- Le flag `--service` (ajouté le 2026-10-26) enregistre le serveur comme *background service* (fichier `~/.local/state/opencode/service.json`) → la CLI (`opencode mcp list`, `opencode api …`) le découvre automatiquement, sans avoir à passer `--server`. **Ne pas utiliser `opencode service start` dans systemd** : le daemon se détache → perte de supervision + boucle de restart ; il faut garder `serve --service` en foreground.


### Étape 4 : Démarrer et valider le service

**1.Charger la configuration systemd :**

```sh
sudo systemctl daemon-reload
```

**2.Activer le lancement au démarrage :**

```sh
sudo systemctl enable opencode
```

**3.Lancer le service :**

```sh
sudo systemctl start opencode
```

Pour contrôler le fonctionnement du service :

```sh
sudo systemctl status opencode
```


### Étape 5 : Tester la connexion locale (depuis Node-RED)

En ligne de commande exécuter :

```sh
curl -i \
  -u 'opencode:OPENCODE-PASSWORD' \
  -H "Accept: application/json" \
  -H "x-opencode-directory: /var/lib/opencode" \
  http://127.0.0.1:49374/api/command
```

**Vérification de la découverte CLI (2026-10-26) :** avec le flag `--service`, la CLI trouve le serveur automatiquement (sinon elle tente d'en démarrer un et échoue sur le port occupé) :

```sh
opencode service status          # → http://127.0.0.1:49374
opencode api get /api/info       # → {"version": "2.1.4", ...}
opencode mcp list                # → ✓ 4 serveurs connected
```

Le fichier d'enregistrement est `~/.local/state/opencode/service.json` (créé au démarrage du serveur avec `--service`).


### Etape 6 : mise à jour d'opencode

```sh
# 1. Téléchargement de la dernière version
cd ~
curl -fsSL https://opencode.ai/v2/install | bash

# 2. Déplacement dans le dossier global
sudo mv ~/.opencode/bin/opencode /usr/local/bin/

# 3. Ajustement du propriétaire et des permissions
sudo chown root:root /usr/local/bin/opencode
sudo chmod 755 /usr/local/bin/opencode

# 4. Redémarrer le service
sudo systemctl status opencode
sudo systemctl restart opencode

```

### Étape 7 : Optimisations et dépôt git (2026-10-14)

**1. Correction des uploads (erreur 500)**

Le serveur OpenCode (utilisateur `opencode`) ne pouvait pas créer `/tmp/opencode/uploads` car `/tmp/opencode` appartenait à `root` (755) → erreur 500 à chaque dépôt de fichier/image. Corrigé :

```sh
sudo chown opencode:opencode /tmp/opencode
```

**2. Règle tmpfiles.d** — `/etc/tmpfiles.d/opencode.conf`

Recrée `/tmp/opencode` avec le bon propriétaire au boot et purge les uploads de plus de 7 jours :

```ini
d /tmp/opencode 0755 opencode opencode -
e /tmp/opencode/uploads 0755 opencode opencode 7d
```

**3. Rotation des logs** — `/etc/logrotate.d/opencode`

Rotation du log (`~/.local/share/opencode/log/opencode.log`) à 50 Mo, 7 archives compressées, `copytruncate` (sans interruption du service).

**4. Limite mémoire** — drop-in `/etc/systemd/system/opencode.service.d/memory.conf`

```ini
[Service]
MemoryHigh=1500M
MemoryMax=2G
```

> ⚠️ Mise à jour 2026-10-26 : les `Environment="SB_AUTH_TOKEN=…"` / `"GRIST_API_KEY=…"` ont été **retirés** de ce drop-in — les secrets sont désormais injectés à l'exécution par `opencode-serve.sh` via le coffre `pass` (cf. Étape 3). Les configs OpenCode utilisent toujours `{env:VAR}` ; seules les limites mémoire restent dans systemd.

**5. Dépôt git de sauvegarde** — `https://forgejo.datagrandest.net/shizendo/vps-opencode`

* Forgejo tourne sur le même VPS, port SSH **222**.
* Remote : `ssh://forgejo@forgejo.datagrandest.net:222/shizendo/vps-opencode.git` (utilisateur SSH `forgejo`, pas `git`)
* Clé de déploiement : `~/.ssh/id_ed25519` (utilisateur `opencode`), à ajouter en lecture/écriture dans les Deploy keys du dépôt.
* Contenu versionné : configs OpenCode, skills, agents, scripts (`sysview`, `sync-silverbullet`), notes.
* `.gitignore` : exclut `.venvs/`, `.npm-global/`, `.local/`, `.ssh/`, `.silverbullet-token`, `service.json`, profils Chromium, logs.
* **Auto-sync git** : `~/.opencode/bin/git-sync.sh` committe + pousse automatiquement les changements utiles à chaque `sync-silverbullet.sh` (commit vide si rien n'a changé ; désactivable avec `GIT_SYNC=0`).
* **Sync périodique** : timer systemd `opencode-git-sync.timer` (2×/jour à 08:00 et 20:00, rattrapé si le serveur était éteint) → `sync-silverbullet.sh` puis `git-sync.sh`. Manuel : `sudo systemctl start opencode-git-sync.service`.
* Pousser les changements : `cd /var/lib/opencode && git push -u origin main`

### Étape 8 : Mise à jour automatique (2026-10-14)

Un script root + un timer systemd hebdomadaire mettent à jour OpenCode automatiquement :

* `/usr/local/sbin/opencode-update.sh` : vérifie la version (`https://opencode.ai/update/api/latest/cli/npm`), télécharge via le script officiel (sous l'utilisateur `opencode`), sauvegarde l'ancien binaire (`/usr/local/bin/.opencode-backups/`), remplace, redémarre le service et **restaure l'ancien binaire en cas d'échec**.
* Timer `opencode-update.timer` : **lundi 03:30** (rattrapé au boot si éteint), avec léger aléa.
* Logs : `/var/log/opencode-update.log`.
* Usage manuel : `sudo /usr/local/sbin/opencode-update.sh` (ou `--check` pour vérifier sans agir).
* **Alerte ntfy** (topic `vps-admin`) : notification en cas de **mise à jour effective** (succès, avec versions ancienne → nouvelle) ou **d'échec** (priorité haute, étape en cause) — aucune notification si déjà à jour. Voir skill [[80_CONFIG/IA_SKILLS/Ntfy]].

**Prérequis** : le script doit être installé en root (une seule fois). L'utilisateur `opencode` n'a pas besoin de droits sudo — tout passe par le timer root.

## Synthèse

Cette installation prend en compte les éléments suivants :
* **Sécurité :** Isolé sous l'utilisateur système `opencode`.  
* **Persistance :** Géré en arrière-plan par `systemd` avec redémarrage automatique.
* **Réseau :** Écoute locale sécurisée sur `127.0.0.1:49374`.
* **Authentification :** Protégé par mot de passe (token), injecté à l'exécution depuis le coffre `pass` via `opencode-serve.sh` — plus rien en clair dans systemd.
* **Sauvegarde :** Config, skills et agents versionnés dans le dépôt git Forgejo `vps-opencode`.
* **Maintenance :** Logs rotatés (logrotate), uploads purgés (tmpfiles.d), mémoire plafonnée (2 Go), mise à jour OpenCode hebdomadaire automatique (lundi 03:30).
