code-serverからopencodeを利用

opencode webでもターミナル操作は出来ますが、やはり使い勝手はcode-serverには劣るので、code-serverと連携したほうが使いやすいでしょう。code-serverのターミナル画面に呼び出して、そのまま作業が行えます。

opencodeのLXDコンテナにcode-serverをインストール

#!/bin/bash
# ============================================================
#  Code-Server インストール(LXDコンテナ / Tailscale HTTPS版)
#  前提:
#    - Ubuntu 24.04 LXDコンテナ内で実行
#    - tailscale up 済み(tailscale serve でHTTPS化)
#    - opencode web (port 4096) が既存で動作中
#    - 実行: sudo bash install-codeserver.sh
# ============================================================

set -euo pipefail

GREEN='\033[0;32m'; CYAN='\033[0;36m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
info()    { echo -e "${CYAN}[INFO]${NC} $*"; }
success() { echo -e "${GREEN}[OK]${NC}   $*"; }
warn()    { echo -e "${YELLOW}[WARN]${NC} $*"; }
error()   { echo -e "${RED}[ERR]${NC}  $*"; exit 1; }

[[ $EUID -ne 0 ]] && error "root権限で実行してください: sudo bash $0"

REAL_USER="${SUDO_USER:-$(logname 2>/dev/null || echo $USER)}"
REAL_HOME=$(getent passwd "$REAL_USER" | cut -d: -f6)
CODE_SERVER_PORT=8089
PASSWORD=""

# ============================================================
# ① パスワードを最初に聞く
# ============================================================
prompt_password() {
  echo ""
  echo -e "${CYAN}╔══════════════════════════════════════════════════════╗${NC}"
  echo -e "${CYAN}║   Code-Server + Tailscale Serve セットアップ         ║${NC}"
  echo -e "${CYAN}╚══════════════════════════════════════════════════════╝${NC}"
  echo ""
  echo -e "インストール対象ユーザー: ${YELLOW}${REAL_USER}${NC} (${REAL_HOME})"
  echo ""
  echo "code-server のパスワードを設定してください。"
  echo -e "  ${CYAN}[A]${NC} 自動生成する(ランダム32文字)"
  echo -e "  ${CYAN}[M]${NC} 手動で入力する"
  echo ""
  read -r -p "選択 [A/M] (Enterで自動生成): " choice
  case "${choice^^}" in
    M)
      while true; do
        read -r -s -p "🔑 パスワードを入力してください: " PASSWORD
        echo ""
        read -r -s -p "🔑 もう一度入力してください:     " PASSWORD2
        echo ""
        if [[ "$PASSWORD" == "$PASSWORD2" && -n "$PASSWORD" ]]; then
          success "パスワードを設定しました。"
          break
        else
          warn "パスワードが一致しないか空です。もう一度入力してください。"
        fi
      done
      ;;
    *)
      PASSWORD=$(openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32)
      success "パスワードを自動生成しました。(後で表示します)"
      ;;
  esac
  echo ""
}

# ============================================================
# ② Tailscale の動作確認
# ============================================================
check_prerequisites() {
  info "前提条件を確認中..."
  command -v tailscale &>/dev/null \
    || error "tailscale がインストールされていません。先に tailscale をセットアップしてください。"
  tailscale status &>/dev/null \
    || error "tailscale が起動していません。'tailscale up' を先に実行してください。"
  success "Tailscale 動作確認OK"
}

# ============================================================
# ③ 依存パッケージのインストール
# ============================================================
install_deps() {
  info "依存パッケージをインストール中..."
  apt-get update -qq
  apt-get install -y -qq curl wget openssl
  success "依存パッケージ インストール完了"
}

# ============================================================
# ④ code-server のインストール
# ============================================================
install_code_server() {
  info "最新バージョンを確認中..."
  LATEST=$(curl -fsSL https://api.github.com/repos/coder/code-server/releases/latest \
    | grep '"tag_name"' | sed 's/.*"v\([^"]*\)".*/\1/')
  info "最新バージョン: v${LATEST}"

  DEB_URL="https://github.com/coder/code-server/releases/download/v${LATEST}/code-server_${LATEST}_amd64.deb"
  info "ダウンロード中..."
  wget -q --show-progress -O /tmp/code-server.deb "$DEB_URL"
  dpkg -i /tmp/code-server.deb
  rm /tmp/code-server.deb
  success "code-server v${LATEST} インストール完了"
}

