SSD Nodes Learn 🎉 VPS $4.99/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor

Self-hosted Calendly বিকল্প: Cal.com বনাম অন্যরা

Cal.com, Easy!Appointments, Rallly ও DayOtter-এর VPS তুলনা করুন। দুইটি সিদ্ধান্তমূলক বিষয় দেখুন: two-way calendar sync এবং নির্ভরযোগ্য outbound email পৌঁছায় কি না।

সংক্ষিপ্ত উত্তর

একটি self-hosted Calendly বিকল্পকে এমন একটি কাজ করতে হয়, যা আপনার VPS-এর অভ্যন্তরীণ tool কখনো করে না: জনসাধারণকে সাড়া দেওয়া। Booking page-ই মূল product। প্রথম দিন থেকেই এর একটি বাস্তব domain name এবং TLS (transport layer security) দরকার। এমন মানুষদের কাছেও mail পৌঁছাতে হবে, যারা আপনার server-এর নাম কখনো শোনেনি।

বাস্তবসম্মত বিকল্পের তালিকায় চারটি project আছে। Cal.com Calendly-এর সঙ্গে সবচেয়ে বেশি মেলে এবং একক consultant-এর জন্য এটি default choice। Easy!Appointments হালকা; এটি PHP ও MySQL-ভিত্তিক এবং 1 GB VPS-এ সহজে চলে। Rallly একটি group poll tool, তাই এতে কোনো booking page নেই। DayOtter সবচেয়ে নতুন project; এটি একটি AGPLv3 scheduling platform, যার সামনে confirm-first assistant রয়েছে।

কোনটি আপনি বাস্তবে চালাতে পারবেন, তা দুটি প্রশ্ন নির্ধারণ করে। আপনি যে calendar-এ ইতিমধ্যে কাজ করেন, তার সঙ্গে এটি কি উভয় দিকে sync করতে পারে? এবং এটি কি mail পাঠাতে পারে? দ্বিতীয় প্রশ্নটির কারণেই অধিকাংশ self-hosted booking setup নীরবে ব্যর্থ হয়। তাই এটি আগে আলোচনা করা হচ্ছে।

আউটবাউন্ড ইমেলই যে অংশটি ব্যর্থ হয়

একটি booking confirmation অপরিচিত কারও inbox-এ পৌঁছে যায়। এটি Gmail বা Microsoft 365-এ পৌঁছানো transactional mail, এবং ওই প্রাপক-সিস্টেমগুলো আপনার sending IP address ও DNS record দেখে আপনার mail গ্রহণের সিদ্ধান্ত নেয়।

VPS থেকে সরাসরি mail পাঠানো প্রায় কখনোই কাজ করে না। অধিকাংশ provider নতুন account-এ outbound TCP port 25 ব্লক করে, ফলে connection ঝুলে থাকে এবং পরে timeout হয়। port 25 খোলা থাকলেও নতুন VPS address-এর কোনো sending history থাকে না। বড় receiver-গুলো অজানা hosting-range address-কে সন্দেহজনক হিসেবে বিবেচনা করে। booking database-এ লেখা হয়, page-এ confirmed দেখায়, কিন্তু কেউ email পায় না। server-এর দিক থেকে কিছুই ভাঙা মনে হয় না। তাই সাধারণত কয়েক সপ্তাহ পরে এমন কোনো client-এর মাধ্যমে বিষয়টি ধরা পড়ে, যে booking করেও আসেনি।

একটি relay ব্যবহার করুন। যেকোনো transactional mail provider কাজ করবে। app-এর প্রয়োজন শুধু একটি hostname, একটি port, একটি user এবং একটি password। application config পরিবর্তনের আগে port-এ পৌঁছানো যাচ্ছে কি না পরীক্ষা করুন:

nc -vz -w 5 "$SMTP_HOST" 587

একটি succeeded line-এর অর্থ হলো পথটি খোলা। connection ঝুলে থাকলে বা Connection refused দেখা গেলে port-টি network level-এ ব্লক করা আছে। .env সম্পাদনা করে এটি ঠিক করা যাবে না। Relay-গুলো 587 বা 465-এ listen করে, কারণ 25 প্রায়ই ব্লক করা থাকে।

