GNU/Linux >> Linux Esercitazione >  >> Linux

Esecuzione di ASP.NET Core sull'hosting Linux condiviso più economico di GoDaddy:non provarlo a casa

In primo luogo, un disclaimer. Non farlo. L'ho fatto per testare una teoria e per dimostrare un punto. ASP.NET Core e .NET Core su cui viene eseguito sono open source e funzionano praticamente ovunque. Volevo vedere se potevo eseguire un sito ASP.NET Core sull'hosting più economico di GoDaddy ($ 3, anche se scala a $ 8) che fondamentalmente supporta solo PHP. Non è una macchina virtuale Linux completa. È bloccato e limitato. Non hai radice. Ti mancano la maggior parte degli strumenti che ti aspetteresti di avere.

MA.

Volevo vedere se potevo comunque far funzionare ASP.NET Core su di esso. Forse se lo faccio, loro (e altri host economici) parleranno con il team .NET, scopriranno che ASP.NET Core è open source e potrebbe essere facilmente eseguito sulla loro infrastruttura esistente.

ANCORA: Non farlo. È hacky. È sciocco. Ma è davvero fantastico. A PARER MIO. Inoltre, un grande ringraziamento a Tomas Weinfurt per il suo aiuto!

Per prima cosa, sono andato su GoDaddy e mi sono registrato per il loro hosting economico. Ancora una volta, non una VM, ma la loro condivisa. Ho anche registrato supercheapaspnetsite.com. Usano un sistema di gestione web basato su cPanel che in realtà non ti consente di fare nulla. Puoi attivare SSH, fare alcune cose PHP e generalmente curiosare, ma non è esattamente di basso livello.

Per prima cosa ssh (shoosh!) E vedo con cosa sto lavorando. Sto sparando con Ubuntu su Windows 10, che ogni sviluppatore dovrebbe attivare. Rende davvero facile lavorare con host Linux se inizi da Linux su Windows 10.

secretname@theirvmname [/proc]$ cat version
Linux version 2.6.32-773.26.1.lve1.4.46.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) ) #1 SMP Tue Dec 5 18:55:41 EST 2017
secretname@theirvmname [/proc]$

OK, sembra Red Hat, quindi CentOS 6 dovrebbe essere compatibile.

Userò .NET Core 2.1 (che è ora in anteprima!) e prenderò l'SDK su https://www.microsoft.com/net/download/all e lo installerò sul mio computer Windows dove svilupperò e costruire l'app. Non ho bisogno di usare Windows per farlo, ma è il laptop che ho ed è anche bello sapere che posso costruire su Windows ma scegliere come target CentOS/RHEL6.

Successivamente creerò un nuovo sito ASP.NET con

dotnet new razor

e poi pubblicherò una versione autonoma come questa:

dotnet publish -r rhel.6-x64

E quei file finiranno in una cartella come \supercheapaspnetsite\bin\Debug\netcoreapp2.1\rhel.6-x64\publish\

NOTA: Potrebbe essere necessario aggiungere il feed NuGet per i quotidiani per questa anteprima di .NET Core per scaricare il runtime RHEL6 durante questa pubblicazione locale.

Quindi ho usato WinSCP (o qualsiasi client FTP/SCP che ti piace, rsync, ecc.) Per trasferire i file nella cartella ~/www sul tuo sito condiviso GoDaddy. Allora io

chmod +x ./supercheapasnetsite

per renderlo eseguibile. Ora, dalla mia sessione ssh su GoDaddy, proviamo a eseguire la mia app!

secretname@theirvmname [~/www]$ ./supercheapaspnetsite
Failed to load hb, error: libunwind.so.8: cannot open shared object file: No such file or directory
Failed to bind to CoreCLR at '/home/secretname/public_html/libcoreclr.so'

Certo non potrebbe essere così facile, giusto? .NET Core vuole la libreria unwind (oggetto condiviso) e non esiste su questo sistema bloccato.

E non ho yum/apt/rpm o un modo per installarlo giusto?

Potrei cercare il file tar.gz da qualche parte come questo http://download.savannah.nongnu.org/releases/libunwind/ ma devo pensare alle versioni e assicurarmi che le cose siano allineate. Dato che sto prendendo di mira CentOS6, dovrei iniziare qui https://centos.pkgs.org/6/epel-x86_64/libunwind-1.1-3.el6.x86_64.rpm.html e scaricare libunwind-1.1-3.el6 .x86_64.rpm.

Ho bisogno di aprire quel file rpm e ottenere la libreria. I pacchetti RPM sono solo intestazioni sopra un archivio CPIO, quindi posso apt-get install rpm2cpio dalle mie istanze Ubuntu locali (su Windows 10). Poi da /mnt/c/users/scott/Downloads (dove ho scaricato il file) lo estrarrò.

