「あれ、さっき何やってたっけ?」もAIがカバー。Copilot+ PCの機能を引き続き試す Dell Pro 13 Premiumガチレビュー

今回で3回目のCopilot+PCのDell Pro 13 Premiumガチレビューとなります。


本記事は、デル アンバサダープログラムのモニターに参加し、Dell Pro 13 Premiumをお借りしてレビューしています。 #デルアンバサダー #DellPC #DellPro13Premium #ノートPCレビュー


これまでのレビューに関しては以下を参照してください。

参考


今回試す3つの機能

前回の記事では、Windows Studio Effectsの映像系機能(背景ぼかし・自動フレーミング・アイコンタクト)を試して、「見た目は同じでも、PCの中では全然違うことが起きていた」という発見がありました。

今回は引き続き、Copilot+ PCに搭載されている他のAI機能を試してみます。取り上げるのは以下の3つです。

  • 音声フォーカス → 前回「設定が見つからない😫」と書いたStudio Effectsのノイズ除去機能。記事公開直前に設定方法が判明したので、今回改めて検証します
  • Live Captions(ライブキャプション) → PCで流れる音声にリアルタイムで字幕をつけてくれる機能。翻訳にも対応
  • Recall(リコール) → PCが画面のスナップショットを自動で蓄積し、あとからキーワードで検索できる機能。「あれ、さっき何やってたっけ?」を解決してくれる(かもしれない)


続きを読む

見た目は互角。NPUの本当の実力は「見えないところ」に出た! Dell Pro 13 Premiumガチレビュー

今回は前回に引き続いての第2回目のDell Pro 13 Premiumガチレビューとなります。

参考

uepon.hatenadiary.com

本記事は、デル アンバサダープログラムのモニターに参加し、Dell Pro 13 Premiumをお借りしてレビューしています。 #デルアンバサダー #DellPC


出先でのWeb会議、3つのストレス

前回の記事では、Dell Pro 13 Premiumの「道具としての基本性能」とNPUの正体について書きました。今回はいよいよ実戦投入です。テーマはWeb会議

カフェや出先でWeb会議に参加したことのある人なら、こんな経験があるはず。

  • バッテリーがみるみる減る 会議が始まって30分、残量表示を見てヒヤッとする
  • ファンが唸り始める 静かなカフェで「ブォーン」は気まずい。相手にも聞こえてないか不安になる💦
  • 背景に余計なものが映り込む 後ろを人が通るたびに気になって、話に集中できない

この3つのストレスに対して、Dell Pro 13 PremiumのNPUの機能でどこまで効果があるのか、確かめてみることにしました。

すっかり忘れていましたが…

前回はPC側の外観についても触れましたが、言い忘れていたことがあります。それはACアダプタについてです。

以下の写真を見てください。Dell Pro 13 PremiumのACアダプタは、すごくコンパクトなんです。手のひらにすっぽり収まるサイズ感で、カバンの中でかさばらないのが嬉しいポイントですね😊

また、電源側のケーブルはミッキータイプのコネクタじゃないのです。海外製の製品はここがミッキータイプのものが多いのです。これが曲者で、ミッキータイプのケーブルは太くなりがちなんですよね。それに比べて今回のコネクタはメガネタイプ。この形状のケーブルは比較的細めのケーブルも存在します。これなら出先での作業も快適にできそうですね😊

これ特筆しておきたいです🤩

続きを読む

ターミナルでQRコードを表示してURL共有する方法まとめ【Python / qrencode / Node.js・WSL対応】

先日の投稿でCloudflare Quick TunnelsでローカルアプリをURL公開する記事を書きました。

前回の記事

uepon.hatenadiary.com

その中で、生成されたURLをQRコードのPNGファイルとして保存するところまでやったのですが、実際使ってみると「QRコード画像ファイルをわざわざ開くのがかなり面倒」という問題がありました。

WSLのターミナルで作業しているのに、QRコードを見せるためにWindowsのエクスプローラーでPNGを探して開いて…って作業をするのは結構面倒😫

QRコードが生成されたらターミナル上に表示して、そのままスマホで読み取るだけでいいのでは?

ということで、コンソール上でQRコードを表示する方法を調べて、前回のツールに組み込んでみました。

コンソールでQRコードを表示する方法

調べてみると、いくつかの方法がありました。

1. qrencode コマンド(Linuxコマンド)

まずは、Linuxで使える定番のQRコード生成コマンドとなります。