প্রতিটি project নিজস্ব পদ্ধতিতে relay ব্যবহার করে। Cal.com EMAIL_FROM, EMAIL_SERVER_HOST, EMAIL_SERVER_PORT, EMAIL_SERVER_USER এবং EMAIL_SERVER_PASSWORD পড়ে। এটি পরিবর্তে একটি RESEND_API_KEY-ও গ্রহণ করে। এই বিষয়টি খেয়াল করুন: shipped .env.example, EMAIL_SERVER_HOST-কে port 1025-এ থাকা localhost-এর দিকে নির্দেশ করে। এটি একটি local development mailbox। default অপরিবর্তিত রাখলে app কোনো error ছাড়াই এমন একটি mailbox-এ mail পাঠায়, যার অস্তিত্ব নেই। Rallly SMTP_HOST, SMTP_PORT, SMTP_USER এবং SMTP_PWD ব্যবহার করে। DayOtter SMTP settings অথবা একটি Resend key ব্যবহার করে। Easy!Appointments application থেকেই notification পাঠায়। তাই প্রকৃত booking গ্রহণের আগে তার settings page-এ একই relay সেট করুন।

এরপর relay থেকে পাওয়া DNS record publish করুন। SPF (sender policy framework) record জানায়, আপনার domain-এর হয়ে কোন server-গুলো mail পাঠাতে পারবে। DKIM (domainkeys identified mail) key প্রতিটি message sign করে, যাতে receiver যাচাই করতে পারে যে message পরিবর্তন করা হয়নি। দুটিই pass করার পরে DMARC (domain-based message authentication, reporting and conformance) policy যোগ করুন। বড় provider-এর কোনো বাস্তব address-এ একটি test booking পাঠান। message header খুলে নিশ্চিত করুন, authentication line-গুলোতে pass লেখা আছে। যে booking page mail পাঠাতে পারে না, সেটি booking page না থাকার চেয়েও খারাপ, কারণ এটি নীরবে ব্যর্থ হয়।

কোন calendar backend সত্যিই দুই দিকেই sync করে

Sync-এর দুটি দিক আছে এবং এগুলো আলাদাভাবে ব্যর্থ হয়। Read direction হলো availability: app-কে আপনার বিদ্যমান busy block দেখতে হবে, না হলে আপনি ইতিমধ্যে ব্যস্ত থাকা সময়েও এটি একটি slot দিয়ে দেবে। Write direction হলো booking: confirmed event-টি আপনার ব্যবহৃত calendar-এ দেখা যেতে হবে, শুধু booking tool-এর ভেতরে থাকলে চলবে না।

Google Calendar এবং Microsoft 365 উভয় দিকেই sync করে, তবে self-hosted install-এর ক্ষেত্রে একটি শর্ত আছে। আপনাকেই OAuth (open authorization) client তৈরি করতে হবে, কারণ hosted product-এর client ID source code-এ থাকে না। Cal.com-এর ক্ষেত্রে এটি হলো GOOGLE_API_CREDENTIALS in .env, যেখানে Google Cloud console থেকে download করা JSON সংরক্ষিত থাকে। DayOtter-ও একইভাবে Google এবং Microsoft OAuth credential ব্যবহার করে।

এখানে দুটি কারণে সমস্যা হয়। শুরু করার আগে দুটিই জানা দরকার। প্রথমত, আপনি যে redirect URI নিবন্ধন করবেন, সেটি scheme এবং শেষের path-সহ আপনার public URL-এর সঙ্গে হুবহু মিলতে হবে। অন্যথায় consent screen-এ Google redirect_uri_mismatch দিয়ে connection বন্ধ করে দেয়। দ্বিতীয়ত, Testing publishing status-এ থাকা Google project সাত দিন পর মেয়াদ শেষ হয় এমন refresh token দেয়। সারা সপ্তাহ sync কাজ করে, তারপর বন্ধ হয়ে যায় এবং পরবর্তী refresh-এর সময় app log-এ invalid_grant দেখা যায়। Consent screen-টি In production-এ পরিবর্তন করুন, অথবা প্রতি সোমবার হাতে reconnect করার বিষয়টি মেনে নিন।

