0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

tailscaleを使ってサブドメインを割り当てる方法

0
Last updated at Posted at 2026-04-07

DiscordのBotを自家サーバーで動かしたいなーと思い,tailscaleでポートを外部公開することにしました.ついでに,拡張性も加味して,サブドメインで通信の振り分けもできるようにしています.

環境

  • ハードウェアは昔使ってたPCを流用しました.i5-6700とかです.
  • それぞれのバージョンはUbuntu(24.04.4 LTS),Docker(29.3.1),DockerCompose(v5.1.1),Tailscale(1.94.2)です.

tailscale側の設定

今回はBotあての通信を5050番ポートに転送します.

  1. タスクバーからadminコンソールを開く
  2. AccessControlを開き,create Tagsを選択.タグを作成する.
    • name:"tag:好きな名前"のフォーマット
    • owner:tailscaleに登録しているメアド.ドロップダウンの一番下にあるはず.
    • Note:メモ書きなので書かなくてもOK.
  3. settingタブを開き,メニューからKeysを選択.Auth Keysを作成する.
    • Description:メモ書きなので書かなくてもOK.
    • reuseable:再利用を可にするか.チェックつけておいた方がいい?つけないで使ってたらある日つながらなくなった.
    • Expiration:とりあえず動作確認できればいいので最長の30日.タグを設定すれば無限になる.
    • Ephemerarl:停止したデバイスをMachinesリストから消去するか.OFFだと停止したコンテナが大量に残るのでON.
    • Tags:さっき作成したタグを設定.
  4. 作成されたキーのフルパスをコピー(なくさない!流出させない!)

Docker側の設定

公式ドキュメントを参考に,Geminiをシバきながら作成しました.

ディレクトリ構成
project
└─ DiscordBot
    ├─ .env
    ├─ docker-compose.yml
    ├─ Dockerfile
    ├─ test.py
    └─ tailscale
        └─ ...(自動生成される)
docker-compose.yml
services:
  myapp:
    build: . # Dockerfileをビルド
    container_name: myapp # コンテナ名
    network_mode: "service:myvpn" # ネットワークモードの指示
    depends_on: # ネットワーク担当コンテナが起動してからこのコンテナを起動
      - myvpn
    volumes: # 今のディレクトリをコンテナの /app に同期
      - .:/app
    working_dir: /app # 作業場所を /app に固定
    tty: true # デバッグ用に仮想端末の有効化
    stdin_open: true # デバッグ用に標準入力の有効化
    restart: always # 起動に失敗したら再起動

  myvpn:
    image: tailscale/tailscale:stable # tailscaleの最新安定板を指定
    container_name: myvpn # コンテナ名
    hostname: discord  # サブドメイン名(今回はdiscordと通信するコンテナなのでdiscord)
    env_file: # 環境変数は.envで管理
      - .env
    volumes: # ボリュームのマウント
      - tailscale:/var/lib/tailscale
      - /dev/net/tun:/dev/net/tun
    cap_add: # ネットワーク管理者権限とカーネルモジュール操作権限を与える
      - net_admin
      - sys_module
    devices: # TUNモジュールの使用を指示
      - /dev/net/tun:/dev/net/tun
    restart: unless-stopped # こちらから停止していなければ停止時に再起動

volumes: # 権限問題を回避するためにボリュームを作成
  tailscale:
    driver: local
Dockerfile
# ビルドするPythonのバージョン指定
FROM python:3.12-slim 

# ワークディレクトリの指定
WORKDIR /app 

# 必要なライブラリをインストール
RUN pip install --no-cache-dir discord.py \
    fastapi \
    uvicorn[standard]

# デバッグのためにコンテナを永続化
CMD ["tail", "-f", "/dev/null"]
.env
TS_AUTHKEY=tskey-auth-...
TS_STATE_DIR=/var/lib/tailscale
TS_USERSPACE=true
test.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "サーバー起動!"}

@app.post("/interactions")
def interactions():
    # 本来はここにDiscordの検証ロジックが入る
    return {"type": 1}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("test:app", host="0.0.0.0", port=5050, reload=True)

上記構成でdocker compose up -d --buildを実行し,docker exec -it myapp python3 test.pyでuvicornサーバーを起動します.

Terminal
INFO:     Will watch for changes in these directories: ['/app']
INFO:     Uvicorn running on http://0.0.0.0:5050 (Press CTRL+C to quit)
INFO:     Started reloader process [7] using WatchFiles
INFO:     Started server process [14]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

起動が終わったら,tailscaleのadminコンソールよりDNSタブを開き,MagicDNSとHTTPS Certificatesが有効になっていることを確認します.下のボタンがDisable...担っていればMagicDNSは現在有効です.

