<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: ASP.NET Core</title><link>https://academy.hsoub.com/programming/c-sharp/dotnet/aspnet/core/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: ASP.NET Core</description><language>ar</language><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x646;&#x634;&#x631; &#x62A;&#x637;&#x628;&#x64A;&#x642; Asp.net Core &#x645;&#x639; &#x62E;&#x627;&#x62F;&#x645; MySQL &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Nginx &#x639;&#x644;&#x649; &#x623;&#x648;&#x628;&#x646;&#x62A;&#x648; 18.04</title><link>https://academy.hsoub.com/programming/c-sharp/dotnet/aspnet/core/%D9%83%D9%8A%D9%81-%D8%AA%D9%86%D8%B4%D8%B1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-aspnet-core-%D9%85%D8%B9-%D8%AE%D8%A7%D8%AF%D9%85-mysql-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-nginx-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1804-r748/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_10/5d983ea1c303e_asp_net.jpg.83a7f4310396108506a1fa610a155e90.jpg" /></p>

<p>
	<a href="https://dotnet.microsoft.com/learn/aspnet/what-is-aspnet-core" rel="external nofollow">ASP.NET Core</a> هي إطار عمل مفتوح المصدر وعالي الأداء لإنشاء تطبيقات ويب حديثة، ومن المفترض أن يكون النسخة الأفضل من <a href="https://dotnet.microsoft.com/apps/aspnet" rel="external nofollow">إطار العمل ASP.NET لمايكروسوفت</a>. تمَّ إصداره عام 2016، ويمكن تشغيله على العديد من أنظمة التشغيل مثل لينكس وmacOS، مما يتيح للمطورين استهداف نظام تشغيل معين للتطوير اعتمادًا على متطلبات التصميم. يستطيع المطور باستخدام ASP.NET Core بناء أي نوع من تطبيقات الويب أو الخدمات بغض النظر عن التعقيد والحجم. يمكن للمطورين أيضًا استخدام <a href="https://docs.microsoft.com/en-us/aspnet/core/razor-pages/?view=aspnetcore-2.2&amp;tabs=visual-studio" rel="external nofollow">صفحات Razor</a> لإنشاء تصميم يركز على الصفحة يعمل أعلى النمط التقليدي <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" rel="external nofollow">MVC</a> (اختصارًا للعبارة Model-View-Controller).
</p>

<p>
	يوفر ASP.NET Core المرونة للتكامل مع أي إطار عمل للواجهة الأمامية للتعامل مع العمليات المنطقية من طرف العميل أو استخدام خدمة ويب. مثلًا، بإمكانك بناء واجهة برمجية RESTful مع ASP.NET Core واستخدامها ببساطة مع أطر عمل جافاسكربت مثل Angular، React و Vue.js.
</p>

<p>
	ستعدّ في هذا الدرس تطبيق ASP.NET Core وتنشره ليكون جاهزًا للإطلاق مع خادم MySQL على أوبنتو 18.04 باستخدام Nginx. ستنشر تطبيق ASP.NET Core تجريبي مماثل للتطبيق من توثيق مايكروسوفت والمُستضاف على <a href="https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/tutorials/razor-pages/razor-pages-start/2.2-stage-samples" rel="external nofollow">GitHub</a>. بمجرد أن يتم النشر، سيسمح لك التطبيق التجريبي بإنشاء قائمة أفلام وتخزينها في قاعدة البيانات. ستكون قادرًا على إنشاء، وقراءة، وتحديث، وحذف سجلات من قاعدة البيانات. يمكنك بدلًا من ذلك استخدام هذا الدرس لتنشر تطبيق ASP.NET Core خاص بك؛ من الممكن أن تحتاج إلى تنفيذ خطواتٍ إضافيةٍ تتضمن إنشاء ملف تهجير (migration) جديد إلى قاعدة البيانات الخاصة بك.
</p>

<p>
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="32043" href="https://academy.hsoub.com/uploads/monthly_2019_10/5d983ea400978_asp_net.jpg.8131baa5b85d797c14fb80f20dd70791.jpg" rel=""><img alt="كيف تنشر تطبيق asp.net.jpg" class="ipsImage ipsImage_thumbnailed" data-fileid="32043" data-unique="wfwyahwi9" src="https://academy.hsoub.com/uploads/monthly_2019_10/5d983ea41627f_asp_net.thumb.jpg.45c5865ab7efaa4a4b803cfd0b154d42.jpg"></a>
</p>