$ sudo apt install qrencode
$ qrencode -t UTF8 "https://example.com"

-t UTF8オプションを指定するとUnicodeのブロック文字(█ ▀ ▄ など)を使ってターミナルに直接描画してくれます。他にも -t ANSI-t ANSI256 などの出力形式があるようです。テキストからQRコードを生成して表示するだけなら、これが最もシンプルですね。標準出力にリダイレクトするといったプログラムであれば、ワンライナーで済ませることもできます。

また、WSLで実行できるコマンドはPowerShellでも動作させることができます。以下のように実行することで、いつでも実行ができます。 以下の例ではWSLのディストリビューション名をMyUbuntuとしています。自分の環境にあわせることで簡単に動作ができます。

PS> wsl -d MyUbuntu qrencode -t UTF8 "https://example.com"

ただ今回はPythonのプログラムに組み込みたかったので、別の方法を選びました。

2. Python qrcode ライブラリの print_ascii()

前回のスクリプトでもQRコード画像の生成に使っていた qrcode ライブラリですが、実は ターミナルへのテキスト出力機能も持っています。

# ライブラリのインストールが必要です→ pip install "qrcode[pil]"
import qrcode

qr = qrcode.QRCode(border=1)
qr.add_data("https://example.com")
qr.make(fit=True)
qr.print_ascii(invert=True)

これだけでターミナルにQRコードが表示されます。invert=True を指定すると白黒が反転して、ターミナルの暗い背景でも読み取りやすくなります。

前回のプログラムからであれば、追加のライブラリが不要で、すでに使っている qrcode だけで完結するのがポイントです。

3. Node.js qrcode-terminal

Node.js環境であれば qrcode-terminal もあります。

$ npx qrcode-terminal "https://example.com"

Node.js系のアプリと組み合わせるときは、こちらの方が相性が良いかもしれません。

どれを選ぶか?

今回はPythonのqrcodeライブラリの print_ascii()を採用しました。理由は次の通りです。

  • 前回のプログラムで qrcode ライブラリを使っているので、追加インストールが不要
  • Pythonのコード内で制御できるので、URL取得後のタイミングで自然に呼び出せる

Pythonプログラムへの組み込み

前回のスクリプト(cloudflared_tunnel.py)に対して、変更は2箇所だけです。

1. display_qr_in_terminal 関数の追加

今回使用するQRコードのターミナル表示用の関数を追加します。これは比較的他のプロジェクトでも使い回せる汎用的な関数ですね。

def display_qr_in_terminal(url):
    """QRコードをターミナルにテキストで表示"""
    try:
        qr = qrcode.QRCode(
            border=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
        )
        qr.add_data(url)
        qr.make(fit=True)
        print("📱 スマホでスキャンしてください:")
        print()
        qr.print_ascii(invert=True)
        print()
    except Exception as e:
        print(f"⚠️ ターミナルへのQRコード表示に失敗しました: {e}")

この処理のポイントは以下となります。

  • border=1 でQRコードの余白を小さめにし、ターミナルでの表示をコンパクトにしている
  • invert=True で白黒反転。WSLのデフォルトの暗い背景でも読み取りやすくなる
  • error_correction=ERROR_CORRECT_L で誤り訂正レベルをLow(7%)に設定。URLのような短いデータでは十分で、QRコードのサイズが小さくなる
  • try-except で囲んでいるので、万が一表示に失敗してもスクリプト全体は止まらない

2. main 関数内での呼び出し

    # QRコードを生成(PNGファイル)
    generate_qr_code(tunnel_url, qr_file_path)
    
    # QRコードをターミナルに表示 ← ここを追加
    display_qr_in_terminal(tunnel_url)

PNG画像の生成の直後に、ターミナル表示を呼び出すだけです。

実行結果

実際に追加したコードを実行すると、以下のような出力がターミナルに表示されました。

このターミナル画面をそのままスマホのカメラで読み取るだけ。わざわざPNG画像を開く必要がないので楽になりました🤩

フォントの問題

QRコードの表示にはUnicodeのブロック文字(█ ▀ ▄)を使っています。ターミナルのフォントがこれらの文字をサポートしていないと、表示が崩れます。

Windows Terminalを使っている場合はデフォルトのCascadia Monoで問題なく表示できます。もし崩れる場合は等幅フォントに変更すると改善のではないでしょうか。

ターミナルの幅が足りない

