リモートデスクトップ接続を行う場合、通常は専用クライアントを使用しますが、これをWebブラウザ経由で実現する方法を。若干パフォーマンスは落ちますが、それなりに実用的です。
Docker環境が使えるLXD内で試しています。
#!/usr/bin/env bash
# =============================================================================
# Apache Guacamole — Docker Compose セットアップスクリプト
# 実行環境 : LXDコンテナ内 (Docker インストール済み前提)
# 構築内容 : guacd + Guacamole Client + PostgreSQL
# 実行方法 : bash setup-guacamole-docker.sh
# =============================================================================
set -euo pipefail
# ── 設定変数 ──────────────────────────────────────────────────────────────────
GUAC_VERSION="${GUAC_VERSION:-1.5.5}"
INSTALL_DIR="${INSTALL_DIR:-/opt/guacamole}"
POSTGRES_DB="${POSTGRES_DB:-guacamole_db}"
POSTGRES_USER="${POSTGRES_USER:-guacamole_user}"
POSTGRES_PASS="${POSTGRES_PASS:-$(openssl rand -base64 16 | tr -dc 'a-zA-Z0-9' | head -c 20)}"
GUAC_PORT="${GUAC_PORT:-8080}"
# ─────────────────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
die() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
echo ""
echo -e "${CYAN}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ Apache Guacamole ${GUAC_VERSION} — Docker Compose セットアップ ║${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
# ── 前提チェック ──────────────────────────────────────────────────────────────
command -v docker >/dev/null 2>&1 || die "docker が見つかりません"
docker compose version >/dev/null 2>&1 || \
docker-compose version >/dev/null 2>&1 || \
die "docker compose / docker-compose が見つかりません"
# compose コマンドの決定
if docker compose version >/dev/null 2>&1; then
COMPOSE="docker compose"
else
COMPOSE="docker-compose"
fi
info "Docker : $(docker --version)"
info "Compose : $($COMPOSE version --short 2>/dev/null || echo 'OK')"
info "Guacamole : ${GUAC_VERSION}"
info "インストール先: ${INSTALL_DIR}"
info "ポート : ${GUAC_PORT}"
echo ""
# ── ディレクトリ作成 ──────────────────────────────────────────────────────────
info "ディレクトリを作成..."
mkdir -p "${INSTALL_DIR}"/{init,data/postgres,data/drive,data/record}
ok "ディレクトリ作成完了: ${INSTALL_DIR}"
# ── 初期化SQLの生成 ───────────────────────────────────────────────────────────
info "PostgreSQL 初期化SQL を生成..."
docker run --rm "guacamole/guacamole:${GUAC_VERSION}" \
/opt/guacamole/bin/initdb.sh --postgresql \
> "${INSTALL_DIR}/init/initdb.sql"
ok "initdb.sql 生成完了"
# ── docker-compose.yml 生成 ───────────────────────────────────────────────────
info "docker-compose.yml を生成..."
# 変数を展開してymlを書き出す(クォートなしEOFで展開)
cat > "${INSTALL_DIR}/docker-compose.yml" <<EOF
services:
# guacd (プロキシデーモン)
guacd:
image: guacamole/guacd:${GUAC_VERSION}
container_name: guacd
restart: unless-stopped
volumes:
- ./data/drive:/drive:rw
- ./data/record:/record:rw
networks:
- guacnet
# PostgreSQL
postgres:
image: postgres:15-alpine
container_name: guac_postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASS}
volumes:
- ./data/postgres:/var/lib/postgresql/data:rw
- ./init/initdb.sql:/docker-entrypoint-initdb.d/initdb.sql:ro
networks:
- guacnet
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
# Guacamole Client
guacamole:
image: guacamole/guacamole:${GUAC_VERSION}
container_name: guacamole
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
guacd:
condition: service_started
environment:
GUACD_HOSTNAME: guacd
GUACD_PORT: 4822
POSTGRESQL_HOSTNAME: postgres
POSTGRESQL_PORT: 5432
POSTGRESQL_DATABASE: ${POSTGRES_DB}
POSTGRESQL_USER: ${POSTGRES_USER}
POSTGRESQL_PASSWORD: ${POSTGRES_PASS}
ports:
- "${GUAC_PORT}:8080"
networks:
- guacnet
networks:
guacnet:
driver: bridge
EOF
ok "docker-compose.yml 生成完了"
# ── 起動 ─────────────────────────────────────────────────────────────────────
info "コンテナを起動..."
cd "${INSTALL_DIR}"
$COMPOSE up -d
ok "コンテナ起動完了"
# ── 起動確認 ──────────────────────────────────────────────────────────────────
info "Guacamole の起動を待機しています (最大120秒)..."
for i in $(seq 1 40); do
if curl -sf "http://localhost:${GUAC_PORT}/guacamole/" >/dev/null 2>&1; then
ok "Guacamole 起動確認 OK"
break
fi
echo -n "."
sleep 3
if [[ $i -eq 40 ]]; then
warn "タイムアウト — ログを確認: cd ${INSTALL_DIR} && $COMPOSE logs"
fi
done
echo ""
# ── 認証情報を保存 ────────────────────────────────────────────────────────────
CONTAINER_IP=$(ip route get 1.1.1.1 2>/dev/null | awk '/src/{print $7}' | head -1 || echo "不明")
cat > "${INSTALL_DIR}/.credentials" <<EOF2
POSTGRES_DB=${POSTGRES_DB}
POSTGRES_USER=${POSTGRES_USER}
POSTGRES_PASSWORD=${POSTGRES_PASS}
EOF2
chmod 600 "${INSTALL_DIR}/.credentials"
# ── 完了メッセージ ────────────────────────────────────────────────────────────
echo ""
echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ セットアップ完了! ║${NC}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e " ${CYAN}アクセス URL${NC} : http://${CONTAINER_IP}:${GUAC_PORT}/guacamole/"
echo -e " ${CYAN}初期ユーザー${NC} : guacadmin"
echo -e " ${CYAN}初期パスワード${NC} : guacadmin"
echo -e " ${CYAN}DB パスワード${NC} : ${POSTGRES_PASS}"
echo -e " ${CYAN}認証情報保存先${NC} : ${INSTALL_DIR}/.credentials"
echo ""
echo -e " ${YELLOW}※ 初回ログイン後、必ず管理者パスワードを変更してください。${NC}"
echo -e " ${YELLOW}※ ホスト側からアクセスする場合はポートフォワードを設定:${NC}"
echo -e " ${CYAN}lxc config device add <コンテナ名> guac-proxy proxy \\"
echo -e " listen=tcp:0.0.0.0:${GUAC_PORT} connect=tcp:127.0.0.1:${GUAC_PORT}${NC}"
echo ""
echo -e " 管理コマンド:"
echo -e " 起動 : ${CYAN}cd ${INSTALL_DIR} && $COMPOSE up -d${NC}"
echo -e " 停止 : ${CYAN}cd ${INSTALL_DIR} && $COMPOSE down${NC}"
echo -e " ログ : ${CYAN}cd ${INSTALL_DIR} && $COMPOSE logs -f${NC}"
echo -e " 状態 : ${CYAN}cd ${INSTALL_DIR} && $COMPOSE ps${NC}"
echo ""
ブラウザでアクセスしたら、まずパスワードを変更。その後、接続先を追加します。名前は適当に、プロトコルは「RDP」を選択。

ホスト名のIPアドレスや、ユーザー名、パスワードを入力。
サーバ証明書を無視する、にチェックを入れます。

保存したら、ホーム画面に戻って接続します。複数の接続先を管理出来て便利ではないでしょうか。