<h2>
	المتطلبات الأساسية
</h2>

<p>
	ستحتاج لما يلي لاتباع هذا الدرس:
</p>

<ul>
<li>
		خادم أوبنتو 18.04 تم ضبطه باستخدام <a href="https://academy.hsoub.com/devops/linux/%D8%A7%D9%84%D8%AA%D9%87%D9%8A%D8%A6%D8%A9-%D8%A7%D9%84%D8%A3%D9%88%D9%84%D9%8A%D8%A9-%D9%84%D8%AE%D8%A7%D8%AF%D9%85-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r431/" rel="">دليل التهيئة الأولية لخادم أوبنتو 18.04</a>، متضمنًا مستخدمًا عاديًا مع وصول <code>sudo</code> وجدار حماية.
	</li>
	<li>
		خادم Nginx مثبَّت باتباع الخطوات <a href="https://academy.hsoub.com/devops/servers/web/nginx/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-nginx-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r434/" rel="">كيفية تثبيت Nginx على أوبنتو 18.04</a>.
	</li>
	<li>
		خادم ويب Nginx آمن. بإمكانك اتباع درس <a href="https://academy.hsoub.com/devops/servers/web/nginx/%D9%83%D9%8A%D9%81-%D8%AA%D8%A4%D9%85%D9%91%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-%D9%88%D9%8A%D8%A8-nginx-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1604-r365/" rel="">كيف تؤمّن خادم Nginx بشهادة Let's Encrypt في أوبنتو</a> للقيام بذلك.
	</li>
	<li>
		ضبط سجلَّي الـ DNS لخادمك. يمكنك اتّباع هذه <a href="https://www.digitalocean.com/docs/networking/dns/" rel="external nofollow">المقدمة إلى DigitalOcean DNS</a> للتفاصيل حول كيفية إضافتها.
		<ul>
<li>
				سجل <code>A</code> مع إشارة اسم النطاق الخاص بك <code>your-domain</code> إلى عنوان IP العام للخادم.
			</li>
			<li>
				سجل <code>A</code> مع إشارة اسم النطاق الخاص بك مسبوقًا بـ www <code>www.your-domain</code>. إلى عنوان IP العام للخادم.
			</li>
		</ul>
</li>
	<li>
		نظام إدارة قواعد البيانات MySQL مثبَّت باتباع خطوات <a href="https://academy.hsoub.com/devops/servers/databases/mysql/%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-mysql-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%88%D9%86%D8%AA%D9%88-1804-r433/" rel="">كيف تثبّت الإصدار الأخير من MySQL على أوبنتو 18.0</a>.
	</li>
</ul>
<h2>
	الخطوة 1: تثبيت مُشِّغل NET Core. الآني
</h2>

<p>
	مُشِّغل NET Core. الآني (أي NET Core runtime.) مطلوب لتشغيل تطبيق NET Core.، لذا يجب البدء بتثبيته على جهازك. تحتاج أولًا لتسجيل مفتاح مايكروسوفت ومستودع المنتج. بعد ذلك ستثبّت الاعتماديات (dependencies) المطلوبة.
</p>

<p>
	أولًا، سجّل الدخول كمستخدم مُنشأ حديثًا، وتأكّد من أنَّك في المجلد الجذر:
</p>

<pre class="ipsCode">
$ cd ~
</pre>

<p>
	ثمّ نفّذ الأمر التالي لتسجيل مفتاح مايكروسوفت ومستودع المنتج:
</p>

<pre class="ipsCode">
$ wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
</pre>

<p>
	استخدم <code>dpkg</code> مع الراية <code>i-</code> لتثبيت الملف المحدد:
</p>

<pre class="ipsCode">
$ sudo dpkg -i packages-microsoft-prod.deb
</pre>

<p>
	لتسهيل تثبيت الحزم الأخرى الضرورية لتطبيقك، ستثبّت مستودع <code>universe</code> باستخدام الأمر التالي:
</p>

<pre class="ipsCode">
$ sudo add-apt-repository universe
</pre>

<p>
	ثمّ ثبّت حزمة <code>apt-transport</code> لتسمح باستخدام المستودعات التي يتم الوصول إليها عبر بروتوكول HTTP الآمن:
</p>

<pre class="ipsCode">
$ sudo apt install apt-transport-https
</pre>