起動したコンテナに対してdocker exec myvpn tailscale funnel 5050を実行すると,

Terminal
Funnel is enabled, but the list of allowed nodes in the tailnet policy file does not include the one you are using.
To give access to this node you can edit the tailnet policy file, or visit:

         https://login.tailscale.com/f/funnel?node=...

と表示されるので,リンクを踏んでボタンをクリックするとURLがゲットできます!!

そのリンクをスマホや別のPCで開けば,画面に{"message": "サーバー起動!"}が表示されるはずです.

トラブル

記憶とGeminiとのトーク履歴を元に書いているので,間違っている部分があるかもしれません.

docker compose up -dしてもmachinesに追加されない

コンテナを起動してもadminコンソールのmachinesに追加されないので,docker logs myvpnでコンテナのログを確認.

最後のログ2026/04/04 07:11:00 health(warnable=warming-up): okをgeminiに投げると,「Tailscaleのエンジンは起動したけど外部との通信はできてない.1分経っても接続できなかったらコマンドの実行でコケてるかも.」とのこと.なのでアドバイス通りコマンドからシングルクォーテーションを消去.

.env
TS_AUTHKEY=tskey-auth-...
TS_STATE_DIR=/var/lib/tailscale
- TAILSCALE_SERVE_CONFIG='{"Web":{"443":{"Handlers":{"/":{"Proxy":"http://127.0.0.1:5050"}}}},"AllowFunnel":{"443":true}}'
+ TS_SERVE_CONFIG={"Web":{"443":{"Handlers":{"/":{"Proxy":"http://127.0.0.1:5050"}}}},"AllowFunnel":{"443":true}}

docker compose downののちにdocker compose up -dしてログを再度確認すると,

Terminal
To authenticate, visit:

        https://login.tailscale.com/~~~~

2026/04/04 07:16:01 health(warnable=warming-up): ok

が出力されていたので成功か?と思ったけどよく見たら認証のためにリンクをふむ必要があるらしい.なのでURLを開いてログインし,表示されるconnectのボタンをクリックしてめでたくmachinesに追加.

あとから気づいたけども,これ環境変数名TS_SERVE_CONFIGTAILSCALE_SERVE_CONFIGに変えちゃってたのが原因かも.ってことで,ダブルクォーテーションを元に戻して環境変数名のみ変えて再チャレンジ.

.env
TS_AUTHKEY=tskey-auth-...
TS_STATE_DIR=/var/lib/tailscale
TS_SERVE_CONFIG='{"Web":{"443":{"Handlers":{"/":{"Proxy":"http://127.0.0.1:5050"}}}},"AllowFunnel":{"443":true}}'

結果,docker compose up -dするも接続は成功せず.結局変数名変更&シングルクォーテーション削除で接続成功.

.env
TS_AUTHKEY=tskey-auth-...
TS_STATE_DIR=/var/lib/tailscale
- TS_SERVE_CONFIG='{"Web":{"443":{"Handlers":{"/":{"Proxy":"http://127.0.0.1:5050"}}}},"AllowFunnel":{"443":true}}'
+ TS_SERVE_CONFIG={"Web":{"443":{"Handlers":{"/":{"Proxy":"http://127.0.0.1:5050"}}}},"AllowFunnel":{"443":true}}

.pyを実行することができない

pythonを実行しようとすると

Error response from daemon: Container <コンテナID> is restarting, wait until the container is running

というエラーが返ってきた.起動時に再起動ループにハマっているようだったが,原因がイマイチわからず.抜けていた作業ディレクトリの指示を追記するも改善はしなかった.「myvpnの通信確立までにラグがあって,dependでmyvpnの起動を待つだけでは行けないのかも.」ということでhealthcheckを追加したが,コンテナすら起動しなくなってしまう.移行どういう順番で実施したか覚えていませんが,

  • 実行モードをUserPlaceモードに変更.
  • マウント先をローカルボリュームに変更.
  • ヘルスチェックの無効化.
  • CMD ["tail", "-f", "/dev/null"]を追記.
  • TS_SERVE_CONFIG={"Web":{"443":{"Handlers":{"/":{"Proxy":"http://127.0.0.1:5050"}}}},"AllowFunnel":{"443":true}}を削除.
    することで無事疎通確認.

2026/4/8追記:証明書エラーが発生する

ある時から,なぜか
image.png
が表示されるようになってしまいました.再読み込みしてもtest.pyを立ち上げなおしても改善せず.ふとシークレットウィンドウで開いてみるとすんなり開いたので,ブラウザのキャッシュが原因の可能性が高そうです.スーパーリロードを試しても解決しなかったため,

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?