ردیاب بودجهٔ خودمیزبان: متنباز با Docker و Postgres
یک ردیاب متنباز هزینه و بودجه را با Docker و Postgres روی سیستم خود اجرا کنید و با پشتیبانگیری، مرزهای حریم خصوصی و زمان مناسب استفاده از سرویس میزبانیشده آشنا شوید.
پیکربندی فعلی Docker Compose تا وقتی حالت احراز هویت را مشخص نکنید، اجرا نمیشود. برای نصب محلی و بدون ورود باید فرمان را بهصورت صریح اجرا کنید:
AUTH_MODE=none make up
همین نکتهٔ کوچک، واقعیت مهمی را دربارهٔ خودمیزبانی نرمافزار مدیریت مالی شخصی نشان میدهد. اجرای کانتینرها آسان است؛ کار اصلی این است که مشخص کنید چه کسانی به آنها دسترسی دارند، نسخههای پشتیبان کجا نگهداری میشوند و کدام سرویسهای اختیاری میتوانند دادههای مالی را دریافت کنند.
Expense Budget Tracker ردیاب بودجهای متنباز با مجوز MIT است که با Next.js و Postgres ساخته شده است. این راهنما بر اساس وضعیت کنونی مخزن نوشته شده: راهاندازی محلی با Docker برای یک کاربر فنی، مسیر مستند استقرار در محیط تولید با AWS/CDK و نقاط پایانی مدیریتشده و مجزا برای رابط کاربری میزبانیشده، MCP و Agent API.