QRコードはURLの長さに応じてサイズが変わります。Cloudflare Quick Tunnelsの生成URLは結構長い(https://xxxx-xxxx-xxxx-xxxx.trycloudflare.com)ので、ターミナルの幅が狭いと折り返されて読み取れなくなります。そんなときにはターミナルの幅を80カラム以上にしておくのが無難です。

qrencode コマンドも便利

スクリプトに組み込む用途では Python の qrcode ライブラリが便利でしたが、コマンドラインからさっとQRコードを表示したいだけなら qrencode コマンドもおすすめです。こちらはワンライナーで完結するので、ちょっとしたURL共有のときに便利ですね。

$ sudo apt install qrencode

# URLをQRコード表示
$ qrencode -t UTF8 "https://example.com"

# .bashrcにエイリアスを追加しておくと楽
$ echo 'qr() { qrencode -t UTF8 "$1"; }' >> ~/.bashrc
$ source ~/.bashrc

# 以後はこれだけ
$ qr "https://example.com"

デモや発表の場で「このURLにアクセスしてください」と言いながら、ターミナルで qr "URL" を叩くだけでQRコードが出る…というのはなかなかスマートです。

おわりに

コンソールにQRコードを表示するというのは、調べてみると意外と簡単にできました。PNGファイルとして保存する仕組みはすでにあったので、ターミナル表示を追加したのは実質10行程度です。

以前は、Google ChromeのQRコード生成機能や、QRコードを生成するGoogle Colabノートブックを用意してURLをコピペして…という流れでしたが、これがターミナル上で完結するようになったので便利になりました。

GoogleColabノードブックでの参考例

uepon.hatenadiary.com

WSLのbashターミナル上でも問題なく動作する点がいいですね🤗🤗🤗

Copilot+ PCは仕事の相棒になれるか? Dell Pro 13 Premiumガチレビュー

Copilot+ PCは仕事の相棒になれるか? Dell Pro 13 Premiumガチレビュー【第1回】


本記事は、デル アンバサダープログラムのモニターに参加し、Dell Pro 13 Premiumをお借りしてレビューしています。 #デルアンバサダー #DellPC


Copilot+ PCのレビュー!

デル アンバサダープログラムのモニター企画で、Dell Pro 13 Premium をお借りすることができました。Intel Core Ultra搭載の、いわゆるCopilot+ PCとなります。さて、その実力とは🤔

正直、Copilot+ PCって言葉はよく聞くようになったけど、自分の仕事が変わった実感はまだない。Youtubeなどのレビュー記事を探しても、Cinebenchのスコアやマルチコア性能の話ばかりで、「結局知りたい、自分の仕事は楽になるの?」という疑問には誰も答えてくれない。そこは察するしかないのかもしれませんけどね。

折角お借りすることができたので、ここではベンチマークのスコアを追いかけるのは他のレビュアーにお任せして、わたしは「手触り」で勝負することにします。本業の仕事や趣味といった、複数の役割を行き来するなかで、Dell Pro 13 Premiumを持ち込んで、「カタログスペックには載らない使い心地」を正直にレポートできればと思います。もちろん、数字で語るべきところは数字で語るしかないですけどね🤗

今回お借りしたDell Pro 13 Premium (PA13250)のスペック表

項目 スペック
プロセッサー インテル® Core™ Ultra 7 268V, vPro®
OS Windows 11 Pro Copilot+ PC
メモリー 32 GB LPDDR5x
ストレージ 512 GB, M.2 2230, PCIe Gen4 NVMe, SSD
グラフィックス 内蔵インテル® Arc™ グラフィックス
ディスプレイ 13.3インチ, タッチ, Gorilla® Glass, QHD+

ただ、Cinebenchではなく、「バッテリーが何分持ったか」「ファンの音が何デシベルだったか」「Copilotの返事が仕事に使えるレベルか」という形で表現できればと思います。できるだろうか…🤔

いまのところ、全5回+番外編の構成で、「Copilot+ PCは私にとっての"相棒"になれるのか?」を確かめたい。


続きを読む

Cloudflare Quick Tunnelsを試してみた!ngrokの代替になるか?

研究のデモシステムでStreamlitを使ったデモをする機会が多かったです。これまではngrokを使っていたのですが、制限が多く実験中に困ることがありました。そんな中、Cloudflare Quick Tunnelsで代替できそうだったので実際に試してみました。

結論から言うと、アカウント不要で即使えるのは想像以上に便利ですね。ただし、万能ではないので、その辺りも書いておこうと思います。

なぜngrokから移行を検討したのか

Streamlitのシステムデモをするとき、ngrok(無料版)にはいくつか困る点があった。

  1. 転送量・リクエスト数などの上限に当たりやすい
  2. 同時接続数が制限されている

WSL環境で設定する

Windowsの導入は比較的ドキュメントが多いようだったので、今回は以下の環境で試してみました。

  • Windows 11
  • WSL2 (Ubuntu)
  • Python 3.12

1. cloudflaredのインストール

WSLのターミナルで以下を実行します。

$ wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
$ sudo dpkg -i cloudflared-linux-amd64.deb
$ cloudflared --version

特に問題なくインストールでき、バージョン情報が表示されればOKです。

2. 事前設定

事前にプロジェクトの設定を行なっておきます。

$ mkdir cloudflare-Tunnels
$ cd cloudflare-Tunnels/

$ uv venv
Using CPython 3.12.3 interpreter at: /usr/bin/python3
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate

$ source .venv/bin/activate

$ uv pip install streamlit pandas numpy

2. Streamlitアプリを起動

テスト用に簡単なアプリを作成します。

test_app.py

# test_app.py
import streamlit as st
import pandas as pd
import numpy as np

st.title('データ分析デモ')

data = pd.DataFrame({
    '日付': pd.date_range('2024-01-01', periods=100),
    '数値': np.random.randint(10, 100, 100)
})

st.line_chart(data.set_index('日付'))

プログラムの実行

$ streamlit run test_app.py

ブラウザでhttp://localhost:8501で起動することを確認。

3. Quick Tunnelで公開

別のターミナルで以下を実行:

$ cloudflared tunnel --url http://localhost:8501

すると、こんな感じでURLが表示されます。

+--------------------------------------------------------------------------------------------+
|  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |
|  https://shanghai-pierce-possibility-famous.trycloudflare.com                              |
+--------------------------------------------------------------------------------------------+

URLをブラウザで開くと、Streamlitアプリが表示された。本当にこれだけ

以下は別回線からiPadでアクセスを行なった場合のスクリーンショット

スマホからもアクセスできるし、HTTPSで接続されているのも良い🤩

良かった点😊

1. アカウント登録が不要

これが最大のメリット。cloudflaredをインストールするだけで使える。

2. 転送量・リクエスト数などの上限にひっかかりにくい

ngrokではアクセス数の上限に引っかかることが多かったのですが、変更することで引っかかりにくくなったようです。被験者の多い実験では結構これは大きいかな。

3. WSLでそのまま使える

WSL内のlocalhostを指定するだけで動く。IPアドレスを調べたり、ポートフォワーディングを設定したりする必要がない。 Windows + WSL環境でも、Linuxと同じ感覚で使えるのは助かる。

4. URLがHTTPSでアクセスできる

生成されるURLはHTTPSでアクセスできる。セキュリティ的にも安心だし、ブラウザの警告も出ない。

5. プログラムを起動後に、トンネルが起動できる

検証するアプリを起動してから、別のターミナルでトンネルを起動できる。順番を気にせずに使えるのは便利。

困った点・注意点🥲

もちろん万能ではない。使ってみて気づいた注意点も書いておく。

1. URLが毎回変わる

これはngrok(無料版)と同じ。再起動するたびにURLが変わる。

デモ中は起動したままにしておく必要がある。「ちょっとアプリを修正して再起動」すると、URLを共有し直さないといけない。

対策: デモ前にしっかりテストして、本番は再起動しないようにする。

2. URLが覚えにくい

生成されるURLは https://形容詞-名詞-動詞-副詞.trycloudflare.com みたいな感じで、かなり長い。

口頭で伝えるのは難しいので、Slackやメールで送るか、QRコード化するのが良さそう。

ということで、補助用のラッパースクリプトをpythonで作ってみました。

#!/usr/bin/env python3
"""
cloudflared_tunnel.py - Cloudflare Quick Tunnelを起動してURLを取得・保存するツール

使い方:
    python cloudflared_tunnel.py --url http://localhost:8501

必要なライブラリのインストール:
    pip install qrcode pillow
"""

import argparse
import subprocess
import re
import sys
import time
import os
import signal
from pathlib import Path

try:
    import qrcode
except ImportError:
    print("エラー: qrcodeライブラリがインストールされていません。")
    print("以下のコマンドでインストールしてください:")
    print("  pip install qrcode pillow")
    sys.exit(1)


# グローバル変数
cloudflared_process = None


def signal_handler(sig, frame):
    """シグナルハンドラ(Ctrl+C)"""
    print("\n")
    print("🛑 トンネルを停止しています...")
    if cloudflared_process:
        cloudflared_process.terminate()
        cloudflared_process.wait(timeout=5)
    print("✅ トンネルを停止しました")
    sys.exit(0)


def parse_arguments():
    """コマンドライン引数を解析"""
    parser = argparse.ArgumentParser(
        description='Cloudflare Quick Tunnelを起動してURLを取得・保存します',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
使用例:
  %(prog)s --url http://localhost:8501
  %(prog)s --url http://localhost:5000 --output-dir ./output

出力ファイル:
  URL.txt  - 生成されたトンネルのURL
  QR.png   - URLのQRコード画像

停止方法:
  Enter キーを押す、または Ctrl+C
        """
    )
    
    parser.add_argument(
        '--url',
        required=True,
        help='公開するローカルアプリのURL (例: http://localhost:8501)'
    )
    
    parser.add_argument(
        '--output-dir',
        default='.',
        help='出力ディレクトリ (デフォルト: カレントディレクトリ)'
    )
    
    parser.add_argument(
        '--url-file',
        default='URL.txt',
        help='URLを保存するファイル名 (デフォルト: URL.txt)'
    )
    
    parser.add_argument(
        '--qr-file',
        default='QR.png',
        help='QRコード画像のファイル名 (デフォルト: QR.png)'
    )
    
    return parser.parse_args()


def extract_tunnel_url(output_line):
    """cloudflaredの出力からトンネルURLを抽出"""
    # https://xxxxx.trycloudflare.com の形式のURLを探す
    url_pattern = r'https://[a-z0-9\-]+\.trycloudflare\.com'
    match = re.search(url_pattern, output_line)
    if match:
        return match.group(0)
    return None


def start_cloudflared_tunnel(local_url):
    """cloudflared tunnelを起動してURLを取得"""
    global cloudflared_process
    
    print(f"cloudflared tunnel を起動中...")
    print(f"ローカルURL: {local_url}")
    print("トンネルURLの取得を待機中...\n")
    
    try:
        # cloudflaredを起動
        cloudflared_process = subprocess.Popen(
            ['cloudflared', 'tunnel', '--url', local_url],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
            bufsize=1
        )
        
        # 出力を読み取ってURLを探す
        tunnel_url = None
        timeout = 30  # 30秒タイムアウト
        start_time = time.time()
        
        for line in cloudflared_process.stdout:
            print(line.rstrip())  # 出力を表示
            
            # URLを抽出
            url = extract_tunnel_url(line)
            if url:
                tunnel_url = url
                print(f"\n✅ トンネルURL取得成功: {tunnel_url}\n")
                break
            
            # タイムアウトチェック
            if time.time() - start_time > timeout:
                print(f"\n⚠️ タイムアウト: {timeout}秒以内にURLを取得できませんでした")
                cloudflared_process.terminate()
                return None
        
        if not tunnel_url:
            print("\n⚠️ トンネルURLを取得できませんでした")
            cloudflared_process.terminate()
            return None
        
        print("📝 cloudflaredプロセスが起動しました")
        print(f"   プロセスID: {cloudflared_process.pid}\n")
        
        return tunnel_url
        
    except FileNotFoundError:
        print("エラー: cloudflaredコマンドが見つかりません")
        print("cloudflaredがインストールされていることを確認してください")
        print("インストール方法: https://github.com/cloudflare/cloudflared")
        return None
    except Exception as e:
        print(f"エラー: cloudflaredの起動に失敗しました - {e}")
        return None


def save_url_to_file(url, file_path):
    """URLをテキストファイルに保存"""
    try:
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(url + '\n')
        print(f"✅ URLをファイルに保存しました: {file_path}")
        return True
    except Exception as e:
        print(f"⚠️ URLファイルの保存に失敗しました: {e}")
        return False


def generate_qr_code(url, file_path):
    """URLからQRコードを生成して画像ファイルに保存"""
    try:
        # QRコードを生成
        qr = qrcode.QRCode(
            version=1,  # 自動調整
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=10,
            border=4,
        )
        qr.add_data(url)
        qr.make(fit=True)
        
        # 画像を生成
        img = qr.make_image(fill_color="black", back_color="white")
        
        # ファイルに保存
        img.save(file_path)
        print(f"✅ QRコードを生成しました: {file_path}")
        return True
    except Exception as e:
        print(f"⚠️ QRコードの生成に失敗しました: {e}")
        return False


def main():
    """メイン処理"""
    # シグナルハンドラを登録
    signal.signal(signal.SIGINT, signal_handler)
    
    args = parse_arguments()
    
    # 出力ディレクトリの作成
    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)
    
    # 出力ファイルのパス
    url_file_path = output_dir / args.url_file
    qr_file_path = output_dir / args.qr_file
    
    print("=" * 60)
    print("Cloudflare Quick Tunnel URLキャプチャツール")
    print("=" * 60)
    print()
    
    # cloudflared tunnelを起動してURLを取得
    tunnel_url = start_cloudflared_tunnel(args.url)
    
    if not tunnel_url:
        print("\n❌ トンネルURLの取得に失敗しました")
        sys.exit(1)
    
    # URLをファイルに保存
    save_url_to_file(tunnel_url, url_file_path)
    
    # QRコードを生成
    generate_qr_code(tunnel_url, qr_file_path)
    
    print()
    print("=" * 60)
    print("✅ 処理完了")
    print("=" * 60)
    print(f"トンネルURL: {tunnel_url}")
    print(f"URLファイル: {url_file_path}")
    print(f"QRコード:   {qr_file_path}")
    print()
    print("💡 このURLを共有してアクセスしてもらってください")
    print("=" * 60)
    print()
    print("📌 トンネルは実行中です")
    print(f"   プロセスID: {cloudflared_process.pid}")
    print()
    print("⏸️  停止するには Enter キーを押してください")
    print("   (または Ctrl+C)")
    print()
    
    try:
        # キー入力待ち
        input()
    except KeyboardInterrupt:
        # Ctrl+Cの場合はシグナルハンドラが処理
        pass
    
    # トンネルを停止
    print("\n🛑 トンネルを停止しています...")
    if cloudflared_process:
        cloudflared_process.terminate()
        try:
            cloudflared_process.wait(timeout=5)
            print("✅ トンネルを停止しました")
        except subprocess.TimeoutExpired:
            cloudflared_process.kill()
            print("✅ トンネルを強制停止しました")
    print("=" * 60)


if __name__ == '__main__':
    main()

プログラムの実行

$ python cloudflared_tunnel.py --url http://localhost:8501

3. アクセス制限はかけられない

URLを知っていれば誰でもアクセスできる。手軽さの裏返しで、セキュリティ面では注意が必要。 短時間のデモなら問題ないが、機密情報を扱う場合は注意が必要。アプリ側で認証を実装するか、別の方法(永続トンネル + Cloudflare Access)を検討する必要がある。

今回の実験で気付いたこと 複数のトンネルを起動が可能!

最初、「1つのトンネルで複数のアプリを公開できないのか?」と思っていたけど、別のターミナルで別のトンネルを起動すればOKだった。つまり、複数のアプリを同時に公開できる。

# ターミナル1
$ streamlit run app1.py &
$ cloudflared tunnel --url http://localhost:8501

# ターミナル2
$ python -m http.server 8000 &
$ cloudflared tunnel --url http://localhost:8000

それぞれ異なるURLが生成される。当たり前のことだが、最初気づかなかったけど、複数のアプリを同時に公開できるのは便利。

おわりに

Cloudflare Quick Tunnelsを実際に使ってみた感想としては以下のようになるでしょうか。

良かったこと

  • 時間制限がなく、安心してデモできる
  • WSL環境でもそのまま使える
  • 複数のトンネルを同時に起動できる
  • HTTPSでアクセスできる

注意すること

  • URLが毎回変わる(再起動で変わる)
  • アクセス制限はかけられない
  • URLが長くて覚えにくいかも

向いている用途

  • 授業・ワークショップでのデモ
  • 一時的なプレビュー共有
  • PoCシステムの発表

向いていない用途

  • 長期運用(固定URLが必要)
  • 機密情報を扱うシステム(認証が必要)

個人的にはngrokの「面倒な部分」(アカウント登録、2時間制限)を解消してくれるサービスといえるかな。 デモで「ちょっと見せたい」には最適。ただし、本格的な運用には向かないので、用途に応じて使い分けるのが良さそう。

もし、固定URLが必要になったら、cloudflareにある永続トンネル(ドメイン必要)を検討するのも良いかも。 ただ、ドメインが必要なので、ドメインの管理コストも必要です。

参考リンク

github.com

developers.cloudflare.com