# ============================================================
# ⑤ 設定ファイルの生成
# ============================================================
setup_config() {
  info "config.yaml を生成中..."
  CONFIG_DIR="$REAL_HOME/.config/code-server"
  mkdir -p "$CONFIG_DIR"
  cat > "$CONFIG_DIR/config.yaml" <<EOF
bind-addr: 127.0.0.1:${CODE_SERVER_PORT}
auth: password
password: ${PASSWORD}
cert: false
EOF
  chown -R "$REAL_USER:$REAL_USER" "$CONFIG_DIR"
  chmod 600 "$CONFIG_DIR/config.yaml"
  success "config.yaml 生成完了(127.0.0.1:${CODE_SERVER_PORT} でローカルのみ待受)"

  info "argv.json(日本語化)を配置中..."
  VSCODE_DIR="$REAL_HOME/.local/share/code-server/User"
  mkdir -p "$VSCODE_DIR"
  cat > "$VSCODE_DIR/argv.json" <<'EOF'
{
  "locale": "ja"
}
EOF
  chown -R "$REAL_USER:$REAL_USER" "$REAL_HOME/.local/share/code-server"
  success "argv.json 配置完了"
}

# ============================================================
# ⑥ systemd サービスの登録・起動
# ============================================================
setup_systemd() {
  info "systemd サービスを登録中..."
  cat > /etc/systemd/system/code-server.service <<EOF
[Unit]
Description=code-server (VS Code in Browser)
After=network.target

[Service]
Type=exec
User=${REAL_USER}
WorkingDirectory=${REAL_HOME}
ExecStart=/usr/bin/code-server
Restart=always
RestartSec=5
Environment=HOME=${REAL_HOME}

[Install]
WantedBy=multi-user.target
EOF
  systemctl daemon-reload
  systemctl enable code-server
  systemctl restart code-server

  info "起動確認中..."
  sleep 4
  systemctl is-active --quiet code-server \
    && success "code-server 正常起動" \
    || { journalctl -u code-server -n 20 --no-pager; error "code-server の起動に失敗しました"; }
}

# ============================================================
# ⑦ opencode の PATH を通す
# ============================================================
setup_path() {
  info "opencode のバイナリパスを確認中..."

  # 候補パスを優先順に検索
  OPENCODE_BIN=""
  for candidate in \
      "/usr/local/bin/opencode" \
      "$REAL_HOME/.local/bin/opencode" \
      "$REAL_HOME/bin/opencode" \
      "$REAL_HOME/.opencode/bin/opencode"; do
    if [[ -x "$candidate" ]]; then
      OPENCODE_BIN="$candidate"
      break
    fi
  done

  if [[ -z "$OPENCODE_BIN" ]]; then
    warn "opencode バイナリが見つかりませんでした。PATH 設定をスキップします。"
    warn "手動で確認: find /usr /home -name opencode -type f 2>/dev/null"
    return
  fi

  OPENCODE_DIR=$(dirname "$OPENCODE_BIN")
  info "opencode を発見: $OPENCODE_BIN"

  # /usr/local/bin なら既に PATH が通っているはずなのでスキップ
  if [[ "$OPENCODE_DIR" == "/usr/local/bin" ]]; then
    success "opencode は /usr/local/bin にあるため PATH 設定不要です。"
    return
  fi

  # ~/.bashrc と ~/.profile の両方に export を追記(重複しないよう確認)
  PATH_LINE="export PATH=\"${OPENCODE_DIR}:\$PATH\""
  for rc in "$REAL_HOME/.bashrc" "$REAL_HOME/.profile"; do
    if [[ -f "$rc" ]] && grep -qF "$OPENCODE_DIR" "$rc"; then
      info "$rc には既に設定済みです。スキップ。"
    else
      echo "" >> "$rc"
      echo "# opencode" >> "$rc"
      echo "$PATH_LINE" >> "$rc"
      chown "$REAL_USER:$REAL_USER" "$rc"
      success "$rc に PATH を追記しました。"
    fi
  done

  # code-server の systemd 環境変数にも追加(ターミナル起動時に即反映)
  if ! grep -q "OPENCODE" /etc/systemd/system/code-server.service; then
    sed -i "/^ExecStart=/i Environment=PATH=${OPENCODE_DIR}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
      /etc/systemd/system/code-server.service
    systemctl daemon-reload
    systemctl restart code-server
    success "code-server の systemd に PATH を追加し再起動しました。"
  fi

  success "opencode PATH 設定完了 → ${OPENCODE_DIR}"
}