rpm2cpio ./libunwind-1.1-3.el6.x86_64.rpm | cpio -idmv

Eccoli.

Questa parte è bella. Anche se ho questi file, non ho root o alcun modo per "installarli". Tuttavia, potrei esportare/utilizzare la variabile di ambiente LD_LIBRARY_PATH per controllare come vengono caricate le librerie OPPURE inserire questi file in $ORIGIN/netcoredeps . Puoi leggere ulteriori informazioni sulle applicazioni Linux autonome su .NET Core qui.

L'eseguibile principale delle applicazioni .NET Core pubblicate (che è l'host .NET Core) ha una proprietà RPATH impostata su $ORIGIN/netcoredeps . Ciò significa che quando il caricatore di librerie condivise di Linux cerca le librerie condivise, cerca in questa posizione prima di cercare le posizioni delle librerie condivise predefinite. Vale la pena notare che i percorsi specificati dal LD_LIBRARY_PATH variabile di ambiente o librerie specificate da LD_PRELOAD le variabili di ambiente sono ancora utilizzate prima della proprietà RPATH. Quindi, per poter utilizzare copie locali delle librerie di terze parti, gli sviluppatori devono creare una directory denominata netcoredeps accanto all'eseguibile dell'applicazione principale e copiarvi tutte le dipendenze necessarie.

A questo punto ho aggiunto una cartella "netcoredeps" alla mia cartella pubblica, quindi l'ho copiata (scp) su GoDaddy. Eseguiamolo di nuovo.

secretname@theirvmname [~/www]$ ./supercheapaspnetsite
FailFast: Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.

   at System.Environment.FailFast(System.String)
   at System.Globalization.GlobalizationMode.GetGlobalizationInvariantMode()
   at System.Globalization.GlobalizationMode..cctor()
   at System.Globalization.CultureData.CreateCultureWithInvariantData()
   at System.Globalization.CultureData.get_Invariant()
   at System.Globalization.CultureInfo..cctor()
   at System.StringComparer..cctor()
   at System.AppDomain.InitializeCompatibilityFlags()
   at System.AppDomain.Setup(System.Object)
Aborted

Ok, ora si lamenta dei pacchetti di terapia intensiva. Questi sono per la globalizzazione. Questo è anche menzionato nei documenti delle app Linux indipendenti e c'è un binario precompilato che potrei scaricare. Ma ci sono opzioni.

Se la tua app non disattiva esplicitamente l'utilizzo della globalizzazione, devi anche aggiungere libicuuc.so.{version} , libicui18n.so.{version} e libicudata.so.{version}

Mi piace "opt-out", quindi non devo andare a scavare questi up (anche se potrei) quindi posso impostare CORECLR_GLOBAL_INVARIANT env var su 1, oppure posso aggiungere System.Globalization.Invariant =true a supercheapaspnetsite.runtimeconfig .json, che farò solo per essere odioso.;)

Quando lo eseguo di nuovo, un altro si lamenta di libuv. Ancora un'altra libreria condivisa che non è installata in questa istanza. potrei vai a prenderlo e mettilo in netcoredeps O poiché sto usando .NET Core 2.1, potrei provare qualcosa di nuovo. Sono stati apportati alcuni miglioramenti in .NET Core 2.1 in merito ai socket e alle prestazioni http. Sul lato client, queste nuove librerie gestite vengono scritte da zero nel codice gestito utilizzando il nuovo Span ad alte prestazioni e sul lato server potrei usare UseSockets sperimentale di Kestrel (Kestrel è il server web .NET Core) sperimentale ( ) mentre stanno iniziando a spostarlo.

In altre parole, posso bypassare completamente l'utilizzo di libuv modificando il mio Program.cs per utilizzare UseSockets() in questo modo.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
     WebHost.CreateDefaultBuilder(args)
     .UseSockets()
     .UseStartup<Startup>();

Eseguiamolo di nuovo. Aggiungerò la variabile di ambiente ASPNETCORE_URLS e la imposterò su una porta alta come 8080. Ricorda, non sono un amministratore, quindi non posso usare nessuna porta inferiore a 1024.

secretname@theirvmname [~/www]$ export ASPNETCORE_URLS="http://*:8080"
secretname@theirvmname [~/www]$ ./supercheapaspnetsite
Hosting environment: Production
Content root path: /home/secretname/public_html
Now listening on: http://0.0.0.0:8080
Application started. Press Ctrl+C to shut down.

Porca miseria, è iniziato davvero.