<p>
	نفِّذ الأمر التالي لتنزيل قائمة الحزم من المستودعات وتحديثها للحصول على معلومات حول أحدث إصدارات الحزم واعتمادياتها:
</p>

<pre class="ipsCode">
$ sudo apt update
</pre>

<p>
	أخيرًا، يمكنك تثبيت SDK لمشغّل NET. الآني عبر الأمر:
</p>

<pre class="ipsCode">
$ sudo apt install dotnet-sdk-2.2
</pre>

<p>
	ستُعرض تفاصيل ما سيجري تنزيله ويُطلب تأكيد ذلك عبر الضغط على Y أي yes للمتابعة.
</p>

<p>
	لقد انتهيت الآن من تثبيت SDK لمشغّل NET Core. الآني على الخادم، وأنت جاهز تقريبًا لتنزيل التطبيق التجريبي من Github لضبط إعدادات النشر. لكن أولًا يجب إنشاء قاعدة بيانات التطبيق.
</p>

<h2>
	الخطوة 2: إنشاء مستخدم MySQL وقاعدة بيانات
</h2>

<p>
	ستنشئ في هذا الجزء مستخدم على خادم MySQL، وقاعدة بيانات للتطبيق، وتمنح جميع الصلاحيات الضرورية للمستخدم الجديد ليتصل بقاعدة البيانات من تطبيقك.
</p>

<p>
	تحتاج لتبدأ إلى الوصول لـMySQL العميل باستخدام حساب MySQL الجذر كما هو موضح هنا:
</p>

<pre class="ipsCode">
$ mysql -u root -p
</pre>

<p>
	سيُطلب منك إدخال كلمة سر الحساب الجذر الذي تمّ إعداده ضمن درس المتطلبات الأساسية.
</p>

<p>
	ثم أنشئ قاعدة بيانات MySQL للتطبيق باستخدام الأمر:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_770_6" style="">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE DATABASE </span><span class="typ">MovieAppDb</span><span class="pun">;</span></pre>

<p>
	ستشاهد الخرج التالي في سطر الأوامر:
</p>

<pre class="ipsCode">
Output
Query OK, 1 row affected (0.03 sec)
</pre>

<p>
	لقد أنشأت الآن قاعدة البيانات بنجاح، بعد ذلك ستُنشئ مستخدم MySQL جديد، وتربطه بقاعدة البيانات التي أُنشئت حديثًا، وتمنحه جميع الصلاحيات.
</p>

<p>
	نفّذ الأمر التالي لتُنشئ مستخدم MySQL وكلمة مرور. تذكّر أن تغيّر اسم المستخدم وكلمة المرور ليصبحوا أكثر أمانًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_770_8" style="">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> CREATE USER </span><span class="str">'movie-admin'</span><span class="pun">@</span><span class="str">'localhost'</span><span class="pln"> IDENTIFIED BY </span><span class="str">'password'</span><span class="pun">;</span><span class="pln"> </span></pre>

<p>
	ستشاهد الخرج التالي:
</p>

<pre class="ipsCode">
Output
Query OK, 0 rows affected (0.02 sec)
</pre>

<p>
	يحتاج مستخدم MySQL إلى الإذن المناسب للوصول إلى قاعدة بيانات أو تنفيذ إجراء محدد عليها، حاليًا لا يملك المستخدم <code>movie-admin</code> الإذن المناسب على قاعدة بيانات التطبيق.
</p>

<p>
	سنغيّر ذلك بتنفيذ الأمر التالي لمنح حق الوصول للمستخدم <code>movie-admin</code> إلى قاعدة البيانات <code>MovieAppDb</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_770_10" style="">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> GRANT ALL PRIVILEGES ON </span><span class="typ">MovieAppDb</span><span class="pun">.*</span><span class="pln"> TO </span><span class="str">'movie-admin'</span><span class="pun">@</span><span class="str">'localhost'</span><span class="pun">;</span></pre>

<p>
	ستشاهد الخرج التالي:
</p>

<pre class="ipsCode">
Output
Query OK, 0 rows affected (0.01 sec)
</pre>

<p>
	يمكنك الآن إعادة تحميل جداول الصلاحيات بتشغيل الأمر التالي لتطبيق التغييرات التي قمت بها باستخدام عبارة التدفق:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_770_16" style="">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> FLUSH PRIVILEGES</span><span class="pun">;</span></pre>