# ============================================================
# ⑧ Tailscale serve 設定(opencode の設定を維持しつつ追加)
# ============================================================
setup_tailscale_serve() {
  info "Tailscale serve に code-server (port ${CODE_SERVER_PORT}) を追加中..."
  # --https=8089 で code-server 専用ポートを公開
  # opencode web の port 4096(デフォルト443)は既存設定のまま残る
  tailscale serve --bg --https=${CODE_SERVER_PORT} "http://127.0.0.1:${CODE_SERVER_PORT}"
  success "Tailscale serve に code-server を追加しました。"

  # Tailscale ホスト名取得
  TS_HOSTNAME=$(tailscale status --json 2>/dev/null | python3 -c "
import sys, json
try:
    d = json.load(sys.stdin)
    s = d.get('Self', {})
    dns = s.get('DNSName', '').rstrip('.')
    print(dns if dns else s.get('HostName', 'unknown'))
except:
    print('unknown')
" 2>/dev/null || echo "unknown")

  echo ""
  echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
  echo -e "${GREEN}  ✅ セットアップ完了!${NC}"
  echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
  echo ""
  echo -e "  🌐 アクセスURL (Tailscaleネットワーク内から):"
  echo -e "     code-server : ${CYAN}https://${TS_HOSTNAME}:${CODE_SERVER_PORT}${NC}"
  echo -e "     opencode web: ${CYAN}https://${TS_HOSTNAME}${NC}  ← 既存(変更なし)"
  echo ""
  echo -e "  🔑 code-server パスワード: ${YELLOW}${PASSWORD}${NC}"
  echo ""
  echo -e "  🧩 日本語化手順:"
  echo -e "     1. Extensions で 'Japanese Language Pack' をインストール"
  echo -e "     2. Ctrl+Shift+P → 'Configure Display Language' → 日本語を選択"
  echo ""
  echo -e "  🤖 opencode の使い方:"
  echo -e "     code-server の統合ターミナルで opencode を実行してください"
  echo -e "     Ctrl+Esc         → opencode をターミナルで開く"
  echo -e "     Ctrl+Shift+Esc   → 新規 opencode セッションを開始"
  echo -e "     Alt+Ctrl+K       → @ファイル参照を挿入"
  echo ""
  echo -e "  📋 管理コマンド:"
  echo -e "     ログ確認:    journalctl -u code-server -f"
  echo -e "     再起動:      sudo systemctl restart code-server"
  echo -e "     serve 確認:  tailscale serve status"
  echo ""
}

# ============================================================
# メイン
# ============================================================
main() {
  prompt_password        # ① パスワードを最初に聞く
  check_prerequisites    # ② Tailscale確認
  install_deps           # ③ 依存パッケージ
  install_code_server    # ④ code-server インストール
  setup_config           # ⑤ 設定ファイル生成
  setup_systemd          # ⑥ systemd 登録・起動
  setup_path             # ⑦ opencode PATH設定
  setup_tailscale_serve  # ⑧ Tailscale serve 設定
}

main "$@"

ターミナルでopencode呼び出し

インストール完了したら、code-serverでターミナルを開いて、下記を実行します。

opencode

これでopencodeが呼び出されるので、作業を依頼すれば、コードを書かなくても実施されるはずです。

もし、opencodeが別のサーバで動いているならサーバのURLを指定します。

opencode attach <opencodeのサーバ:4096>

作業を依頼しておくだけ

指示しておくだけなのでスマホからも依頼出来ます。たとえば、これはUbuntuの最新版が公開されたか定期的にチェックさせ、公開されたら指定場所にダウンロードしておくように指示しています。

タイトルとURLをコピーしました