Ok, ma non riesco ad accedervi da supercheapaspnetsite.com:8080 perché questo è l'hosting condiviso gestito bloccato di GoDaddy. Non posso semplicemente aprire una porta o inoltrare una porta nel loro pannello di controllo.

Ma. Usano Apache e questo ha il file .htaccess!

Posso usare mod_proxy e provare questo?

ProxyPassReverse / http://127.0.0.1:8080/

Sembra di no, non l'hanno attivato. Probabilmente non vogliono eseguire il proxy su domini esterni, ma sarebbe bello se consentissero localhost. Peccato. Così vicino.

Bene, indirizzerò io stesso il traffico. (Non perfetto, ma questo è tutto un picco)

RewriteRule ^(.*)$  "show.php" [L]

Fantastico, ora un proxy scadente va in show.php.

<?php
$site = 'http://127.0.0.1:8080';
$request = $_SERVER['REQUEST_URI'];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $site . $request);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
$f = fopen("headers.txt", "a");
    curl_setopt($ch, CURLOPT_VERBOSE, 0);
    curl_setopt($ch, CURLOPT_STDERR, $f);
    #don't output curl response, I need to strip the headers.
    #yes I know I can just CURLOPT_HEADER, false and all this 
    # goes away, but for testing we log headers
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$hold = curl_exec($ch);

#strip headers
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($hold, 0, $header_size);
$response = substr($hold, $header_size);
$headerArray = explode(PHP_EOL, $headers);

echo $response; #echo ourselves. Yes I know curl can do this for us.
?>

Di formaggio, sì. Funziona per GET? Inoltre, sì. Questo è davvero il lavoro di Apache, non il nostro, ma complimenti a Tomas per questa idea malvagia.

Boom. Che ne dici di un'altra pagina su /about? Sì.

Bello. Ma ho dovuto eseguire l'app da solo. Non ho un supervisore o un responsabile di processo (di nuovo questo è già gestito da GoDaddy per PHP ma sono in un mondo senza privilegi.) Lanciarlo e gestirlo è una cattiva idea e non sostenibile. (Beh, tutta questa faccenda non è sostenibile, ma comunque.)

Potremmo copiare "schermo" e avviarlo e staccarlo come usa l'app screen ./supercheapaspnet, ma di nuovo, se si arresta in modo anomalo, nessuno lo avvierà. Noi lo facciamo dispone di crontab, quindi per ora avvieremo l'app in base a una pianificazione occasionale per eseguire un controllo dello stato e, se necessario, mantenerla in esecuzione. Aggiunti anche alcuni strumenti di debug in ~/bin:

secretname@theirvmname [~/bin]$ ll
total 304
drwxrwxr-x  2    4096 Feb 28 20:13 ./
drwx--x--x 20    4096 Mar  1 01:32 ../
-rwxr-xr-x  1  150776 Feb 28 20:10 lsof*
-rwxr-xr-x  1   21816 Feb 28 20:13 nc*
-rwxr-xr-x  1  123360 Feb 28 20:07 netstat*

Tutto sommato, non così difficile. ASP.NET Core e .NET Core sottostanti possono essere eseguiti praticamente ovunque, proprio come PHP, Python, qualunque cosa.

Se sei un host e vuoi parlare con qualcuno in Microsoft della configurazione dell'hosting condiviso ASP.NET Core, invia un'e-mail a [email protected] e parla con loro! Se sei GoDaddy, mi scuso e dovresti anche inviare un'e-mail.;)

Sponsor: Ottieni l'ultimo JetBrains Rider per il debug di codice .NET di terze parti, Smart Step Into, ulteriori miglioramenti del debugger, C# Interactive, nuova procedura guidata di progetto e formattazione del codice nelle colonne.


Linux
  1. Visual Basic è supportato da .NET Core in Linux?

  2. Esecuzione di un'applicazione ASP.NET Core autonoma su Ubuntu

  3. Come scrivere un demone Linux con .Net Core

  4. NuGet per .NET Core in Linux

  5. C'è F# Interactive per Linux in .NET Core, senza usare Mono?

Esplorazione di ASP.NET Core con Docker in entrambi i contenitori Linux e Windows

Spostamento di un ASP.NET Core dal servizio app di Azure in Windows a Linux eseguendo prima il test in WSL e Docker

Provare .NET Core su Linux con solo un tarball (senza apt-get)

Pubblicazione di un sito Web ASP.NET Core su un host di macchine virtuali Linux economico

Come installare (.NET Core) Dotnet Core nelle distribuzioni Linux

MX Linux:prova questa distribuzione Linux per un'esperienza desktop scattante