CalDAV (calendaring extensions to WebDAV) হলো open option, তবে এর support সীমিত। Cal.com একটি CalDAV app সরবরাহ করে, যেটি এখনও beta হিসেবে চিহ্নিত এবং Baikal, Radicale, Nextcloud ও Kerio Connect-সহ একাধিক server-এ যাচাই করা হয়েছে। Apple iCloud একই app-এর মাধ্যমে কাজ করে, তবে আপনার Apple ID password-এর পরিবর্তে app-specific password প্রয়োজন। DayOtter Google এবং Microsoft 365-এর পাশে CalDAV-এর মাধ্যমে Apple-কে তালিকাভুক্ত করে।

ICS feed sync নয়। Subscribed .ics URL নকশাগতভাবেই read-only, তাই এটি আপনার booking page-এ সময়টি block করতে পারে, কিন্তু booking গ্রহণ করতে পারে না। কোনো tool আপনার calendar-এর জন্য শুধু ICS দিলে, আপনার sync ব্যবস্থার অর্ধেকই তৈরি হয়েছে এবং event এখনও হাতে কপি করতে হবে।

Easy!Appointments শুধু Google Calendar sync করে, অন্য কিছু নয়। Rallly availability পড়ে না: এটি সম্ভাব্য তারিখের একটি সেটে vote সংগ্রহ করে। “আমাদের ছয়জন কখন দেখা করতে পারি” প্রশ্নের জন্য এটি উপযুক্ত tool, কিন্তু “আমার সঙ্গে 30 মিনিটের meeting book করুন” প্রশ্নের জন্য উপযুক্ত নয়।

একটি booking page public, তাই TLS প্রথমেই প্রয়োজন

মানুষ যে self-host করে, তার বেশিরভাগই private। একটি wiki, board বা dashboard VPN কিংবা SSO login-এর আড়ালে রাখা যায় এবং open internet-এ কখনও প্রকাশ না করেও চালানো যায়। কিন্তু একটি booking link-এর ক্ষেত্রে তা সম্ভব নয়। যাকে আপনি link পাঠাবেন, তাকে এটি load করতে হবে। এতে setup-এ 3টি নির্দিষ্ট পরিবর্তন আসে।

কোনো কিছু install করার আগে আপনার একটি domain name প্রয়োজন, যার A record VPS-এর দিকে নির্দেশ করে। প্রথম দিন থেকেই একটি certificate প্রয়োজন, কারণ browser সাধারণ HTTP form-কে not secure হিসেবে চিহ্নিত করে এবং আপনার client সেখানে নিজের name ও email লিখবে। App-এর public URL-ও configuration-এ সঠিকভাবে সেট করতে হবে, কারণ এই value outgoing email-এর link এবং OAuth redirect URI-এর মধ্যে ব্যবহৃত হয়। Cal.com-এ NEXT_PUBLIC_WEBAPP_URL, Rallly-তে DOMAIN, Easy!Appointments-এ BASE_URL অথবা install করার সময় DAYOTTER_DOMAIN সেট করুন। সেখানে আপনি বাস্তবে যে https:// address ব্যবহার করবেন, সেটিই দিন।

Rallly এবং DayOtter আপনার জন্য TLS পরিচালনা করে। Rallly-এর bundled stack-এ Traefik অন্তর্ভুক্ত থাকে এবং ACME_EMAIL-এ দেওয়া address ব্যবহার করে Let's Encrypt certificate issue করে। DayOtter-এর installer automatic HTTPS-সহ Caddy চালু করে। Cal.com এবং Easy!Appointments তা করে না। তাই nginx সামনে রেখে আপনাকেই certificate issue করতে হবে, যেমন nginx-এ Certbot দিয়ে Let's Encrypt certificate নেওয়া হয়। App container-কে 127.0.0.1-এ bind করুন, যাতে প্রবেশের একমাত্র পথ আপনার নিয়ন্ত্রিত proxy হয়। একই box-এ যদি ইতিমধ্যে আপনার internal board-এর জন্য self-hosted Trello alternative চলে, সেটিকে বিদ্যমান auth-এর আড়ালে রাখুন এবং শুধু booking host-এর জন্য একটি public server block দিন।