<p>
	ستشاهد الخرج التالي:
</p>

<pre class="ipsCode">
Output
Query OK, 0 rows affected (0.00 sec)
</pre>

<p>
	لقد أنشأت مستخدم جديد ومنحه الصلاحيات. لتختبر فيما إذا تمّ الأمر بشكلٍ صحيحٍ، أغلق MySQL العميل:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_770_18" style="">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> quit</span><span class="pun">;</span></pre>

<p>
	ثمّ سجّل الدخول مجددًا باستخدام بيانات الاعتماد لمستخدم MySQL الذي أنشأته وأدخل كلمة المرور المناسبة عندما تُطلب منك:
</p>

<pre class="ipsCode">
$ mysql -u movie-admin -p
</pre>

<p>
	للتأكد من أن المستخدم <code>movie-admin</code> يمكنه الوصول إلى قاعدة البيانات المُنشأة، تحقق باستخدام الأمر:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_770_20" style="">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> SHOW DATABASES</span><span class="pun">;</span></pre>

<p>
	الآن ستشاهد جدول <code>MovieAppDb</code> ضمن قائمة الخرج:
</p>

<pre class="ipsCode">
Output
+--------------------+
| Database           |
+--------------------+
| MovieAppDb         |
| information_schema |
+--------------------+
2 rows in set (0.01 sec)
</pre>

<p>
	الآن، أغلق MySQL العميل:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_770_22" style="">
<span class="pln">mysql</span><span class="pun">&gt;</span><span class="pln"> quit</span><span class="pun">;</span></pre>

<p>
	لقد أنشأت قاعدة بيانات، ومستخدم MySQL جديد للتطبيق التجريبي، ومنحت المستخدم الجديد الصلاحيات الصحيحة للوصول إلى قاعدة البيانات. في الجزء التالي، ستبدأ بضبط التطبيق التجريبي.
</p>

<h2>
	الخطوة 3: ضبط التطبيق التجريبي وبيانات اعتماد قاعدة البيانات
</h2>

<p>
	كما ذُكر سابقًا، ستنشر تطبيق ASP.NET Core موجود. تم بناء هذا التطبيق لإنشاء قائمة أفلام باستخدام نمط التصميم (Model-View-Controller) لضمان وجود الهيكل المناسب والفصل بين الاهتمامات. لإنشاء أو إضافة فيلم جديد إلى القائمة، سيملأ المستخدم حقول النموذج بالتفاصيل المناسبة ويضغط على زر إنشاء لإرسال التفاصيل إلى المتحكم (controller). عند ذلك يستقبل المتحكم طلب POST HTTP مع التفاصيل المرسلة وتبقى البيانات في قاعدة البيانات من خلال النموذج (model).
</p>

<p>
	ستستخدم <a href="https://academy.hsoub.com/programming/workflow/git/" rel="">Git</a> لسحب (pull) الشيفرة المصدرية لهذا التطبيق التجريبي من <a href="https://github.com/do-community/movie-app-list" rel="external nofollow">GitHub</a> وحفظه في مجلد جديد. يمكنك أيضًا تحميل تطبيق بديل إذا كنت ستنشر تطبيقًا مختلفًا.
</p>

<p>
	للبدء، أنشئ مجلدًا جديدًا باسم <code>movie-app</code> من الطرفية (terminal) باستخدام الأمر التالي:
</p>

<pre class="ipsCode">
$ sudo mkdir -p /var/www/movie-app
</pre>

<p>
	سيكون هذا المجلد بمثابة المجلد الجذر لتطبيقك. بعد ذلك، عدّل مالك ومجموعة المجلد للسماح لحساب المستخدم العادي بالعمل على ملفات المشروع:
</p>

<pre class="ipsCode">
$ sudo chown sammy:sammy /var/www/movie-app
</pre>

<p>
	استبدل <code>sammy</code> باسم المستخدم العادي الذي يملك صلاحيات sudo.
</p>

<p>
	يمكنك الآن الانتقال إلى المجلد الأب ونسخ (clone) التطبيق من Github:
</p>

<pre class="ipsCode">
$ cd /var/www
$ git clone https://github.com/do-community/movie-app-list.git movie-app
</pre>

<p>
	ستشاهد الخرج التالي:
</p>

