সম্পূর্ণ বাংলা গাইড

Termux দিয়ে ফোনকে
সার্ভার বানাও

কোনো অভিজ্ঞতা ছাড়াই তোমার Android ফোনে FTP ক্লাউড ড্রাইভ অথবা পূর্ণ ওয়েবসাইট হোস্ট করো। শুরু থেকে শেষ পর্যন্ত, একদম সহজ বাংলায়।

Termux ডাউনলোড করুন — GitHub APK
Google Play-এর Termux পুরনো এবং অসম্পূর্ণ — সবসময় GitHub থেকে ডাউনলোড করো

আগে ঠিক করো তুমি কী বানাতে চাও। একটি বেছে নিলে নিচে শুধু সেই পথের ধাপগুলো দেখাবে:

👆 একটি বেছে নাও — তাহলেই নিচে সেটআপ ধাপগুলো দেখাবে। প্রথমের ৩টি ধাপ (১–৩) দুই পথেই লাগবে।
সবার জন্য
১

Termux কী এবং কীভাবে ইনস্টল করবো

Termux হলো Android-এর একটি Linux টার্মিনাল অ্যাপ। সহজ ভাষায় বললে — এটি তোমার ফোনের মধ্যে একটি ছোট কম্পিউটার তৈরি করে যেখানে তুমি কোড লিখতে ও চালাতে পারো। Windows-এর Command Prompt বা Mac-এর Terminal-এর মতো, কিন্তু ফোনে।

Termux দিয়ে তুমি Python, Node.js চালাতে পারবে, ওয়েব সার্ভার তৈরি করতে পারবে, এবং তোমার ফোনের ফাইলগুলো ইন্টারনেটে শেয়ার করতে পারবে — একদম বিনামূল্যে।

⚠️
গুরুত্বপূর্ণ: Google Play Store-এ Termux আছে কিন্তু সেটি পুরনো এবং অনেক ফিচার কাজ করে না। সবসময় GitHub থেকে APK ডাউনলোড করো।
A
GitHub থেকে ডাউনলোড করো

এই লিংকে যাও এবং termux-app_v*.apk ফাইলটি ডাউনলোড করো:

Download URL
https://github.com/termux/termux-app/releases/latest
B
APK ইনস্টল করো

ডাউনলোড হলে APK ফাইলে ট্যাপ করো। Android হয়তো বলবে "Unknown source থেকে install করতে চাও?" — Allow দাও। ইনস্টল হয়ে গেলে Termux খোলো।

C
প্রথমবার Termux খোলার পর

একটি কালো স্ক্রিন দেখবে এবং $ চিহ্ন দেখাবে — এটাই কমান্ড লেখার জায়গা। এখানে তুমি কমান্ড টাইপ করবে এবং Enter চাপলে সেটি চলবে।

💡
টিপস: স্ক্রিনের বাম দিক থেকে ডানে সোয়াইপ করলে মেনু আসে — সেখানে "New Session" দিলে একসাথে একাধিক কাজ করা যায়। এটা পরে কাজে লাগবে।
সবার জন্য
২

প্যাকেজ আপডেট ও ইনস্টলেশন

Termux ইনস্টলের পর প্রথম কাজ হলো সব কিছু আপডেট করা এবং দরকারি টুল ইনস্টল করা। নিচের কমান্ডগুলো একটার পর একটা চালাও:

ধাপ ১: ফোনের স্টোরেজ অ্যাক্সেস করার অনুমতি নাও

Termux
termux-setup-storage

একটি popup আসবে — Allow দাও। এটা দিলে Termux তোমার /sdcard/ ফোল্ডার অ্যাক্সেস করতে পারবে।

ধাপ ২: সব প্যাকেজ আপডেট করো

Termux
pkg update && pkg upgrade -y
💡
এটা চলতে কয়েক মিনিট লাগতে পারে। কোনো প্রশ্ন আসলে শুধু Enter চাপো। ইন্টারনেট চালু রাখো।
⚠️
"Unable to locate package" বা mirror error আসলে: termux-change-repo লিখে Enter দাও, একটি mirror বেছে নিয়ে (Space দিয়ে সিলেক্ট → Enter) আবার pkg update চালাও।

ধাপ ৩: দরকারি টুল ইনস্টল করো

Termux
pkg install python nano cloudflared procps curl -y

ধাপ ৪: Flask ওয়েব ফ্রেমওয়ার্ক ইনস্টল করো

Termux
pip install flask

তুমি যা ইনস্টল করলে:

টুলকাজ কী
pythonসার্ভার চালানোর মূল প্রোগ্রামিং ভাষা
nanoটার্মিনালের ভেতরে ফাইল তৈরি ও এডিট করার এডিটর
cloudflaredফোনের সার্ভারকে ইন্টারনেটে পাবলিক লিংক দেয়
flaskPython দিয়ে ওয়েব সার্ভার বানানোর টুল
procpspkill কমান্ড দেয় — সার্ভার বন্ধ করতে লাগবে
curlসার্ভার চলছে কিনা পরীক্ষা করার টুল
সবার জন্য — গুরুত্বপূর্ণ
৩

Nano Editor — ফাইল তৈরি ও এডিট করা

Nano হলো টার্মিনালের ভেতরে কাজ করার একটি সহজ টেক্সট এডিটর। তুমি এটা দিয়ে Python ফাইল, HTML ফাইল — যেকোনো ফাইল তৈরি ও এডিট করতে পারবে। এই গাইডে সব ফাইল এই nano দিয়ে তৈরি করা হবে।

⌨️
ফোনে Ctrl কীভাবে চাপবে? Termux-এর কীবোর্ডের ওপরে একটি অতিরিক্ত বাটনের সারি (ESC, TAB, CTRL, ALT…) থাকে। CTRL একবার ট্যাপ করো (হাইলাইট হবে), তারপর অক্ষর কী ট্যাপ করো। যেমন Ctrl+O মানে: CTRL ট্যাপ → O ট্যাপ। সারিটি না দেখালে Volume Up + Q চাপো। বিকল্প: Volume Down চেপে ধরে অক্ষর চাপলেও Ctrl কাজ করে।
A
নতুন ফাইল তৈরি করা

যেকোনো ফাইল তৈরি করতে nano এর পর ফাইলের নাম লিখো:

উদাহরণ
nano ~/myfile.py

এতে nano খুলবে এবং তুমি লিখতে পারবে। ফাইলটি ~ (home) ফোল্ডারে তৈরি হবে। ফাইলটি আগে থেকে থাকলে খুলবে, না থাকলে নতুন তৈরি হবে।

B
কোড পেস্ট করা (ফোনে)

nano খোলার পর কোড পেস্ট করতে — টার্মিনালের স্ক্রিনে যেকোনো জায়গায় আঙুল দিয়ে লং-প্রেস করো। একটি মেনু আসবে — সেখানে Paste ট্যাপ করো।

💡
আগে ফোনের ক্লিপবোর্ডে কোডটি কপি করে রাখো (Copy বাটনে ট্যাপ করে), তারপর nano-তে পেস্ট করো।
C
Nano-র কীবোর্ড শর্টকাট
শর্টকাটকী করে
Ctrl + Oফাইল সেভ করো (Write Out) — চাপার পর Enter দাও
Ctrl + Xnano থেকে বের হও (Exit)
Ctrl + Kপুরো একটা লাইন কেটে ফেলো (Cut)
Ctrl + Wকোনো শব্দ খোঁজো (Search/Where)
Ctrl + Aলাইনের শুরুতে যাও
Ctrl + Eলাইনের শেষে যাও
Ctrl + Cকার্সর কোথায় আছে দেখো
✅
সেভ করার সঠিক পদ্ধতি: Ctrl+O চাপো → স্ক্রিনে ফাইলের নাম দেখাবে → Enter চাপো → তারপর Ctrl+X চাপলে বের হবে।
D
ফাইলের কোড সম্পূর্ণ পরিষ্কার করা

যদি পুরো ফাইলের কোড মুছে নতুন করে লিখতে চাও, nano থেকে বের হয়ে এই কমান্ড চালাও:

ফাইল খালি করো
truncate -s 0 ~/myfile.py

এতে ফাইলটি থাকবে কিন্তু ভেতরের সব কোড মুছে যাবে। এরপর nano ~/myfile.py দিয়ে নতুন কোড লিখতে পারবে।

অথবা, nano-র ভেতরে থাকলে প্রতিটি লাইন Ctrl+K দিয়ে মুছো।

E
ফাইল ডিলিট করা
ফাইল ডিলিট
rm ~/myfile.py
ফোল্ডার ডিলিট
rm -rf ~/mywebsite
⚠️
সাবধান: rm কমান্ড দিলে ফাইল চিরতরে মুছে যায়, Recycle Bin-এ যায় না।

প্রস্তুতি শেষ! 🎉 এবার বেছে নাও কী বানাবে। বেছে নিলে নিচে শুধু সেই ধাপগুলো দেখাবে:

☁ FTP ক্লাউড ড্রাইভ
৪

fileserver.py — ক্লাউড সার্ভার কোড

এই Python ফাইলটি তোমার ফাইল সার্ভারের মূল কোড। এটি তোমার /sdcard/PublicCloud ফোল্ডারের ফাইলগুলো ব্রাউজারে দেখাবে এবং ডাউনলোড করতে দেবে। কোনো admin প্যানেল বা পাসওয়ার্ড নেই — সরল এবং হালকা।