আপনার VPS-এ Cal.com

Docker configuration আলাদা repository-তে থাকে এবং image-গুলো Docker Hub-এ আগে থেকেই তৈরি করা থাকে। তাই image pull করুন, build করবেন না।

git clone --recursive https://github.com/calcom/cal.diy.git
cd cal.diy
cp .env.example .env
openssl rand -base64 32
openssl rand -base64 24
docker compose pull
docker compose up -d

প্রথম random value-টি NEXTAUTH_SECRET-এ এবং দ্বিতীয়টি CALENDSO_ENCRYPTION_KEY-এ দিন। দুটিই প্রয়োজনীয়। DATABASE_URL সেট করুন এবং NEXT_PUBLIC_WEBAPP_URL-কে আপনার public address-এ নির্দেশ করুন। সংযুক্ত stack-এ web app, PostgreSQL এবং Prisma Studio রয়েছে। আলাদা কোথাও host করা database ব্যবহার করে শুধু app চালানোর জন্য docs-এ docker compose up -d calcom দেওয়া আছে। Installation স্থিতিশীল হলে আপনার সেটিই ব্যবহার করা উচিত।

VPS-এ image build করবেন না; image pull করুন। Source থেকে build করার সময় প্রকল্পের নিজস্ব নির্দেশনায় NODE_OPTIONS="--max-old-space-size=16384" export করতে বলা হয়েছে। এটি একাই Node-এর জন্য 16 GB heap নির্ধারণ করে। ARM hardware-এ image tag-এর শেষে -arm suffix যোগ করুন। Prebuilt image চালানোর জন্য প্রকল্পটি কোনো minimum resource requirement প্রকাশ করেনি। তাই app এবং PostgreSQL-এর জন্য 2 GB-কে documented requirement নয়, আমার ব্যবহারিক হিসাব হিসেবে ধরুন। প্রথম সপ্তাহে memory usage monitor করুন।

চালু হয়েছে কি না পরীক্ষা করুন:

docker compose ps
docker compose logs -f calcom
curl -sI https://cal.example.com | head -n 1

curl কমান্ডের output হিসেবে HTTP/2 200 পাওয়া উচিত। Container running দেখালেও nginx থেকে 502 Bad Gateway পাওয়া গেলে সাধারণত প্রথম boot-এ database migration প্রয়োগ করা হচ্ছে। ভেঙে গেছে ধরে নেওয়ার আগে কয়েক মিনিট অপেক্ষা করুন এবং logs পড়ুন। Cal.com-এর webhook প্রতিটি confirmed booking-এ চালু হয়। তাই একটি booking আপনার আগে থেকেই চালানো যেকোনো automation সক্রিয় করতে পারে, যেমন আপনার VPS-এ HTTPS-এর মাধ্যমে reachable একটি n8n instance

মূল codebase AGPLv3-এর অধীনে প্রকাশিত। কিছু feature আলাদা commercial licence-এর অধীনে enterprise directory-তে রাখা হয়েছে। Team feature ব্যবহার করে paid business process তৈরি করার আগে সেই licence পড়ুন।

1 GB-এর সার্ভারে Easy!Appointments

প্রয়োজনীয় সফটওয়্যার হলো Apache অথবা Nginx, PHP 8.2 বা নতুন সংস্করণ এবং MySQL। alextselegidis/easyappointments-এ একটি official image রয়েছে।

প্রথমে একটি সতর্কতা। repository-এর docker-compose.yml একটি development environment। এতে container-এর ভেতরে shell খুলে npm install && composer install && npm start চালানোর প্রত্যাশা করা হয়। এটি deployment-এর জন্য নয়। এর পরিবর্তে published image ব্যবহার করুন:

services:
  easyappointments:
    image: alextselegidis/easyappointments  # pin the current tag from Docker Hub
    environment:
      - BASE_URL=https://book.example.com
      - DB_HOST=mysql
      - DB_NAME=easyappointments
      - DB_USERNAME=easyapp
      - DB_PASSWORD=change-me
    ports:
      - '127.0.0.1:8080:80'
    depends_on:
      - mysql
  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=change-me-too
      - MYSQL_DATABASE=easyappointments
      - MYSQL_USER=easyapp
      - MYSQL_PASSWORD=change-me
    volumes:
      - ./mysql:/var/lib/mysql

BASE_URL অবশ্যই public HTTPS address হতে হবে। এটি ভুল হলে confirmation email-এর booking link এমন host-এ নির্দেশ করবে, যেটিতে আপনার client পৌঁছাতে পারবে না। imageটি নিজস্ব certificate ছাড়া port 80-এ plain HTTP পরিবেশন করে। তাই portটি 127.0.0.1-এ bind করা হয়েছে এবং সামনে থাকা nginx TLS termination করে। compose syntax আপনার কাছে নতুন হলে VPS-এ Docker Compose-এর প্রাথমিক ধারণা দিয়ে শুরু করে পরে এখানে ফিরে আসুন।

এটি এখানে থাকা বিকল্পগুলোর তুলনায় অনেক কম resource ব্যবহার করে। একটি PHP application এবং MySQL নিয়ে দুটি container 1 GB VPS-এ স্বচ্ছন্দে চলে। তবে এর সুবিধার বিনিময়ে কিছু সীমাবদ্ধতা আছে: একমাত্র calendar backend হলো Google Calendar, এবং আধুনিক booking flow-এর পরিবর্তে interface-টি প্রচলিত admin panel। আপনার calendar যদি Microsoft 365, Fastmail অথবা Nextcloud হয়, তাহলে শুরু করার আগেই এই বিকল্পটি বাদ দিতে হবে।

গ্রুপ পোলের জন্য Rallly

Rallly ভিন্ন একটি সমস্যার সমাধান করে। এটি আপনার availability প্রকাশ করে না। এটি একটি গ্রুপের সামনে সম্ভাব্য সময়ের একটি তালিকা দেয় এবং ভোট সংগ্রহ করে। Board meeting-এর জন্য এটিই উপযোগী, কিন্তু client booking link-এর ক্ষেত্রে এটি কার্যত অপ্রয়োজনীয়।

curl -fsSL https://get.rallly.co | bash

কোনো script shell-এ pipe করার আগে সেটি পড়ে নিন। bash-এর পরিবর্তে less বসিয়ে script-টি কী করে তা পড়ুন, তারপর চালান। Manual পদ্ধতিতে একই কাজ এমন ধাপে করা হয়, যেগুলো আপনি দেখতে পারবেন:

git clone https://github.com/lukevella/rallly-selfhosted.git
cd rallly-selfhosted
./rallly.sh setup
./rallly.sh start

নথিভুক্ত requirement অনুযায়ী কমপক্ষে 2 GB RAM, Compose v2-সহ Docker 19.03 বা পরবর্তী সংস্করণ, free port 80 ও 443, এবং server-এর দিকে নির্দেশ করা একটি domain প্রয়োজন। Bundled stack-এ HTTPS-এর জন্য Traefik, web application, PostgreSQL এবং S3-compatible object storage-এর জন্য Garage থাকে। DOMAIN, কমপক্ষে 32 characters-এর একটি SECRET_PASSWORD, SUPPORT_EMAIL এবং INITIAL_ADMIN_EMAIL সেট করুন। আপনি যদি আগে থেকেই reverse proxy চালান, তাহলে PROXY_MODE=external এবং WEB_PORT সেট করুন; Traefik তখন আর হস্তক্ষেপ করবে না। আপনি যদি আগে থেকেই MinIO-সহ self-hosted S3-compatible object store চালান, তাহলে S3_* variables-এ সেটির ঠিকানা দিন এবং Garage container বাদ দিন।