<pre class="ipsCode">
Output
Cloning into 'movie-app'…
remote: Enumerating objects: 91, done.
remote: Counting objects: 100% (91/91), done.
remote: Compressing objects: 100% (73/73), done.
remote: Total 91 (delta 13), reused 91 (delta 13), pack-reused 0
Unpacking objects: 100% (91/91), done.
</pre>

<p>
	لقد نسخت التطبيق التجريبي بنجاح من GitHub، لذا ستكون الخطوة التالية هي إنشاء اتصال ناجح بقاعدة بيانات التطبيق. ستقوم بذلك عن طريق تعديل خاصية <code>ConnectionStrings</code> ضمن ملف <code>appsettings.json</code> وإضافة تفاصيل قاعدة البيانات.
</p>

<p>
	غيّر المجلد ضمن التطبيق:
</p>

<pre class="ipsCode">
$ cd movie-app
</pre>

<p>
	ثم افتح الملف للتعديل:
</p>

<pre class="ipsCode">
$ sudo nano appsettings.json
</pre>

<p>
	أضف بيانات اعتماد قاعدة البيانات في ملف appsettings.json:
</p>

<pre class="ipsCode prettyprint lang-javascript prettyprinted" id="ips_uid_770_24" style="">
<span class="pun">{</span><span class="pln">
  </span><span class="str">"Logging"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"LogLevel"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="str">"Default"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Warning"</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">},</span><span class="pln">
  </span><span class="str">"AllowedHosts"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"*"</span><span class="pun">,</span><span class="pln">
  </span><span class="str">"ConnectionStrings"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="str">"MovieContext"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"Server=localhost;User Id=movie-admin;Password=password;Database=MovieAppDb"</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	بوضع هذه البيانات بطريقةٍ صحيحة فقد أنشأت اتصالًا ناجحًا بقاعدة البيانات. الآن اضغط <code>CTRL+X</code> لحفظ تغييرات الملف واضغط <code>Y</code> للتأكيد. ثم اضغط <code>ENTER</code> لإغلاق الصفحة.
</p>

<p>
	تستخدم تطبيقات ASP.NET Core مكتبة NET. قياسية تسمّى <a href="https://docs.microsoft.com/en-us/ef/" rel="external nofollow">Entity Framework</a> (EF) Core لإدارة التفاعل مع قاعدة البيانات. <a href="https://docs.microsoft.com/en-us/ef/core/" rel="external nofollow">Entity Framework Core</a> هي إصدار خفيف عابر للمنصات (cross-platform) من التقنية الشائعة للوصول إلى بيانات Entity Framework. إنّها تقنية ربط الكائنات بالعلاقات (<a href="https://academy.hsoub.com/programming/python/flask/%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-%D9%82%D8%A7%D8%B9%D8%AF%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-postgresql-%D9%88%D8%A7%D9%84%D8%AA%D9%91%D8%B9%D8%B1%D9%8A%D9%81-%D8%A8%D9%85%D9%81%D9%87%D9%88%D9%85%D9%8A-orm-%D9%88%D8%A5%D8%B6%D8%A7%D9%81%D8%A7%D8%AA-flask-r506/" rel="">ORM</a>) التي تتيح لمطوري NET. العمل مع قاعدة البيانات باستخدام أي مزود قاعدة بيانات، مثل MySQL.
</p>

<p>
	يمكنك الآن تحديث قاعدة بياناتك مع الجداول من التطبيق التجريبي المنسوخ. نفّذ الأمر التالي لهذا الغرض:
</p>

<pre class="ipsCode">
$ dotnet ef database update
</pre>

<p>
	سيحدّث هذا الأمر قاعدة البيانات ويُنشئ المخططات المناسبة.
</p>

<p>
	الآن، لتبني المشروع وكلّ اعتمادياته، نفّذ الأمر التالي:
</p>

<pre class="ipsCode">
$ dotnet build
</pre>

<p>
	ستشاهد خرجًا مشابهًا للتالي:
</p>

<pre class="ipsCode">
Output
Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 95.09 ms for /var/www/movie-app/MvcMovie.csproj.
  MvcMovie -&gt; /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll
  MvcMovie -&gt; /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.91
</pre>

<p>
	سيؤدي هذا إلى بناء المشروع وتثبيت أيّة اعتماديات خارجية (third-party dependencies) مذكورة في ملف <code>project.assets.json</code>، ولكن لن يكون التطبيق جاهزًا للنشر بعد. نفّذ الأمر التالي ليصبح التطبيق جاهزًا للنشر:
</p>

<pre class="ipsCode">
$ dotnet publish
</pre>

<p>
	ستشاهد التالي:
</p>

<pre class="ipsCode">
Output
Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

Restore completed in 89.62 ms for /var/www/movie-app/MvcMovie.csproj.
MvcMovie -&gt; /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.dll
MvcMovie -&gt; /var/www/movie-app/bin/Debug/netcoreapp2.2/MvcMovie.Views.dll
MvcMovie -&gt; /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/
</pre>

<p>
	هذا سيُحزّم التطبيق ويترجمه، ويقرأ اعتمادياته، وينشر مجموعة الملفات الناتجة في مجلد للنشر، ويُنتج ملف dll. عابر للمنصات يستخدم مشغّل NET Core. الآني المثبّت لتشغيل التطبيق.
</p>

<p>
	بتثبيت الاعتماديات، وإنشاء اتصال بقاعدة البيانات، وتحديث قاعدة البيانات بالجداول الضرورية، ونشرها للإنتاج، تكون قد أكملت ضبط التطبيق التجريبي. في الخطوة التالية ستضبط إعدادات خادم الويب لجعل التطبيق متاحًا وآمنًا على نطاقك.
</p>

<h2>
	الخطوة 4: ضبط إعدادات خادم الويب
</h2>

<p>
	الآن وبعد اتّباع درس <a href="https://academy.hsoub.com/devops/servers/web/nginx/%D9%83%D9%8A%D9%81-%D8%AA%D8%A4%D9%85%D9%91%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-%D9%88%D9%8A%D8%A8-nginx-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1604-r365/" rel="">كيف تؤمّن خادم Nginx بشهادة Let's Encrypt</a> ستحصل على كتلة الخادم لنطاقك في <code>‎/etc/nginx/sites-available/your_domain</code> مع توجيه <code>server_name</code> الذي تمّ تعيينه بالفعل بشكلٍ مناسب. في هذه الخطوة ستعدّل كتلة الخادم هذه لتقوم بضبط Nginx كوكيل (proxy) عكسي لتطبيقك. الوكيل العكسي هو خادم يقع أمام خوادم الويب ويعيد توجيه كل طلب من مستعرض الويب إلى خوادم الويب هذه. إنّه يستقبل كل الطلبات من الشبكة ويعيد توجيهها إلى خادم ويب مختلف.
</p>

<p>
	في حالة تطبيق ASP.NET Core، يعدّ خادم الويب <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2" rel="external nofollow">Kestrel</a> هو الخادم المفضّل المضمّن افتراضيًا، وهذا ممتاز لتقديم المحتوى الديناميكي من تطبيق ASP.NET Core لكونه يوفر أداءً أفضل لمعالجة الطلبات وقد صُمم لجعل ASP.NET أسرع قدر الإمكان. ومع ذلك لا يعد Kestrel خادم ويب كامل المواصفات لأنه لا يمكنه إدارة الأمان وتقديم الملفات الثابتة، ولهذا يُستحسن دائمًا تشغيله خلف خادم ويب.
</p>

<p>
	للبدء، تأكد من أنّك داخل المجلد الجذر للخادم:
</p>

<pre class="ipsCode">
$ cd ~
</pre>

<p>
	افتح كتلة الخادم للتعديل بهذا الأمر:
</p>

<pre class="ipsCode">
$ sudo nano /etc/nginx/sites-available/your_domain
</pre>

<p>
	كما هو مفصّل في الخطوة 4 من درس <a href="https://academy.hsoub.com/devops/servers/web/nginx/%D9%83%D9%8A%D9%81-%D8%AA%D8%A4%D9%85%D9%91%D9%86-%D8%AE%D8%A7%D8%AF%D9%85-%D9%88%D9%8A%D8%A8-nginx-%D8%B9%D9%84%D9%89-%D8%A3%D9%88%D8%A8%D9%86%D8%AA%D9%88-1604-r365/" rel="">كيف تؤمّن خادم Nginx بشهادة Let's Encrypt</a>، إذا اخترت الخيار 2، فإنَّ برنامج Certbot سيضبط تلقائيًا كتلة الخادم هذه لإعادة توجيه حركة مرور HTTP إلى HTTPS مع بعض التعديلات فقط.
</p>

<p>
	تابع الإعدادات بضبط أول كتلتين في الملف لتصل إلى ما يلي في ملف <code>‎/etc/nginx/sites-available/your-domain</code>:
</p>

<pre class="ipsCode">
server {

    server_name your-domain  www.your-domain;

   location / {
     proxy_pass http://localhost:5000;
     proxy_http_version 1.1;
     proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection keep-alive;
     proxy_set_header Host $host;
     proxy_cache_bypass $http_upgrade;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header X-Forwarded-Proto $scheme;
    }

listen [::]:443 <abbr title="Secure Socket Layer | طبقة المنافذ الآمنة">ssl</abbr> ipv6only=on; # managed by Certbot
listen 443 <abbr title="Secure Socket Layer | طبقة المنافذ الآمنة">ssl</abbr>; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/your-domain/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/your-domain/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-<abbr title="Secure Socket Layer | طبقة المنافذ الآمنة">ssl</abbr>-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/<abbr title="Secure Socket Layer | طبقة المنافذ الآمنة">ssl</abbr>-dhparams.pem; # managed by Certbot


}
…
</pre>

<p>
	هذه الإعدادات في كتلة الخادم ستطلب من خادم Nginx التنصّت على المنفذ 443، الذي هو المنفذ القياسي للمواقع التي تستخدم <abbr title="Secure Socket Layer | طبقة المنافذ الآمنة">SSL</abbr>. بالإضافة إلى ذلك سيقبل Nginx حركة المرور العامة على المنفذ 443 ويعيد توجيه كل طلب مطابق إلى خادم Kestrel المدمج <code><a href="http://localhost:5000" ipsnoembed="false" rel="external nofollow">http://localhost:5000</a></code>.
</p>

<p>
	أخيرًا، بعد كتلة الخادم التي عدلتها في الملف، تأكّد من أنّ كتلة الخادم الثانية في الملف <code>‎/etc/nginx/sites-available/your-domain</code> تبدو كالتالي:
</p>

<pre class="ipsCode">
…
server {
if ($host = www.your-domain) {
    return 301 https://$host$request_uri;
} # managed by Certbot


if ($host = your-domain) {
    return 301 https://$host$request_uri;
} # managed by Certbot


    listen 80;
    listen [::]:80;

    server_name your-domain  www.your-domain;
return 404; # managed by Certbot
}
</pre>

<p>
	ستعيد كتلة الخادم توجيه كل الطلبات إلى <code>https://your-domain</code> و<code>https://www.your-domain</code> لوصول HTTPS آمن.
</p>

<p>
	بعد ذلك، دع Nginx يعكس التغييرات التي قمت بها على كتلة الخادم بتنفيذ الأمر:
</p>

<pre class="ipsCode">
$ sudo nginx -s reload
</pre>

<p>
	بعد إكمال إعداد خادم Nginx، تمّ ضبط الخادم بالكامل لإعادة توجيه جميع طلبات HTTPS الموجهة إلى <code>https://your-domain</code> على تطبيق ASP.NET Core الذي يعمل على الخادم Kestrel إلى <code><a href="http://localhost:5000" ipsnoembed="false" rel="external nofollow">http://localhost:5000</a></code>. ولكن لم يتم ضبط Nginx ليدير إجراء الخادم Kestrel. ستستخدم وظائف <code>systemd</code> لمعالجة هذا والتأكّد من أنّ عملية Kestrel تعمل في الخلفية.
</p>

<p>
	ستسمح لك ملفات <a href="https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files" rel="external nofollow">Systemd</a> بأن تدير إجراءًا من خلال توفير وظائف البدء، والإيقاف، وإعادة التشغيل، والدخول، حالما تنشئ إجراء عمل يدعى وحدة.
</p>

<p>
	انتقل ضمن مجلد <code>systemd</code>:
</p>

<pre class="ipsCode">
$ cd /etc/systemd/systems
</pre>

<p>
	أنشئ ملفًا جديدًا للتعديل:
</p>

<pre class="ipsCode">
$ sudo nano movie.service
</pre>

<p>
	وأضف المحتوى التالي له:
</p>

<pre class="ipsCode">
[Unit]
Description=Movie app

[Service]
WorkingDirectory=/var/www/movie-app
ExecStart=/usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll
Restart=always
RestartSec=10
SyslogIdentifier=movie
User=sammy
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target
</pre>