প্রথমে সার্ভারের ফোল্ডার ও ফাইল একসাথে তৈরি করো:

Termux
mkdir -p ~/server/templates && nano ~/server/fileserver.py

nano খুললে নিচের পুরো কোডটি কপি করে পেস্ট করো, তারপর Ctrl+O → Enter → Ctrl+X:

fileserver.py
import os
import math
import socket
from datetime import datetime
from flask import (
    Flask, render_template, send_from_directory,
    send_file, abort
)

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
app = Flask(__name__, template_folder=os.path.join(BASE_DIR, "templates"))

# ফাইল শেয়ার করার ফোল্ডার (শুধু এই ফোল্ডারটিই শেয়ার হবে)
SHARED_DIR = os.path.realpath("/sdcard/PublicCloud")
os.makedirs(SHARED_DIR, exist_ok=True)


def safe_path(rel):
    """ফোল্ডারের বাইরে যাওয়া ঠেকায়"""
    result = os.path.realpath(os.path.join(SHARED_DIR, rel))
    if result != SHARED_DIR and not result.startswith(SHARED_DIR + os.sep):
        abort(403)
    return result


def human_size(n):
    if n == 0:
        return "0 B"
    units = ["B", "KB", "MB", "GB", "TB"]
    i = min(int(math.floor(math.log(n, 1024))), 4)
    return f"{n / 1024 ** i:.1f} {units[i]}"


def file_icon(name):
    ext = os.path.splitext(name)[1].lower()
    groups = [
        ((".mp4", ".mkv", ".webm", ".avi", ".mov"), "🎬"),
        ((".mp3", ".wav", ".ogg", ".m4a", ".flac"), "🎵"),
        ((".jpg", ".jpeg", ".png", ".gif", ".webp"), "🖼️"),
        ((".pdf",), "📄"),
        ((".zip", ".rar", ".tar", ".gz", ".7z"), "📦"),
        ((".py", ".js", ".html", ".css", ".json", ".xml",
          ".md", ".sh", ".txt", ".csv", ".log"), "📝"),
    ]
    for exts, icon in groups:
        if ext in exts:
            return icon
    return "📎"