এখানে SMTP ঐচ্ছিক নয়, কারণ sign-in একটি magic link-এর মাধ্যমে হয়। কার্যকর relay না থাকলে কেউই log in করতে পারবে না, এমনকি আপনি সদ্য তৈরি করা admin account-ও নয়। Email ব্যর্থতার এটিই তুলনামূলকভাবে নিরাপদ পরিস্থিতি: এটি আপনাকে প্রবেশের সময় থামিয়ে দেয়, তিন সপ্তাহ পরে কোনো client-এর booking হারিয়ে যাওয়ার পর নয়।

সবচেয়ে নতুন সংযোজন, DayOtter

DayOtter হলো একটি AGPLv3 scheduling platform, যার সঙ্গে একটি assistant যুক্ত আছে। Production install করতে একটি command-ই যথেষ্ট:

curl -fsSL https://raw.githubusercontent.com/Dayotter/dayotter/main/deploy/install.sh \
  | sudo DAYOTTER_DOMAIN=cal.example.com bash

উপরের মতো, চালানোর আগে এটি পড়ে নিন। Installer Docker সেট আপ করে, secrets তৈরি করে এবং পুরো stack চালু করে: Next.js web app, reminders, calendar sync ও webhooks পরিচালনাকারী background worker, PostgreSQL, Redis এবং automatic HTTPS-সহ Caddy।

চারটির মধ্যে এটির calendar support সবচেয়ে বিস্তৃত। Google, Microsoft 365, CalDAV-এর মাধ্যমে Apple এবং ICS feeds সমর্থিত; তবে উপরের ICS caveat প্রযোজ্য। অন্য সব integration environment variables-এর মাধ্যমে opt-in, যার মধ্যে mail-এর জন্য SMTP বা Resend, assistant-এর জন্য ANTHROPIC_API_KEY, SMS-এর জন্য Twilio এবং payments-এর জন্য Stripe অন্তর্ভুক্ত। Assistant confirm-first পদ্ধতিতে কাজ করে: এটি প্রস্তাব দেয়, আপনি অনুমোদন করেন, এবং explicit yes না দিলে কিছুই আপনার calendar-এ যোগ হয় না। API key খালি রাখলে product-এর ওই অংশটি চালু হবে না।

Self-hosters-এর জন্য licensing পরিষ্কার। Core অংশ AGPLv3-এর অধীনে, এবং একটি ee/ directory-তে commercial cloud-only licence রয়েছে, যা DAYOTTER_CLOUD=1 সেট না করা পর্যন্ত নিষ্ক্রিয় থাকে। এর অর্থ হলো hosted plan-এ প্রতি seat প্রতি মাসে $9 বিল করা team features, August 2026 অনুযায়ী, আপনার নিজের সার্ভারে ব্যবহার করা যায়।

এখানকার stack-গুলোর মধ্যে এটিই সবচেয়ে ভারী, এবং project-টিও সবচেয়ে নতুন। আপনার বিদ্যমান booking link-এর পাশাপাশি এটি দুই সপ্তাহ চালান, উভয়টির মাধ্যমে বাস্তব booking নিন, এবং clients স্থানান্তরের আগে worker logs পড়ুন।

প্রতিটি stack-এর প্রকৃত খরচ

একটি stack ছোট VPS-এর ওপর কতটা চাপ ফেলবে, তার সৎ সূচক হলো container-এর সংখ্যা। কারণ প্রতিটি service-এর নিজস্ব ন্যূনতম memory প্রয়োজন। নিচের সংখ্যা প্রতিটি project-এর প্রকাশিত Docker stack থেকে নেওয়া হয়েছে এবং August 2026-এ যাচাই করা হয়েছে।

ChartServices in each project's documented Docker stack
The data behind this chart
[
  {
    "tool": "Easy!Appointments",
    "containers": 2,
    "database": "MySQL"
  },
  {
    "tool": "Cal.com",
    "containers": 3,
    "database": "PostgreSQL"
  },
  {
    "tool": "Rallly",
    "containers": 4,
    "database": "PostgreSQL"
  },
  {
    "tool": "DayOtter",
    "containers": 5,
    "database": "PostgreSQL and Redis"
  }
]