اول مرزی را انتخاب کنید که واقعاً میخواهید
«خودمیزبان» ممکن است به چند نوع راهاندازی کاملاً متفاوت اشاره کند؛ نباید آنها را معادل یکدیگر دانست.
| روش راهاندازی | محل نگهداری دادههای مالی | مسئولیتهای شما | مناسب برای |
|---|---|---|---|
| Docker Compose محلی | Postgres در یک والیوم Docker روی دستگاه شما | کانتینرها، بهروزرسانیها، دسترسی محلی و پشتیبانگیری | یک کاربر فنی که عمدتاً رابط وب را روی یک دستگاه میخواهد |
| حساب AWS خودتان با پشتهٔ مستندشدهٔ CDK | RDS و سرویسهای برنامه در حساب AWS شما | AWS، Cloudflare، دامنهها، گواهیها، ارسال ایمیل، اطلاعات محرمانه، پایش و پشتیبانگیری | استقرار عمومی یا چندکاربرهای که مسئولیت کار زیرساختی آن را میپذیرید |
| برنامهٔ وب مدیریتشده | محیط میزبانیشدهٔ Expense Budget Tracker | حساب کاربری و روند ورود دادهها | کسی که رابط کاربری را بدون مدیریت سرورها میخواهد |
| اتصالدهندهٔ MCP میزبانیشده | فضای کاری میزبانیشده که از طریق سرویس MCP به آن دسترسی دارید | اعطای مجوز OAuth و اتصال کلاینت | عامل سازگار با MCP که به دسترسی خواندن یا نوشتن با دامنهٔ مشخص نیاز دارد |
| Agent API میزبانیشده | فضای کاری میزبانیشده که از طریق سرویس API به آن دسترسی دارید | یک ApiKey بلندمدت، انتخاب فضای کاری و SQL بازبینیشده | اسکریپتها و عاملهای ترمینالی که میتوانند مستقیماً درخواست HTTP بفرستند |
فرمان محلی Compose، api.your-domain.com یا mcp.your-domain.com را ایجاد نمیکند. این رابطهای دسترسی ماشینی متعلق به معماری AWS و سرویس مدیریتشدهاند. اتصال یک کلاینت میزبانیشده به https://mcp.expense-budget-tracker.com/mcp یعنی استفاده از فضای کاری میزبانیشده، نه دسترسی به کانتینر Postgres روی لپتاپ شما.
نخستین پرسش دربارهٔ هر ردیاب بودجهٔ خودمیزبان از همین تمایز میآید: کنترل محلی برنامهٔ وب و پایگاه داده را میخواهید، یا یکپارچهسازیهای راه دوری را که به استقرار گستردهتری نیاز دارند؟
ردیاب هزینهٔ مبتنی بر Docker را محلی اجرا کنید
به Git، Docker و Docker Compose نیاز دارید. مخزن را کلون کنید و پشته را از ریشهٔ آن بالا بیاورید:
git clone https://github.com/kirill-markin/expense-budget-tracker.git
cd expense-budget-tracker
AUTH_MODE=none make up
سپس http://localhost:3000 را باز کنید.
AUTH_MODE یکی از متغیرهای الزامی Compose است. اگر .env.example را در .env کپی نکردهاید، باید این پیشوند را در هر فرمان Compose تکرار کنید. فرمانهای زیر عمداً همین کار را انجام میدهند.
make up میانبری برای این فرمان است:
AUTH_MODE=none docker compose -f infra/docker/compose.yml up -d
فایل فعلی Compose شامل Postgres 18، سرویس یکبارهٔ اجرای مهاجرتها، برنامهٔ وب Next.js، سرویس احراز هویت و پردازشگر نرخ ارز است. با AUTH_MODE=none، برنامهٔ وب بهجای الزام به ورود با Cognito از هویت محلی استفاده میکند. این حالت را دسترسی مخصوص توسعهٔ محلی بدانید، نه سازوکار احراز هویت یک سرور عمومی.
با فرمانهای معمول Compose میتوانید وضعیت کانتینرها را ببینید و لاگهای برنامه را دنبال کنید:
AUTH_MODE=none docker compose -f infra/docker/compose.yml ps
AUTH_MODE=none docker compose -f infra/docker/compose.yml logs -f web
پشته را با این فرمان متوقف کنید:
AUTH_MODE=none make down
Makefile این فرمان را به docker compose down بدون -v نگاشت میکند. دادههای Postgres در والیوم نامگذاریشدهٔ pgdata باقی میمانند و دفعهٔ بعد که پشته را بالا میآورید، دوباره استفاده میشوند.
این ماندگاری مفید است، اما جای نسخهٔ پشتیبان را نمیگیرد. خرابی میزبان، آسیب دیسک، حذف تصادفی والیوم یا اجرای صریح docker compose down -v همچنان میتواند تنها نسخهٔ موجود را از بین ببرد.
این راهاندازی را محلی نگه دارید
پیکربندی Compose برنامهٔ وب را روی پورت 3000 میزبان، Postgres را روی 5432 و سرویس احراز هویت را روی 8081 در دسترس قرار میدهد. این پیکربندی اعتبارنامههای پایگاه دادهٔ محیط توسعه را نیز در خود دارد. آن را روی میزبانی متصل به اینترنت اجرا نکنید و فرض نکنید که Docker آن را خصوصی نگه میدارد.
برای نصب روی یک رایانهٔ کاری:
- با فایروال دستگاه دسترسی شبکه را محدود کنید؛
- پورتهای
3000،5432یا8081را از روتر خود فوروارد نکنید؛ AUTH_MODE=noneرا از طریق پراکسی معکوس عمومی در دسترس قرار ندهید؛- مخزن، فایلهای
.envو دامپهای پایگاه داده را در پوشههای عمومی یا پوشههایی با دسترسی گسترده نگه ندارید.
مخزن، AWS/CDK را بهعنوان روش استقرار در محیط تولید مستند کرده است. برای هر VPS، NAS، کلاستر Kubernetes یا سرور خانگی، راهنمای ایمنسازیشدهای ارائه نشده است؛ هرچند یک مدیر سیستم باتجربه ممکن است بتواند کد را با آن محیط تطبیق دهد.
چه چیزهایی اجرا میشوند و چه چیزهایی در Postgres میمانند
معماری محلی آنقدر کوچک است که بتوان اجزایش را بررسی کرد:
- برنامهٔ وب Next.js: رابطهای بودجه، تراکنش، مانده، داشبورد، نسخهٔ نمایشی و چت را ارائه میکند.
- Postgres: دفتر کل، برنامههای بودجه، تنظیمات فضای کاری، فرادادهٔ حساب و وضعیت برنامه را ذخیره میکند.
- کانتینر مهاجرت: پیش از شروع سرویس وب، مهاجرتهای SQL مخزن را اعمال میکند.
- پردازشگر نرخ ارز: دادههای عمومی نرخ ارز را دریافت میکند و با استفاده از یک نقش محدود در پایگاه داده مینویسد.
- سرویس احراز هویت: از معماری استقرار دارای احراز هویت پشتیبانی میکند؛ وقتی
AUTH_MODE=noneباشد، استفادهٔ محلی از وب به Cognito نیاز ندارد.
Postgres مرجع اصلی دادههاست. به همین دلیل، این پروژه برای توسعهدهندگان یک برنامهٔ بودجهبندی کاربردی مبتنی بر Postgres است: میتوانید مهاجرتها را بررسی کنید، روابط جدولها را بشناسید، پایگاه دادهٔ خودتان را پرسوجو کنید و با ابزارهای استاندارد Postgres از آن خروجی بگیرید. امنیت در سطح سطر و نقشهای جداگانهٔ برنامه همچنان اهمیت دارند، اما جای امنیت میزبان یا نسخهٔ پشتیبان را نمیگیرند.
پردازشگر نرخ ارز برای دریافت نرخها درخواستهای خروجی میفرستد، اما برای دریافت این دادههای عمومی نیازی به ارسال سطرهای دفتر کل شما ندارد. قابلیتهای اختیاری هوش مصنوعی مرز متفاوتی دارند و باید جداگانه بررسی شوند.
پیش از آنکه دادهها را امن بدانید، نسخهٔ پشتیبان واقعی بسازید
برای پایگاه دادهٔ پیشفرض محلی Compose، این فرمان یک آرشیو فشردهٔ Postgres روی میزبان ایجاد میکند:
AUTH_MODE=none docker compose -f infra/docker/compose.yml exec -T postgres \
pg_dump -U tracker -d tracker --format=custom \
> expense-budget-tracker.dump
با این فایل مانند صورتحساب بانکی رفتار کنید؛ ممکن است شرح تراکنشها، ماندهها، دستهبندیها، یادداشتها و دیگر اطلاعات هویتی را در خود داشته باشد.
یک روال پشتیبانگیری قابلاتکا به چهار تصمیم نیاز دارد:
- تناوب: مشخص کنید از دستدادن چه مقدار از دادههای تازه برایتان قابلقبول است.
- مکان دوم: دامپ را در محلی جدا از میزبان Docker کپی کنید تا خرابی یک دیسک هر دو نسخه را از بین نبرد.
- رمزنگاری و دسترسی: آرشیو را هنگام ذخیرهسازی رمزگذاری کنید و دسترسی خواندن آن را محدود نگه دارید.
- آزمون بازیابی: هرچند وقت یک بار آن را در یک نمونهٔ سازگار و جداگانهٔ Postgres بازیابی کنید و تراکنشها، بودجهها و ماندهها را بررسی کنید.
پیش از بهروزرسانی برنامه، یک دامپ تازه بسازید. سپس کد جدید را دریافت کنید، ایمیجها را دوباره بسازید و پشته را از نو بالا بیاورید:
git pull
AUTH_MODE=none make build
AUTH_MODE=none make up
کانتینر مهاجرت هنگام راهاندازی اجرا میشود. پیش از ارتقا، تغییرات نسخه را بخوانید و دامپ پیش از ارتقا را تا وقتی نگه دارید که برنامه را بررسی کرده و یک دور بازیابی آزمایشی را با موفقیت انجام داده باشید.
خودمیزبانی خودبهخود همهٔ بایتها را محلی نگه نمیدارد
رابط محلی اصلی و پایگاه دادهٔ Postgres میتوانند روی دستگاه شما اجرا شوند. اما هرگاه قابلیت یا نقطهٔ پایانیای را انتخاب کنید که دادهها را به جای دیگری میفرستد، آن دادهها از این مرز خارج میشوند.
چت داخلی هوش مصنوعی
چت داخلی از OPENAI_API_KEY استفاده میکند. هنگام استفاده از آن، پرامپتها، محتوای پیوستشده یا استخراجشده و زمینهٔ مالی لازم برای فراخوانی مدل ممکن است به OpenAI ارسال شوند. مسیر فعلی درخواست، store: false را تنظیم میکند؛ بااینحال، ارائهدهنده همچنان باید درخواست را پردازش کند و سایر کنترلهای نگهداری داده به سازمان API شما بستگی دارند. پیش از فرستادن صورتحساب بانکی یا جزئیات دفتر کل، سیاستهای فعلی OpenAI برای دادههای API را بررسی کنید.
ردیابی Langfuse اختیاری است و فقط زمانی فعال میشود که مقادیر اتصال و نسخهٔ انتشار با هم پیکربندی شده باشند. در این حالت، دادههای ردیابی چت به LANGFUSE_BASE_URL انتخابی شما ارسال میشوند. نشانی Langfuse Cloud یک پردازشکنندهٔ خارجی دیگر به مرز اعتماد اضافه میکند؛ استقرار خودمیزبان Langfuse این مقصد را به زیرساختی منتقل میکند که خودتان اداره میکنید.
اگر الزام شما این است که «سطرهای مالی هرگز به ارائهدهندهٔ LLM ارسال نشوند»، یکپارچهسازی هوش مصنوعی را پیکربندی نکنید و از چت استفاده نکنید. خودمیزبانی پایگاه داده، درخواستی را که آگاهانه به یک مدل بیرونی میفرستید متوقف نمیکند.
استقرار AWS خودتان
استقرار مستندشدهٔ AWS، سرویسهای برنامه و RDS را در حساب AWS شما قرار میدهد. در عین حال، سامانهها و روابط اعتماد بیشتری نیز اضافه میکند: Cloudflare برای DNS و ترافیک لبه، Cognito برای احراز هویت، Resend برای ایمیل ورود، گواهیهای دامنههای عمومی، Secrets Manager، پایش و اتصالهای اختیاری OpenAI و Langfuse.
پشتهٔ CDK زیرساخت مدیریتشدهٔ پشتیبانگیری از پایگاه داده را در بر میگیرد. بااینحال، این شما هستید که باید دربارهٔ کافیبودن دورهٔ نگهداری تصمیم بگیرید، خرابیها را زیر نظر داشته باشید، بازیابی را آزمایش کنید، اطلاعات محرمانه را بهطور دورهای تغییر دهید، بهروزرسانیها را اعمال کنید و به رخدادها پاسخ دهید. «حساب AWS خودم» مرز کنترلی مفیدی است، اما به معنای «بدون شخص ثالث» نیست.
رابط مدیریتشده، MCP میزبانیشده و Agent API میزبانیشده
رابط مدیریتشده از app.expense-budget-tracker.com در دسترس است. این مسیر کمترین کار عملیاتی را میطلبد، اما گردانندهٔ سرویس و ارائهدهندگان میزبانی درون مرز دادههای شما قرار میگیرند. پیش از واردکردن دادههای مالی واقعی، سیاست حفظ حریم خصوصی را بخوانید.
کلاینتی با قابلیت MCP میتواند به این نشانی متصل شود:
https://mcp.expense-budget-tracker.com/mcp
اتصالدهندهٔ MCP میزبانیشده از OAuth مبتنی بر مرورگر استفاده میکند. محدودهٔ دسترسی الزامی expenses:read اجازهٔ کشف فضای کاری، بررسی شِمای پایگاه داده و اجرای پرسوجوهای خواندنی را میدهد. expenses:write محدودهای جداگانه است و برای sql_execute ضرورت دارد. مگر اینکه کلاینت واقعاً نیازمند ایجاد، تغییر یا حذف رکوردهای مالی باشد، با دسترسی فقطخواندنی شروع کنید. کلاینت MCP نیز میتواند دادههای خروجی ابزارها را دریافت کند؛ بنابراین سیاست حریم خصوصی خود آن هم اهمیت دارد. روند کامل را در راهنمای اتصالدهندهٔ MCP ببینید.
Agent API میزبانیشده، رابط و اعتبارنامهٔ متفاوتی دارد. از اینجا شروع کنید:
curl --fail --silent --show-error \
https://api.expense-budget-tracker.com/v1/
پس از آنکه فرایند راهاندازی با کد ایمیل یک کلید بلندعمر برگرداند، درخواستهای مستقیم از قالب زیر استفاده میکنند:
Authorization: ApiKey <key>
نقاط پایانی اصلی SQL عمداً یک عملیات خواندن را از یک عملیات نوشتن تأییدشده جدا میکنند:
POST /v1/sql/queryیکSELECTمحدودشده یاWITH ... SELECTرا میپذیرد.POST /v1/sql/executeیکINSERT،UPDATEیاDELETEتأییدشده را میپذیرد.
انتخاب فضای کاری و امنیت در سطح سطر Postgres روی سرور اعمال میشوند. این کنترلها درخواست میزبانیشده را به درخواست خودمیزبان تبدیل نمیکنند و ApiKey نیز در نقطهٔ پایانی MCP مبتنی بر OAuth پذیرفته نمیشود. مرجع API فرایند کشف، انتخاب فضای کاری، بررسی شِمای پایگاه داده، محدودیتهای درخواست و سیاست دقیق SQL را مستند میکند. راهنمای API ردیابی هزینه نیز فرایند تأیید و تطبیق را با جزئیات بیشتری توضیح میدهد.
با خودمیزبانی چه مسئولیتهایی را میپذیرید
مدیریت مالی شخصی برای توسعهدهندگان ممکن است از جنبهٔ برنامه بسیار ساده و دلپذیر به نظر برسد: یک مخزن، یک فرمان Compose و یک پایگاه داده. اما کار عملیاتی با بارگذاری موفق نخستین صفحه تمام نمیشود.
برای Docker محلی، این موارد با شماست:
- بهروزرسانی Docker و سیستمعامل میزبان؛
- بهروزرسانی برنامه و بازبینی مهاجرتها؛
- دامپهای پایگاه داده، نسخههای رمزگذاریشدهٔ خارج از دستگاه، سیاست نگهداری و آزمونهای بازیابی؛
- ظرفیت دیسک و سلامت کانتینرها؛
- قوانین فایروال و دسترسی فیزیکی به دستگاه؛
- محافظت از فایلهای
.env، کلیدهای API، کلیدهای مدل و نسخههای پشتیبان.
برای استقرار عمومی، این موارد هم اضافه میشوند:
- دامنه و پیکربندی DNS؛
- گواهیهای TLS و سازوکار تمدید آنها؛
- دسترسی همراه با احراز هویت بهجای
AUTH_MODE=none؛ - ارسال ایمیل OTP و اعتبارنامههای آن؛
- پایش پایگاه داده و سرویسها؛
- رسیدگی به هشدارها، واکنش به رخدادها و بازیابی؛
- هزینههای ابری و امنیت حساب ارائهدهنده.
راهنمای خودمیزبانی مرجع کوتاه راهاندازی است. برای معماری پشتیبانیشدهٔ AWS، مستندات استقرار در مخزن کد منبع اصلی محسوب میشود.
یک چکلیست عملی برای تصمیمگیری
ردیاب هزینهٔ خودمیزبان زمانی مناسب است که بیشتر موارد زیر دربارهٔ شما صدق کنند:
- با بر عهده گرفتن مدیریت Docker و Postgres راحت هستید، نه اینکه فقط یک بار از آنها استفاده کنید.
- پشتیبانگیری را خودکار میکنید و بازیابی را میآزمایید؛ صرفاً به والیوم اعتماد نمیکنید.
- به یک پایگاه دادهٔ استاندارد و کد منبعی دسترسی مستقیم میخواهید تا بتوانید آنها را بررسی یا تغییر دهید.
- دسترسی محلی از مرورگر برایتان کافی است یا آمادهاید پشتهٔ مستندشدهٔ AWS را اداره کنید.
- میتوانید
AUTH_MODE=noneرا از شبکههای عمومی دور نگه دارید. - همهٔ مسیرهای خروجی اختیاری، بهویژه چت هوش مصنوعی و تلهمتری را بررسی میکنید.
اگر موارد زیر توصیف دقیقتری از نیاز شماست، از برنامهٔ مدیریتشده یا گزینهٔ میزبانیشدهٔ دیگری استفاده کنید:
- میخواهید بدون نیاز به وصلهکردن زیرساخت، دادههای مالی را وارد و بررسی کنید.
- به دسترسی راه دور قابلاعتماد نیاز دارید، اما نمیخواهید دامنه، TLS، احراز هویت، ایمیل، اسرار و پایش را مدیریت کنید.
- بعید است متوجه ناموفقبودن پشتیبانگیری یا تأخیر در بهروزرسانی امنیتی شوید.
- MCP با محدودهٔ دسترسی OAuth یا Agent API میزبانیشده، نیاز شما به یکپارچهسازی را بدون ادارهٔ کل پشته برطرف میکند.
یک انتخاب میانهٔ مفید هم وجود دارد: سامانهٔ محلی را بدون هیچ کلید مربوط به هوش مصنوعی اجرا کنید، آن را از اینترنت عمومی دور نگه دارید و نسخههای پشتیبان رمزگذاریشدهٔ Postgres را به فضای ذخیرهسازی تحت کنترل خودتان منتقل کنید. به این ترتیب، از مزیت اصلی یک ردیاب بودجهٔ خودمیزبان بهرهمند میشوید، بیآنکه فایل Compose روی لپتاپ را پلتفرمی مناسب محیط تولید فرض کنید.
با AUTH_MODE=none make up شروع کنید، چند تراکنش آزمایشی غیرحساس وارد کنید، پشته را متوقف و دوباره راهاندازی کنید، سپس از پایگاه داده دامپ بگیرید و صحتش را بررسی کنید. اگر این چرخهٔ عملیاتی کوچک برایتان معقول است، دادههای واقعی را منتقل کنید. اگر همین چرخه از حالا کاری ملالآور به نظر میرسد، احتمالاً راهاندازی مدیریتشده انتخاب صادقانهتری است.