PHP संस्करण संस्थापित करना
PHP संस्करण साझा होस्टिंग पर ज्यों का त्यों रख दिया जाता है: न Composer, न पैकेज-प्रबंधक, न कोई सेवा जिसे चलाते रहना पड़े। एक फ़ोल्डर, एक विन्यास-फ़ाइल, एक निर्धारित कार्य। यह निर्देश ख़ाली फ़ोल्डर से लेकर उत्पादन में चलते प्रतिष्ठान तक जाता है, उन बातों सहित जिन्हें अधिकांश मार्गदर्शिकाएँ छोड़ देती हैं: अनुमतियाँ, TLS, निर्धारित कार्य, बैकअप और उन्नयन।
क्या चाहिए#
| तत्व | संस्करण | क्यों |
|---|---|---|
| PHP | 8.1 या नया | संघ-प्रकार, enum, readonly, never: कोड इनका उपयोग करता है। |
pdo_sqlite | — | पूरा डेटाबेस। इसके बिना कुछ नहीं चलता। |
mbstring | — | सोलह भाषाओं में स्ट्रिंग का सही व्यवहार। |
openssl | अनुशंसित | डेटाबेस में रहस्यों का गोपन (SMTP पासवर्ड, बाहरी भंडारण के टोकन)। |
curl | अनुशंसित | बाहर जाते वेबहुक और बैकअप को किसी तीसरे पक्ष के यहाँ रखना। |
intl | अनुशंसित | तिथियाँ Node संस्करण जैसी लिखी जाती हैं। इसके बिना महीनों के नाम शब्दकोशों से आते हैं। |
संस्थापन-सहायक यह सब जाँचता है और आपको आगे बढ़ने देने से पहले परदे पर दिखाता है: जो बाधक है वह संस्थापन रोक देता है, जो वैकल्पिक है वह बिना रोके सूचित किया जाता है।
composer से संस्थापित करने को कुछ नहीं है: IMAP पाठक, tar.gz
अभिलेख, PDF, CSV, QR कोड और HTTP क्लाइंट — सब उत्पाद के भीतर लिखे हैं। यही उसे ऐसी होस्टिंग
पर रखने देता है जहाँ आपके पास कमांड लाइन नहीं।
१. फ़ाइलें चढ़ाना#
PHP संस्करण का अभिलेख लीजिए, फिर उसे चढ़ाइए। फ़ोल्डर ऐसा दिखता है:
toutadmin/
├── app/ कोड (वेब सर्वर इसे कभी नहीं परोसता)
│ ├── Core/ कोर: मार्ग-निर्धारण, डेटाबेस, सत्र, सुरक्षा
│ ├── Modules/ व्यावसायिक: मानव संसाधन, वित्त, परियोजनाएँ, गुणवत्ता…
│ ├── Controllers/
│ ├── views/ साँचे
│ ├── locales/ सोलह शब्दकोश
│ └── schema.sql ढाँचा, Node संस्करण जैसा ही
├── public/ ← वेब-मूल यहीं इंगित करता है, और कहीं नहीं
│ ├── index.php अग्रिम नियंत्रक
│ ├── css/ js/
├── data/ डेटाबेस, तिजोरी, हस्ताक्षर-पत्र, प्राप्त दस्तावेज़, बैकअप
├── tools/ cron.php, check-keys.php
├── tests/
├── config.sample.php
└── VERSION
public/ पर इंगित करता है, फ़ोल्डर पर नहीं
यह इस पृष्ठ की सबसे महत्वपूर्ण बात है। यदि सर्वर पूरा फ़ोल्डर परोसे, तो
data/app.sqlite कोई भी उतार सकता है: पूरा डेटाबेस, पासवर्ड की छापों और तिजोरी
सहित। data/ फ़ोल्डर public/ के ऊपर जानबूझकर रखा गया है।
साझा होस्टिंग पर#
दो स्थितियाँ बनती हैं। यदि आपका होस्ट डोमेन का मूल चुनने दे (cPanel, Plesk, और «मूल फ़ोल्डर»
मोड वाली अधिकांश होस्टिंग), तो फ़ोल्डर www/ के बाहर रखिए और डोमेन को
toutadmin/public पर इंगित कीजिए।
यदि मूल थोपा हुआ हो — अक्सर www/ या public_html/ — तो उसमें
public/ की सामग्री रखिए और शेष उसके ऊपर, फिर
public/index.php के शीर्ष पर पथ सुधारिए:
www/ ← थोपा हुआ मूल
├── index.php
├── css/ js/
toutadmin/ ← शेष, वेब की पहुँच से बाहर
├── app/
├── data/
└── config.php
// www/index.php — जो पंक्ति समायोजित करनी है
require_once __DIR__ . '/../toutadmin/app/bootstrap.php';
अंतिम उपाय के रूप में, यदि आप मूल के ऊपर कुछ न रख सकें, तो data/ में दी गई
.htaccess फ़ाइल पहले ही पहुँच रोक देती है। यह कमरबंद है, समाधान नहीं: हमेशा मूल
के बाहर वाले फ़ोल्डर को वरीयता दीजिए।
२. विन्यास लिखना#
cp config.sample.php config.php
फिर config.php खोलिए:
<?php
return [
// SQLite डेटाबेस और डेटा-फ़ोल्डर: वेब-मूल के बाहर।
'db_path' => __DIR__ . '/data/app.sqlite',
'data_dir' => __DIR__ . '/data',
// इस प्रतिष्ठान की अपनी कुंजी। एक बार बनाइए:
// php -r "echo bin2hex(random_bytes(32));"
'session_secret' => '…',
// संस्थापन-टोकन: अगला चरण देखिए।
'install_token' => '',
// सार्वजनिक पता, ईमेल से भेजे गए लिंकों के लिए।
'base_url' => 'https://intranet.udaharan.in',
// केवल भरोसेमंद प्रॉक्सी के पीछे चालू कीजिए।
'trust_proxy' => false,
// सीमाएँ: प्रति पते, प्रति पंद्रह मिनट लॉगिन प्रयास;
// प्रति पते, प्रति मिनट अनुरोध।
'login_rate_limit' => 10,
'global_rate_limit' => 300,
// समाप्ति: निष्क्रियता, फिर निरपेक्ष अवधि जिसे कुछ नहीं बढ़ाता।
'session_idle_minutes' => 60,
'session_max_hours' => 12,
];
यह हस्ताक्षर-पत्र के हस्ताक्षरों पर मुहर लगाती है और डेटाबेस के रहस्यों को गोपित करती है।
इसे खोना हस्ताक्षरों को अमान्य कर देता है। यदि आप नमूने का मान छोड़ दें, तो उत्पाद स्वयं
data/.instance-key में एक बना लेता है (अनुमतियाँ 0600) — तब इस
फ़ाइल को भी बाकी के साथ सहेजना याद रखिए।
विन्यास कहीं और भी रखा जा सकता है: पर्यावरण चर TOUTADMIN_CONFIG किसी दूसरी फ़ाइल
को इंगित करता है।
३. संस्थापन-टोकन रखना#
फ़ाइलें चढ़ाने और सहायक तक आपके पहुँचने के बीच प्रतिष्ठान जिसे मिल जाए उसका होता है: जो पहले आया, वही प्रशासन-खाता बना लेता है। खिड़की छोटी है, पर काफ़ी है। इसलिए प्रकाशित करने से पहले कोई यादृच्छिक मान रख दीजिए:
php -r "echo bin2hex(random_bytes(16));"
# फिर config.php में:
'install_token' => 'c3f1…',
सहायक इसे माँगता है, स्थिर समय में मिलाता है — साधारण तुलना टोकन को अक्षर-दर-अक्षर ताड़ लेने देती — और हर अस्वीकृति को पंजी में लिखता है। टोकन के बिना कुछ नहीं बनता। प्रतिष्ठान बन जाने पर सहायक स्वयं बंद हो जाता है: टोकन रहने दीजिए, अब उसका कोई काम नहीं।
४. अनुमतियाँ#
| पथ | अधिकार | कौन लिखता है |
|---|---|---|
data/ | 0770 | वेब सर्वर, और केवल वही |
data/app.sqlite | 0660 | संस्थापन द्वारा बनाया जाता है |
config.php | 0640 | कोई नहीं — सर्वर के लिए केवल पठन |
app/, public/ | 0755 | कोई नहीं — केवल पठन |
# ऐसे सर्वर पर उदाहरण जहाँ PHP www-data के रूप में चलता है
sudo chown -R aap:www-data /var/www/toutadmin
sudo find /var/www/toutadmin -type d -exec chmod 750 {} \;
sudo find /var/www/toutadmin -type f -exec chmod 640 {} \;
sudo chmod 770 /var/www/toutadmin/data
sudo chmod 750 /var/www/toutadmin/public
SQLite पड़ोसी फ़ाइलें भी लिखता है (-wal, -shm): लेख्य
फ़ोल्डर होना चाहिए, केवल डेटाबेस नहीं।
५. वेब सर्वर#
Nginx#
server {
listen 443 ssl http2;
server_name intranet.udaharan.in;
root /var/www/toutadmin/public; # और कुछ नहीं
index index.php;
ssl_certificate /etc/letsencrypt/live/intranet.udaharan.in/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/intranet.udaharan.in/privkey.pem;
client_max_body_size 20M; # तिजोरी में जमा, प्राप्त दस्तावेज़
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# चढ़ाई गई फ़ाइलें कभी सीधे नहीं परोसी जातीं: वे एक ऐसे मार्ग से
# जाती हैं जो सत्र और छाप जाँचता है।
location ~ ^/(data|app|tools|tests)/ { deny all; }
}
server {
listen 80;
server_name intranet.udaharan.in;
return 301 https://$host$request_uri;
}
Apache#
<VirtualHost *:443>
ServerName intranet.udaharan.in
DocumentRoot /var/www/toutadmin/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/intranet.udaharan.in/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/intranet.udaharan.in/privkey.pem
<Directory /var/www/toutadmin/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
साथ दी गई public/.htaccess फ़ाइल पहले ही सारे पते index.php पर भेज
देती है। Apache वाली साझा होस्टिंग पर इतना ही चाहिए।
TLS#
संपर्क गोपित होते ही उत्पाद Strict-Transport-Security शीर्षक लगा देता है, और खुले
में कभी नहीं: बिना गोपन वाले पृष्ठ से घोषित होने पर वह पढ़ा ही न जाता, और किसी स्थानीय परख को
छह महीने के लिए https में बंद कर देता। अपने चलाए सर्वर पर:
sudo certbot --nginx -d intranet.udaharan.in
जहाँ कोई प्रॉक्सी या भार-वितरक TLS समाप्त करता हो, वहाँ
'trust_proxy' => true कीजिए — और केवल वहीं: अन्यथा कोई भी शीर्षक में अपनी
पसंद का IP पता और प्रोटोकॉल घोषित कर सकता है।
६. निर्धारित कार्य#
PHP साइट केवल अनुरोध के समय चलती है। Node संस्करण अपने घंटे-घंटे के फेरे में जो आठ काम करता है, वे यहाँ होस्टिंग के cron से होते हैं:
* * * * * /usr/bin/php /var/www/toutadmin/tools/cron.php >> /var/log/toutadmin-cron.log 2>&1
| कार्य क्या करता है | किस लय में |
|---|---|
| जिनका अनुबंध पूरा हो चुका, उन खातों को बंद करता है | हर फेरे पर |
| जिन सदस्यताओं की तिथि आ गई, उनके बीजक जारी करता है | हर फेरे पर, कभी दो बार नहीं |
| समय-सीमाओं को सूचनाओं में बदलता है | हर फेरे पर, दोहराव हटाकर |
| पढ़ी हुई सूचनाएँ और लेखा-पंजी साफ़ करता है | चुनी हुई संरक्षण-अवधि के अनुसार |
| लेखा-डाकपेटी (IMAP) से संदेश उठाता है | यदि उठाना विन्यस्त हो |
| वेबहुक की कतार, पुनःप्रयासों सहित, ख़ाली करता है | हर फेरे पर |
| स्वचालित बैकअप बनाता है और बाहर भेजता है | जब निर्धारित अंतराल बीत चुका हो |
निर्धारित अंतराल से अधिक बार स्क्रिप्ट पुकारने से बैकअप अधिक बार नहीं बनते: समय से पहले कुछ
नहीं चलता। जिस होस्टिंग पर cron पंद्रह मिनट में एक बार तक सीमित हो, वहाँ
* * * * * की जगह */15 * * * * रखिए — वेबहुक बस उतनी देरी से जाएँगे।
कुछ शुरुआती पैकेज इसे नहीं देते। किसी बाहरी सेवा से HTTP पुकार (उपलब्धता-प्रहरी आदि) काफ़ी
नहीं: cron.php कमांड लाइन के बाहर चलने से इनकार करता है, ठीक इसीलिए कि कोई
सार्वजनिक पता बैकअप न चला सके। ऐसी स्थिति में बैकअप बैकअप परदे से हाथ से चलाया
जाता है।
७. सहायक#
अपना डोमेन खोलिए। जब तक कोई खाता नहीं, हर पता /installation पर भेज देता है।
सहायक एक पृष्ठ में समाता है:
- पूर्वापेक्षाएँ, जाँची और दिखाई गईं — जो बाधक है वह वैसा ही चिह्नित है।
- संस्थापन-टोकन, यदि विन्यस्त हो।
- कंपनी: हर जगह दिखने वाला नाम, और हर नए ग़ैर-फ़्रीलांस कर्मचारी को मिलने वाले वार्षिक अवकाश के दिन।
- प्रतिष्ठान की पूर्वनिर्धारित भाषा, 16 में से।
- प्रशासन-खाता: पता और कम-से-कम बारह अक्षरों का पासवर्ड।
सब कुछ एक ही लेन-देन में लिखा जाता है। जैसे ही कोई खाता बनता है,
/installation लॉगिन पृष्ठ पर भेजने लगता है: सहायक स्वयं बंद हो चुका है, हाथ से
हटाने को कोई फ़ाइल नहीं।
८. जाँचना कि सब चलता है#
# परीक्षण, मशीन पर (ये आपके डेटाबेस में नहीं लिखते)
php tests/run.php
# अनुवाद: कोई परदा ऐसी कुंजी नहीं वापरता जो शब्दकोशों में न हो
php tools/check-keys.php
फिर अंतरफलक में: एक सदस्य बनाइए, उससे लॉग इन कीजिए, एक संलग्नक चढ़ाइए, हाथ से बैकअप चलाइए और बैकअप परदे से उसे जाँचिए। ये चार काम डेटाबेस, फ़ाइलों, अधिकारों और अभिलेख को छूते हैं — यानी वह सब जो होस्टिंग को आना चाहिए।
९. उन्नयन#
# १. पहले बैकअप, हमेशा
php tools/cron.php # या बैकअप परदा
# २. कोड बदलिए, डेटा नहीं
# app/ public/ tools/ tests/ VERSION ← बदले जाते हैं
# data/ config.php ← ज्यों के त्यों रहते हैं
# ३. डेटाबेस पहले अनुरोध पर स्वयं अद्यतन हो जाता है
ढाँचा समघाती प्रवासों से बदलता है: उन्नयन दोहराने से कुछ नहीं टूटता। Node संस्करण का प्रतिष्ठान और PHP संस्करण का प्रतिष्ठान एक ही ढाँचा बाँटते हैं — 142 तालिकाएँ, 1311 स्तंभ — और एक ही पासवर्ड: डेटाबेस एक से दूसरे में बिना रूपांतरण चला जाता है।
१०. सचमुच बैकअप लेना#
tar.gz अभिलेख डेटाबेस (VACUUM INTO से नक़ल, इसलिए लेखन के बीच भी
संगत) और पाँच फ़ाइल-फ़ोल्डर ले जाता है: प्रोफ़ाइल चित्र, प्राप्त बायोडेटा, तिजोरी,
हस्ताक्षर-पत्र, प्राप्त दस्तावेज़। उसमें हर फ़ाइल अपनी SHA-256 छाप लिए चलती है, जो पुनर्स्थापन
पर जाँची जाती है।
जिस सर्वर की रक्षा करता है उसी पर पड़ा अभिलेख किसी की रक्षा नहीं करता: बैकअप परदे से दूरस्थ गंतव्य (FTPS या Google Drive) सेट कीजिए। ब्योरा बैकअप और पुनर्स्थापन पृष्ठ पर है।
पहले स्थानीय रूप से आज़माइए#
cp config.sample.php config.php
php -S localhost:8000 -t public public/index.php
उत्पाद से परिचय के लिए PHP का अंतर्निहित सर्वर काफ़ी है। उत्पादन के लिए वह उपयुक्त नहीं: एक ही प्रक्रिया, TLS नहीं, भार की कोई सीमा नहीं।
Toutadmin प्रलेखन — 2026-09-13 को बनाया गया। स्वतंत्र साइट, सॉफ़्टवेयर से अलग।