সহজ! Easy!Appointments-এর 2টি container প্রয়োজন এবং এটি 1 GB-এ চলে। Rallly-এর bundled stack-এ 4টি container রয়েছে, এবং এর documentation-এ 2 GB প্রয়োজন বলা হয়েছে। DayOtter-এর installer 5টি container চালু করে। তাই এখানে থাকা 4টি stack-এর মধ্যে এটির জন্য সবচেয়ে বড় server প্রয়োজন। Cal.com এবং DayOtter কোনো minimum memory figure প্রকাশ করে না। তাই supported number হিসেবে নয়, দুটির জন্যই আমি 2 GB-কে প্রাথমিক পছন্দ ধরছি।

আপনি যদি আগে থেকেই infrastructure চালান, তাহলে এই count-এর দুটি কমে যাবে। আপনি নিজের proxy এবং object storage ব্যবহার করলে Rallly-এর Traefik ও Garage container দুটিই বাদ যায়। Cal.com-এর Prisma Studio একটি development tool। এটি public server-এ চালু রাখা উচিত নয়।

কোন self-hosted Calendly বিকল্পটি বেছে নেওয়া উচিত

একজন একক পরামর্শকের Cal.com চালানো উচিত। এই তালিকায় এটিই একমাত্র প্রকল্প, যেখানে পরিচিত ধরনের booking page, এমন prebuilt image যা আপনার VPS-এ Node build করার প্রয়োজন দূর করে, এবং Google বা Microsoft-এ calendar না রাখলেও ব্যবহারযোগ্য একটি CalDAV ব্যবস্থা—এই তিনটি একসঙ্গে রয়েছে। একটি PostgreSQL database এবং একটি application container বহু বছর ধরে সামলানো যায় এমন maintenance load তৈরি করে। OAuth client এবং mail relay-এর জন্য একটি বিকেল সময় নির্ধারণ করুন। মনে রাখবেন, CalDAV app এখনও beta পর্যায়ে রয়েছে। তাই link প্রকাশের আগে একটি বাস্তব booking শুরু থেকে শেষ পর্যন্ত পরীক্ষা করুন।

একটি ছোট দলের DayOtter বিবেচনা করা উচিত। Weighted round robin এবং collective booking AGPLv3 core-এর অংশ। তাই self-hosting করলে hosted seat-এর জন্য যে feature-গুলোর অতিরিক্ত charge নেওয়া হয়, সেগুলো পাওয়া যায়। Worker process-টি team-এর বাস্তবে ব্যবহৃত reminders এবং webhooks সামলানোর জন্য তৈরি। এর বিনিময়ে maturity কম: এই তালিকায় এটিই নতুনতম প্রকল্প। তাই প্রথমে এটি parallelভাবে চালান এবং bookings-এর একটি পূর্ণ মাস monitor না করা পর্যন্ত পুরোনো link চালু রাখুন।

আরও দুটি নির্দিষ্ট পরিস্থিতি রয়েছে। শুধু দলের সবার উপযোগী একটি সময় খুঁজতে poll দরকার হলে Rallly install করে সেখানেই থামুন। আপনার 1 GB VPS থাকলে, আপনি Google Calendar ব্যবহার করলে এবং booking নেওয়ার জন্য সবচেয়ে ছোট সমাধান চাইলে, সেই server-এ চালাতে পারেন এমন আরও জটিল যেকোনো বিকল্পের চেয়ে Easy!Appointments বেশি দিন টিকে থাকবে। একই server-এ আর কী self-hosting করার মতো, সেই বিস্তৃত প্রশ্নের উত্তর জানতে 2026 সালে self-hosting করার মতো কী আছে দেখুন।

FAQ

আমি কি domain name ছাড়া self-hosted booking page চালাতে পারি?