<p>
	يحدد ملف الإعداد موقع مجلد المشروع مع <code>WorkingDirectory</code> وأمر التنفيذ في بداية العملية في <code>ExecStart</code>. بالإضافة إلى ذلك، لقد اعتدت على استخدام توجيه <code>RestartSec</code> لوصف متى سيتم إعادة تشغيل خدمة <code>systemd</code> إذا تعطلت خدمة مشغّل NET. الآني.
</p>

<p>
	الآن، احفظ الملف وفعّل خدمة movie المنشأة حديثًا مع الأمر:
</p>

<pre class="ipsCode">
$ sudo systemctl enable movie.service
</pre>

<p>
	بعد ذلك، تابع لتشغيل الخدمة والتحقق من أنّها تعمل عند التشغيل:
</p>

<pre class="ipsCode">
$ sudo systemctl start movie.service
</pre>

<p>
	ثمّ تفحّص حالتها:
</p>

<pre class="ipsCode">
$ sudo systemctl status movie.service
</pre>

<p>
	ستشاهد الخرج التالي:
</p>

<pre class="ipsCode">
Output
movie.service - Movie app
   Loaded: loaded (/etc/systemd/system/movie.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2019-06-23 04:51:28 UTC; 11s ago
 Main <abbr title="Process IDentifier | معرّف العملية أو البرنامج">PID</abbr>: 6038 (dotnet)
    Tasks: 16 (limit: 1152)
   CGroup: /system.slice/movie.service
           └─6038 /usr/bin/dotnet /var/www/movie-app/bin/Debug/netcoreapp2.2/publish/MvcMovie.dll
</pre>

<p>
	يعطيك هذا الخرج نظرةً عامةً عن الحالة الراهنة لخدمة <code>movie.service</code> المنشأة لتحافظ على التطبيق شغّالًا. تشير إلى أنّ الخدمة شغّالة وفعّالة حاليًا.
</p>

<p>
	انتقل إلى <code>https://your-domain</code> من متصفحك لتشغيل التطبيق واختباره. ستشاهد الصفحة الرئيسية للتطبيق التجريبي- تطبيق قائمة الأفلام.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="32042" href="https://academy.hsoub.com/uploads/monthly_2019_10/pic01.png.b3e856b5e8ca04b7bb03898532be3586.png" rel=""><img alt="pic01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="32042" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2019_10/pic01.thumb.png.26422c04eaf5a74e858ba581c9e0b1cf.png"></a>
</p>

<p>
	مع الخادم الوكيل العكسي وKestrel الذي تتم إدارته باستخدام systemd، تم ضبط تطبيق الويب بالكامل ويمكن الوصول إليه من المتصفح.
</p>

<h2>
	خاتمة
</h2>

<p>
	نشرت في هذا الدرس تطبيق ASP.NET Core على خادم أوبنتو. وقمت بتثبيت خادم MySQL واستخدمته لاستمرار البيانات وإدارتها، واستخدمت خادم الويب Nginx كوكيل عكسي لخدمة تطبيقك.
</p>

<p>
	بعد هذا الدرس، إذا كنت مهتمًا ببناء تطبيق ويب تفاعلي باستخدام #C بدلًا من جافاسكربت، يمكنك تجربة إطار العمل <a href="https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor" rel="external nofollow">Blazor</a> لواجهة المستخدم للويب من مايكروسوفت. إنّه واجهة المستخدم للويب تعتمد على المكونات ومقادة بالأحداث لتحقيق المنطق من جهة العميل في تطبيق ASP.NET Core.
</p>

<p>
	إذا كنت ترغب بنشر تطبيقك، ستحتاج إلى أخذ الإجراءات الأخرى بالحسبان لنشر تطبيقك. الشيفرة المصدرية الكاملة لهذا التطبيق التجريبي تجدها <a href="https://github.com/do-community/movie-app-list" rel="external nofollow">هنا على GitHub</a>.
</p>

<p>
	ترجمة -وبتصرف- للمقال <a href="https://www.digitalocean.com/community/tutorials/how-to-deploy-an-asp-net-core-application-with-mysql-server-using-nginx-on-ubuntu-18-04" rel="external nofollow">How To Deploy an ASP.NET Core Application with MySQL Server Using Nginx on Ubuntu 18.04</a> لصاحبه Oluyemi Olususi
</p>
]]></description><guid isPermaLink="false">748</guid><pubDate>Sat, 05 Oct 2019 06:57:28 +0000</pubDate></item></channel></rss>