def local_ip():
    """একই WiFi-তে অন্য ডিভাইস থেকে ঢোকার জন্য ফোনের IP"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        sock.connect(("8.8.8.8", 80))
        return sock.getsockname()[0]
    except OSError:
        return "আপনার-ফোনের-IP"
    finally:
        sock.close()


@app.route("/", defaults={"req_path": ""})
@app.route("/<path:req_path>")
def browse(req_path):
    abs_path = safe_path(req_path)
    if not os.path.exists(abs_path):
        abort(404)

    # ফাইল হলে সরাসরি খুলে দাও
    if os.path.isfile(abs_path):
        return send_from_directory(
            os.path.dirname(abs_path), os.path.basename(abs_path)
        )

    # ফোল্ডার হলে তালিকা দেখাও
    entries = []
    for name in os.listdir(abs_path):
        if name.startswith("."):
            continue
        full = os.path.join(abs_path, name)
        is_dir = os.path.isdir(full)
        try:
            st = os.stat(full)
            size = "—" if is_dir else human_size(st.st_size)
            mtime = datetime.fromtimestamp(st.st_mtime).strftime("%d %b %Y")
        except OSError:
            size, mtime = "—", "—"
        entries.append({
            "name": name,
            "path": (req_path.strip("/") + "/" + name).lstrip("/"),
            "is_dir": is_dir,
            "icon": "📂" if is_dir else file_icon(name),
            "size": size,
            "mtime": mtime,
        })

    # ফোল্ডার আগে, তারপর ফাইল
    entries.sort(key=lambda e: (not e["is_dir"], e["name"].lower()))

    clean = req_path.strip("/")
    parent = "/".join(clean.split("/")[:-1]) if clean else None

    return render_template(
        "files.html",
        entries=entries,
        current_path=clean,
        parent=parent,
        folder_name=os.path.basename(abs_path) or "PublicCloud",
    )


@app.route("/dl/<path:req_path>")
def download(req_path):
    abs_path = safe_path(req_path)
    if os.path.isfile(abs_path):
        return send_file(abs_path, as_attachment=True)
    abort(404)


if __name__ == "__main__":
    print("=" * 44)
    print("✅  Cloud File Server চালু হয়েছে!")
    print(f"📁  ফাইল ফোল্ডার: {SHARED_DIR}")
    print("💻  এই ফোনে:       http://localhost:8080")
    print(f"📶  একই WiFi-তে:    http://{local_ip()}:8080")
    print("=" * 44)
    app.run(host="0.0.0.0", port=8080, debug=False)
💡
SHARED_DIR পরিবর্তন: যদি অন্য ফোল্ডার শেয়ার করতে চাও, কোডের SHARED_DIR = "/sdcard/PublicCloud" লাইনে ফোল্ডারের পথ বদলে দাও।
☁ FTP ক্লাউড ড্রাইভ
৫

HTML Template তৈরি করা

fileserver.py আলাদা একটি HTML ফাইল ব্যবহার করে — এতে Python কোড এবং HTML আলাদা থাকে, পরিবর্তন করা সহজ হয়। প্রথমে templates ফোল্ডার তৈরি করো:

Termux
mkdir -p ~/server/templates && nano ~/server/templates/files.html

nano খুললে নিচের HTML কোডটি পেস্ট করো, তারপর Ctrl+O → Enter → Ctrl+X:

~/server/templates/files.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ folder_name }} — Cloud Drive</title>
<style>
  * { box-sizing: border-box; margin: 0; padding: 0; }
  body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    background: #0f172a; color: #cbd5e1;
    min-height: 100vh; padding: 24px 16px;
  }
  .wrap { max-width: 860px; margin: 0 auto; }
  h1 { font-size: 22px; font-weight: 700; color: #f1f5f9; margin-bottom: 4px; }
  .sub { font-size: 13px; color: #64748b; margin-bottom: 24px; }
  .pathbar {
    background: #1e293b; border: 1px solid #334155;
    border-radius: 8px; padding: 8px 14px;
    font-size: 13px; font-family: monospace;
    color: #94a3b8; margin-bottom: 16px;
    display: flex; align-items: center; gap: 8px;
  }
  .table-wrap {
    border: 1px solid #1e293b; border-radius: 10px; overflow: hidden;
  }
  table { width: 100%; border-collapse: collapse; }
  thead tr { background: #1e293b; }
  th {
    text-align: left; padding: 10px 16px;
    font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.8px;
    color: #475569;
  }
  td { padding: 10px 16px; border-top: 1px solid #1e293b; font-size: 14px; }
  tr:hover td { background: rgba(255,255,255,0.02); }
  .name-cell { display: flex; align-items: center; gap: 10px; }
  .icon { font-size: 18px; flex-shrink: 0; line-height: 1; }
  a { color: #94a3b8; text-decoration: none; }
  a:hover { color: #60a5fa; }
  .dir-link { color: #60a5fa; font-weight: 500; }
  .size-cell { color: #475569; font-family: monospace; font-size: 12px; white-space: nowrap; }
  .date-cell { color: #475569; font-size: 12px; white-space: nowrap; }
  .dl-btn {
    display: inline-flex; align-items: center; gap: 4px;
    background: #1e293b; border: 1px solid #334155;
    color: #94a3b8; font-size: 11px; font-weight: 500;
    padding: 4px 10px; border-radius: 5px;
    text-decoration: none; transition: all 0.15s;
  }
  .dl-btn:hover { border-color: #60a5fa; color: #60a5fa; }
  .empty { padding: 48px; text-align: center; color: #334155; font-size: 14px; }
  .back {
    display: inline-flex; align-items: center; gap: 6px;
    background: #1e293b; border: 1px solid #334155;
    color: #94a3b8; text-decoration: none;
    padding: 7px 14px; border-radius: 7px;
    font-size: 13px; margin-bottom: 16px;
    transition: all 0.15s;
  }
  .back:hover { color: #f1f5f9; border-color: #475569; }
  input[type=text] {
    width: 100%; background: #1e293b; border: 1px solid #334155;
    color: #cbd5e1; padding: 8px 14px; border-radius: 8px;
    font-size: 13px; outline: none; margin-bottom: 12px;
  }
  input[type=text]:focus { border-color: #3b82f6; }
  @media (max-width: 600px) {
    .date-cell, .size-cell { display: none; }
  }
</style>
</head>
<body>
<div class="wrap">
  <h1>☁ {{ folder_name }}</h1>
  <p class="sub">Cloud File Browser — /{{ current_path }}</p>

  {% if parent is not none %}
  <a href="/{{ parent|urlencode }}" class="back">← Back</a>
  {% endif %}

  <div class="pathbar">📂 /{{ current_path or "PublicCloud" }}</div>
  <input type="text" id="search" placeholder="🔍  ফাইল খুঁজুন..." oninput="filterTable(this.value)">

  <div class="table-wrap">
    <table>
      <thead>
        <tr>
          <th>নাম</th>
          <th class="size-cell">সাইজ</th>
          <th class="date-cell">তারিখ</th>
          <th></th>
        </tr>
      </thead>
      <tbody id="tbody">
        {% if not entries %}
        <tr><td colspan="4" class="empty">ফোল্ডার খালি — /sdcard/PublicCloud-এ ফাইল রাখো</td></tr>
        {% endif %}
        {% for e in entries %}
        <tr>
          <td>
            <div class="name-cell">
              <span class="icon">{{ e.icon }}</span>
              {% if e.is_dir %}
              <a href="/{{ e.path|urlencode }}" class="dir-link">{{ e.name }}/</a>
              {% else %}
              <a href="/{{ e.path|urlencode }}">{{ e.name }}</a>
              {% endif %}
            </div>
          </td>
          <td class="size-cell">{{ e.size }}</td>
          <td class="date-cell">{{ e.mtime }}</td>
          <td>
            {% if not e.is_dir %}
            <a href="/dl/{{ e.path|urlencode }}" class="dl-btn">⬇ Download</a>
            {% endif %}
          </td>
        </tr>
        {% endfor %}
      </tbody>
    </table>
  </div>
</div>

<script>
function filterTable(q) {
  const rows = document.querySelectorAll('#tbody tr');
  rows.forEach(r => {
    const text = r.querySelector('td')?.textContent?.toLowerCase() || '';
    r.style.display = text.includes(q.toLowerCase()) ? '' : 'none';
  });
}
</script>
</body>
</html>

সেভ করো: Ctrl+O → Enter → Ctrl+X

এখন তোমার ফাইল কাঠামো হবে:

ফাইল কাঠামো
~/server/
├── fileserver.py       ← Python সার্ভার
└── templates/
    └── files.html      ← HTML ইন্টারফেস
☁ FTP ক্লাউড ড্রাইভ
৬

ক্লাউড সার্ভার চালানো

প্রথমে /sdcard/PublicCloud ফোল্ডারটি আছে কিনা দেখো (না থাকলে তৈরি হবে):

Termux
mkdir -p /sdcard/PublicCloud

এবার সার্ভার চালাও:

Termux
python ~/server/fileserver.py

স্ক্রিনে এরকম দেখাবে:

Output
============================================
✅  Cloud File Server চালু হয়েছে!
📁  ফাইল ফোল্ডার: /storage/emulated/0/PublicCloud
💻  এই ফোনে:       http://localhost:8080
📶  একই WiFi-তে:    http://192.168.x.x:8080
============================================
✅
এখন ফোনের ব্রাউজারে http://localhost:8080 লিখলে তোমার ক্লাউড ড্রাইভ দেখবে!

ফাইল যোগ করতে: ফোনের File Manager দিয়ে Internal Storage → PublicCloud ফোল্ডারে যেকোনো ফাইল কপি করো। ব্রাউজার রিফ্রেশ করলে দেখাবে।

সার্ভার বন্ধ করতে: Termux-এ Ctrl+C চাপো।

💡
এই পদ্ধতিতে Termux খোলা রাখতে হয়। ব্যাকগ্রাউন্ডে চালিয়ে রাখার সহজ উপায় ধাপ ৭-এ (cloudgo)।
🌐 ওয়েবসাইট হোস্ট
৪

ওয়েবসাইটের ফোল্ডার ও index.html তৈরি

তোমার ওয়েবসাইটের সব ফাইল (HTML, CSS, ছবি) থাকবে ~/mywebsite ফোল্ডারে। প্রথম পেজের নাম অবশ্যই index.html হতে হবে — কেউ সাইটে ঢুকলে এটাই প্রথমে দেখাবে।

Termux
mkdir -p ~/mywebsite && nano ~/mywebsite/index.html

nano খুললে এই উদাহরণ পেস্ট করো (পরে নিজের মতো বদলাবে):

~/mywebsite/index.html
<!DOCTYPE html>
<html lang="bn">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>আমার ওয়েবসাইট</title>
  <style>
    body { font-family: sans-serif; text-align: center; padding: 60px 16px; background: #0f172a; color: #fff; }
    h1 { font-size: 36px; }
  </style>
</head>
<body>
  <h1>👋 হ্যালো পৃথিবী!</h1>
  <p>আমার ওয়েবসাইট Termux থেকে চলছে।</p>
</body>
</html>

সেভ করো: Ctrl+O → Enter → Ctrl+X।

💡
ছবি বা ফাইল যোগ করতে: ফোনের Download ফোল্ডার থেকে কপি করো: cp /sdcard/Download/photo.jpg ~/mywebsite/। তারপর HTML-এ <img src="photo.jpg"> লিখলেই দেখাবে। CSS আলাদা ফাইলে রাখতে: nano ~/mywebsite/style.css বানিয়ে HTML-এ <link rel="stylesheet" href="style.css"> দাও।
🌐 ওয়েবসাইট হোস্ট
৫

webserver.py তৈরি করা

এই Python ফাইলটি ~/mywebsite ফোল্ডারের ফাইলগুলো ব্রাউজারে পাঠায়। এটি ওয়েবসাইট ফোল্ডারের বাইরে (~/webserver.py) থাকবে, যাতে কেউ সার্ভারের কোড দেখতে না পারে।

Termux
nano ~/webserver.py

নিচের কোড পেস্ট করে সেভ করো (Ctrl+O → Enter → Ctrl+X):

~/webserver.py
import os
import socket
from flask import Flask, send_from_directory, abort

app = Flask(__name__)

# তোমার ওয়েবসাইটের ফোল্ডার
WEB_DIR = os.path.realpath(os.path.expanduser("~/mywebsite"))
os.makedirs(WEB_DIR, exist_ok=True)


def local_ip():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        sock.connect(("8.8.8.8", 80))
        return sock.getsockname()[0]
    except OSError:
        return "আপনার-ফোনের-IP"
    finally:
        sock.close()


@app.route("/", defaults={"path": ""})
@app.route("/<path:path>")
def serve(path):
    full = os.path.realpath(os.path.join(WEB_DIR, path))
    # ফোল্ডারের বাইরে যাওয়া ঠেকাও
    if full != WEB_DIR and not full.startswith(WEB_DIR + os.sep):
        abort(403)
    # ফোল্ডার হলে তার index.html দেখাও
    if os.path.isdir(full):
        full = os.path.join(full, "index.html")
    if not os.path.isfile(full):
        abort(404)
    return send_from_directory(os.path.dirname(full), os.path.basename(full))


if __name__ == "__main__":
    print("=" * 44)
    print("🌐  ওয়েবসাইট চালু হয়েছে!")
    print(f"📂  ওয়েব ফোল্ডার: {WEB_DIR}")
    print("💻  এই ফোনে:       http://localhost:8080")
    print(f"📶  একই WiFi-তে:    http://{local_ip()}:8080")
    print("=" * 44)
    app.run(host="0.0.0.0", port=8080, debug=False)
🌐 ওয়েবসাইট হোস্ট
৬

ওয়েবসাইট চালানো

Termux
python ~/webserver.py

স্ক্রিনে এমন দেখাবে:

Output
============================================
🌐  ওয়েবসাইট চালু হয়েছে!
📂  ওয়েব ফোল্ডার: /data/data/com.termux/files/home/mywebsite
💻  এই ফোনে:       http://localhost:8080
📶  একই WiFi-তে:    http://192.168.x.x:8080
============================================
✅
ফোনের ব্রাউজারে http://localhost:8080 খুললে তোমার ওয়েবসাইট দেখাবে।

পরিবর্তন করলে: সার্ভার আবার চালাতে হবে না। ফাইল এডিট করে সেভ করো, তারপর ব্রাউজারে রিফ্রেশ দাও (না বদলালে ক্যাশ রিফ্রেশ করো)।

সার্ভার বন্ধ করতে: Termux-এ Ctrl+C চাপো। ব্যাকগ্রাউন্ডে চালাতে ধাপ ৭ দেখো।

সবার জন্য
৭

ব্যাকগ্রাউন্ড শর্টকাট — এক শব্দে চালু/বন্ধ

সার্ভার সরাসরি চালালে Termux-এর ওই স্ক্রিন আটকে থাকে। এই শর্টকাটগুলো সার্ভার ব্যাকগ্রাউন্ডে চালায়, তাই Termux-এ অন্য কাজও করতে পারবে। নিচের পুরো কমান্ডটি একবারে কপি করে পেস্ট করে Enter দাও — nano লাগবে না:

Termux — একবারে পেস্ট করো
cat >> ~/.bashrc << 'EOF'

# ── Cloud Drive শর্টকাট ──
cloudgo() {
  termux-wake-lock
  pkill -f fileserver.py 2>/dev/null
  nohup python -u ~/server/fileserver.py > ~/server/server.log 2>&1 &
  sleep 2
  echo "✅ Cloud Drive চালু! লিংক দেখতে লিখো: cloudlog"
}
cloudstop() {
  pkill -f fileserver.py 2>/dev/null
  termux-wake-unlock
  echo "⛔ সার্ভার বন্ধ।"
}
cloudlog() { tail -n 15 ~/server/server.log; }
EOF
কমান্ডকাজ কী
cloudgoক্লাউড ড্রাইভ ব্যাকগ্রাউন্ডে চালু (আগের চালু থাকলে রিস্টার্ট)
cloudstopসার্ভার বন্ধ ও ব্যাটারি লক ছাড়ো
cloudlogসার্ভারের লগ ও লিংক দেখো
Termux — একবারে পেস্ট করো
cat >> ~/.bashrc << 'EOF'

# ── Website শর্টকাট ──
webgo() {
  termux-wake-lock
  pkill -f webserver.py 2>/dev/null
  nohup python -u ~/webserver.py > ~/web.log 2>&1 &
  sleep 2
  echo "🌐 Website চালু! লিংক দেখতে লিখো: weblog"
}
webstop() {
  pkill -f webserver.py 2>/dev/null
  termux-wake-unlock
  echo "⛔ সার্ভার বন্ধ।"
}
weblog() { tail -n 15 ~/web.log; }
EOF
কমান্ডকাজ কী
webgoওয়েবসাইট ব্যাকগ্রাউন্ডে চালু (আগের চালু থাকলে রিস্টার্ট)
webstopসার্ভার বন্ধ ও ব্যাটারি লক ছাড়ো
weblogসার্ভারের লগ ও লিংক দেখো

এবার শর্টকাটগুলো সক্রিয় করো:

Termux
source ~/.bashrc
💡
এরপর Termux বন্ধ করে আবার খুললেও শর্টকাট থাকবে। cat >> কমান্ড দুইবার চালালে একই লাইন দুইবার যোগ হয় — ক্ষতি নেই, তবে দরকারও নেই। চালু অবস্থায় নোটিফিকেশনে "wake lock held" দেখাবে — ফোন ঘুমালেও সার্ভার চলবে।
সবার জন্য
৮

একই WiFi / হটস্পটে অন্য ডিভাইস থেকে অ্যাক্সেস

সার্ভার চালু থাকলে একই WiFi-তে (অথবা তোমার ফোনের হটস্পটে) যুক্ত যেকোনো ডিভাইস থেকে দেখা যাবে। এর জন্য ফোনের IP দরকার। সার্ভার চালু হলে লগে লিংকটি লেখা থাকে:

Termux
cloudlog
Termux
weblog

"📶 একই WiFi-তে" লাইনের লিংকটি অন্য ডিভাইসের ব্রাউজারে খোলো:

অন্য ডিভাইসের ব্রাউজারে
http://192.168.1.105:8080

↑ উদাহরণ। তোমার লগে যে IP দেখাবে সেটা ব্যবহার করো।

⚠️
"আপনার-ফোনের-IP" দেখালে: ফোন কোনো নেটওয়ার্কে যুক্ত নেই। WiFi চালু করো, অথবা ফোনের Settings → WiFi → যুক্ত নেটওয়ার্কের বিস্তারিত থেকে IP দেখো। ফোন নিজে হটস্পট হলে সাধারণত IP হয় 192.168.43.1।
💡
এটি শুধু একই নেটওয়ার্কের ডিভাইসের জন্য। দূরের মানুষকে দেখাতে পরের ধাপের Cloudflare ব্যবহার করো।
সবার জন্য
৯

Cloudflare Tunnel — ইন্টারনেটে পাবলিক লিংক

পৃথিবীর যেকোনো জায়গা থেকে তোমার সার্ভারে ঢুকতে Cloudflare Tunnel ব্যবহার করো। এটি বিনামূল্যে এবং খুব সহজ। তোমার ফোনে পাবলিক IP বা Port Forwarding লাগবে না।

একটি নতুন Termux session খোলো (বাম দিক থেকে সোয়াইপ → New Session)। আগের session-এ সার্ভার চালু রাখো, নতুন session-এ এই কমান্ড চালাও:

নতুন Termux Session
cloudflared tunnel --protocol http2 --url http://127.0.0.1:8080

কিছুক্ষণ পর স্ক্রিনে এরকম একটি লিংক দেখাবে:

পাবলিক লিংক (উদাহরণ)
https://random-words-here.trycloudflare.com

এই লিংকটি যেকোনো মানুষকে দাও — সে ইন্টারনেট থেকে তোমার সার্ভার অ্যাক্সেস করতে পারবে। Mobile Data-তেও কাজ করে।

⚠️
সতর্কতা: এই ফ্রি লিংক প্রতিবার Cloudflare বন্ধ করে চালু করলে পরিবর্তন হয়। স্থায়ী লিংকের জন্য পরের ধাপ দেখো।
💡
Mobile Data-তে কাজ না করলে: কমান্ডে --protocol http2 অবশ্যই রাখো — কিছু অপারেটর UDP ব্লক করে।
সবার জন্য
১০

স্থায়ী কাস্টম ডোমেইন (ঐচ্ছিক)

যদি তুমি drive.তোমার-নাম.com এর মতো একটি স্থায়ী ঠিকানা চাও, তাহলে একটি ডোমেইন কিনে Cloudflare-এ যুক্ত করো এবং নিচের ধাপগুলো সম্পন্ন করো।

⚠️
আগে: ডোমেইনটি Cloudflare ড্যাশবোর্ডে (Add a site → Free plan) যোগ করে ডোমেইন-রেজিস্ট্রারে Cloudflare-এর দেওয়া দুটি nameserver বসাতে হবে। সক্রিয় হতে কয়েক মিনিট থেকে কয়েক ঘণ্টা লাগতে পারে।
A
Cloudflare-এ লগইন করো
Termux
cloudflared tunnel login

একটি লিংক দেখাবে — ব্রাউজারে খোলো → Cloudflare-এ লগইন করো → তোমার ডোমেইন সিলেক্ট করো → Authorize ক্লিক করো।

B
টানেল তৈরি করো
Termux
cloudflared tunnel create myserver

myserver যেকোনো নাম দিতে পারো। একটি UUID দেখাবে — এটা মনে না রাখলেও হবে।

C
DNS যুক্ত করো
Termux
cloudflared tunnel route dns myserver drive.yourdomain.com
⚠️
drive.yourdomain.com এর জায়গায় তোমার আসল ডোমেইন দাও।
D
টানেল চালু করো (নতুন session-এ)

নতুন session খুলে (বাম থেকে সোয়াইপ → New Session):

নতুন Session
cloudflared tunnel --protocol http2 run --url http://127.0.0.1:8080 myserver
✅
এখন https://drive.yourdomain.com লিখলে তোমার সার্ভার দেখাবে!
সবার জন্য
!

সমস্যা ও সমাধান

⌨️ Ctrl+O বা Ctrl+C কাজ করছে না

কীবোর্ডের ওপরের সারিতে CTRL একবার ট্যাপ করে তারপর অক্ষর চাপো। সারি না দেখালে Volume Up + Q চাপো।

❓ command not found: cloudgo / webgo

source ~/.bashrc চালাও, অথবা Termux বন্ধ করে আবার খোলো। তবুও না হলে ধাপ ৭-এর cat >> কমান্ডটি আবার চালাও।

📦 ModuleNotFoundError: No module named 'flask'

Flask ইনস্টল হয়নি: pip install flask

🔪 pkill: command not found

pkg install procps -y চালাও।

🗂️ TemplateNotFound: files.html

~/server/templates/files.html ফাইলটি আছে কিনা দেখো: ls ~/server/templates/। ফোল্ডারের নাম হুবহু templates হতে হবে।

🚧 Address already in use (পোর্ট ব্যস্ত)

আগের সার্ভার এখনো চলছে। ক্লাউডের জন্য cloudstop, ওয়েবসাইটের জন্য webstop চালাও। না হলে pkill -f python।

🔒 Permission denied: /sdcard/PublicCloud

termux-setup-storage চালিয়ে Allow দাও। তারপর সার্ভার আবার চালাও।

❌ Error 530 / "Origin Error" (Cloudflare লিংকে)

Cloudflare টানেল চলছে কিন্তু তোমার সার্ভার বন্ধ। cloudgo (বা webgo) দিয়ে সার্ভার চালু করো।

🔋 ব্যাকগ্রাউন্ডে সার্ভার বন্ধ হয়ে যাচ্ছে

Settings → Apps → Termux → Battery → Unrestricted সেট করো। Termux-কে recent apps থেকে সোয়াইপ করে বন্ধ করলে সার্ভারও বন্ধ হয়; আবার চালু করতে cloudgo/webgo লিখো।

📡 Mobile Data-তে Cloudflare কাজ করছে না

কমান্ডে --protocol http2 রাখো। কিছু অপারেটর UDP ব্লক করে।

🔄 পরিবর্তন দেখা যাচ্ছে না

ব্রাউজারের ক্যাশ পুরনো পেজ দেখাচ্ছে। পেজ রিফ্রেশ করো বা প্রাইভেট ট্যাবে খোলো।

📁 ফাইল কোথায় রাখবো?

ফাইল সার্ভার শুধু /sdcard/PublicCloud ফোল্ডার দেখায়। ফোনের File Manager → Internal Storage → PublicCloud-এ ফাইল রাখো, তারপর ব্রাউজার রিফ্রেশ করো।

📁 ওয়েবসাইটের ফাইল কোথায়?

সব ফাইল ~/mywebsite ফোল্ডারে থাকবে। ls ~/mywebsite দিয়ে দেখো। প্রথম পেজের নাম অবশ্যই index.html।

🔍 সার্ভার চলছে কিনা পরীক্ষা
Termux
curl -s http://localhost:8080 | head -3

কিছু HTML দেখালে সার্ভার চলছে। "Connection refused" মানে বন্ধ।