না। এই অ্যাপগুলোর প্রতিটিই confirmation email-এর লিংকের মধ্যে public URL লিখে রাখে। Google এবং Microsoft উভয়ই একই মানের সঙ্গে OAuth redirect URI মিলিয়ে দেখে। তাই শুধু IP address ব্যবহার করলে consent screen-এ redirect_uri_mismatch দেখা যায়। Let's Encrypt IP address-এর জন্য certificate ইস্যু করে না। ফলে page-টি সাধারণ HTTP-তে লোড হয় এবং browser form-টিকে নিরাপদ নয় বলে চিহ্নিত করে। প্রথমে domain কিনুন। VPS-এর দিকে একটি A record নির্দেশ করুন। এরপর install করুন।

আমার booking confirmation email কখনও পৌঁছায় না কেন?

প্রায় সব ক্ষেত্রেই কারণ হলো server নিজেই mail deliver করার চেষ্টা করছে। অধিকাংশ VPS provider নতুন account-এ outbound port 25 block করে। তাই connection স্থগিত থাকে। Port খোলা থাকলেও নতুন address-এর কোনো sending reputation থাকে না। বড় mail receiver-গুলো সেটি প্রত্যাখ্যান করে। App-টিকে port 587-এ একটি transactional mail relay ব্যবহার করতে দিন। nc -vz -w 5 "$SMTP_HOST" 587 দিয়ে port-টি reachable কি না নিশ্চিত করুন। এরপর relay যে SPF এবং DKIM record দেয়, সেগুলো publish করুন। আপনি Cal.com চালালে নিশ্চিত করুন যে shipped EMAIL_SERVER_HOST=localhost এবং EMAIL_SERVER_PORT=1025 default পরিবর্তন করেছেন। এগুলো local development mailbox নির্দেশ করে।

Self-hosted Cal.com কি CalDAV-এর সঙ্গে sync করে, নাকি শুধু Google-এর সঙ্গে?

উভয়ের সঙ্গেই করে, তবে maturity আলাদা। CalDAV app-টিকে beta হিসেবে চিহ্নিত করা হয়েছে। এটি Baikal, Radicale, Nextcloud এবং Kerio Connect-সহ বিভিন্ন server-এর বিরুদ্ধে যাচাই করা হয়েছে। Apple iCloud-ও app-specific password ব্যবহার করে এর মাধ্যমে কাজ করে। Google Calendar এবং Microsoft 365 উভয় দিকেই sync করে। তবে self-hosted install-এ আপনাকে নিজের OAuth client তৈরি করতে হবে এবং GOOGLE_API_CREDENTIALS-এর মাধ্যমে তা দিতে হবে। Hosted service-এর credentials source-এ নেই।

এক সপ্তাহ পর আমার Google Calendar sync কাজ করা বন্ধ করে কেন?

কারণ Google Cloud project এখনও Testing publishing status-এ আছে। এই অবস্থার app-গুলোর জন্য Google এমন refresh token দেয়, যেগুলো সাত দিন পর expire হয়। তাই connection প্রথমে কাজ করে, এরপর পরবর্তী token refresh-এর সময় বন্ধ হয়ে যায়। Application log-এ invalid_grant দেখা যায়। OAuth consent screen-কে In production-এ সরান এবং একবার calendar reconnect করুন। Status পরিবর্তন না করে reconnect করলে আরও সাত দিন পাওয়া যাবে, এর বেশি নয়।

এগুলোর মধ্যে কোনটি 1 GB VPS-এ চলবে?

Easy!Appointments চলবে, কারণ এটি MySQL-সহ একটি PHP application। Rallly 2 GB minimum উল্লেখ করে এবং এর bundled stack চারটি service চালায়। Cal.com এবং DayOtter কোনো minimum প্রকাশ করে না। তবে PostgreSQL-সহ একটি Next.js application চালাতে হয়। DayOtter-এর ক্ষেত্রে Redis এবং একটি worker process-ও থাকে। তাই 2 GB বা তার বেশি memory পরিকল্পনা করা উচিত। ছোট server-এ কখনও source থেকে Cal.com build করবেন না। Project-এর নিজস্ব build instruction-এ 16 GB Node heap চাওয়া হয়েছে। এর পরিবর্তে prebuilt image ব্যবহার করুন।

#scheduling#calendly#cal-com#self-hosted#booking