GNU/Linux >> Tutoriales Linux >  >> Linux

Ejecución de ASP.NET Core en el alojamiento Linux compartido más barato de GoDaddy - No intente esto en casa

Primero, un descargo de responsabilidad. No hagas esto. Hice esto para probar una teoría y probar un punto. ASP.NET Core y .NET Core en los que se ejecuta son de código abierto y se ejecutan prácticamente en cualquier lugar. Quería ver si podía ejecutar un sitio ASP.NET Core en el alojamiento más barato de GoDaddy ($3, aunque se escala a $8) que básicamente admite solo PHP. No es una máquina virtual Linux completa. Está bloqueado y limitado. No tienes raíz. Te estás perdiendo la mayoría de las herramientas que esperarías tener.

PERO.

Quería ver si podía ejecutar ASP.NET Core de todos modos. Tal vez si lo hago, ellos (y otros hosts económicos) hablarán con el equipo de .NET, aprenderán que ASP.NET Core es de código abierto y podría ejecutarse fácilmente en su infraestructura existente.

OTRA VEZ: No hagas esto. Es raro. es tonto Pero es genial. EN MI HUMILDE OPINIÓN. También, muchas gracias a Tomas Weinfurt por su ayuda!

Primero, fui a GoDaddy y me inscribí en su alojamiento económico. Nuevamente, no es una VM, sino una compartida. También registré supercheapaspnetsite.com. Usan un sistema de administración web basado en cPanel que realmente no te permite hacer nada. Puede activar SSH, hacer algunas cosas de PHP y, en general, hurgar, pero no es exactamente de bajo nivel.

Primero hago ssh (¡shoosh!) y veo con qué estoy trabajando. Estoy hablando con Ubuntu en la función de Windows 10, que todo desarrollador debería activar. Hace que sea realmente fácil trabajar con hosts Linux si está comenzando desde Linux en 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]$

Bien, se parece a Red Hat, por lo que CentOS 6 debería ser compatible.

Voy a usar .NET Core 2.1 (¡que está en versión preliminar ahora!) y obtener el SDK en https://www.microsoft.com/net/download/all e instalarlo en mi máquina Windows donde desarrollaré y construir la aplicación. No NECESITO usar Windows para hacer esto, pero es la computadora portátil que tengo y también es bueno saber que puedo construir en Windows pero apuntar a CentOS/RHEL6.

A continuación, crearé un nuevo sitio ASP.NET con

dotnet new razor

y luego publicaré una versión independiente como esta:

dotnet publish -r rhel.6-x64

Y esos archivos terminarán en una carpeta como \supercheapaspnetsite\bin\Debug\netcoreapp2.1\rhel.6-x64\publish\

NOTA: Es posible que deba agregar la fuente de NuGet para los diarios de esta vista previa de .NET Core para poder descargar el tiempo de ejecución de RHEL6 durante esta publicación local.

Luego usé WinSCP (o cualquier cliente FTP/SCP que te guste, rsync, etc.) para pasar los archivos a la carpeta ~/www en tu sitio compartido de GoDaddy. Entonces yo

chmod +x ./supercheapasnetsite

para hacerlo ejecutable. Ahora, desde mi sesión ssh en GoDaddy, ¡tratemos de ejecutar mi aplicación!

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'

Por supuesto que no podría ser tan fácil, ¿verdad? .NET Core quiere la biblioteca de desconexión (objeto compartido) y no existe en este sistema bloqueado.

Y no tengo yum/apt/rpm o una forma de instalarlo, ¿verdad?

Podría buscar el archivo tar.gz en algún lugar como este http://download.savannah.nongnu.org/releases/libunwind/ pero necesito pensar en las versiones y asegurarme de que todo esté alineado. Dado que estoy apuntando a CentOS6, debería comenzar aquí https://centos.pkgs.org/6/epel-x86_64/libunwind-1.1-3.el6.x86_64.rpm.html y descargar libunwind-1.1-3.el6 .x86_64.rpm.

Necesito abrir ese archivo rpm y obtener la biblioteca. Los paquetes RPM son solo encabezados en la parte superior de un archivo CPIO, por lo que puedo apt-get install rpm2cpio desde mis instancias locales de Ubuntu (en Windows 10). Luego desde /mnt/c/users/scott/Downloads (donde descargué el archivo) lo extraeré.

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

Ahí están.

Esta parte es genial. Aunque tengo estos archivos, no tengo root ni ninguna forma de "instalarlos". Sin embargo, podría exportar/usar la variable de entorno LD_LIBRARY_PATH para controlar cómo se cargan las bibliotecas O podría colocar estos archivos en $ORIGIN/netcoredeps . Puede leer más sobre las aplicaciones autónomas de Linux en .NET Core aquí.

El ejecutable principal de las aplicaciones .NET Core publicadas (que es el host .NET Core) tiene una propiedad RPATH establecida en $ORIGIN/netcoredeps . Eso significa que cuando el cargador de bibliotecas compartidas de Linux busca bibliotecas compartidas, busca en esta ubicación antes de buscar ubicaciones de bibliotecas compartidas predeterminadas. Vale la pena señalar que las rutas especificadas por LD_LIBRARY_PATH variable de entorno o bibliotecas especificadas por LD_PRELOAD La variable de entorno todavía se usa antes que la propiedad RPATH. Entonces, para usar copias locales de las bibliotecas de terceros, los desarrolladores deben crear un directorio llamado netcoredeps junto al ejecutable de la aplicación principal y copie todas las dependencias necesarias en él.

En este punto, agregué una carpeta "netcoredeps" a mi carpeta pública y luego la copié (scp) en GoDaddy. Ejecutémoslo de nuevo.

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, ahora se está quejando de los paquetes de UCI. Estos son para la globalización. Eso también se menciona en los documentos de aplicaciones autónomas de Linux y hay un binario precompilado que podría descargar. Pero hay opciones.

Si su aplicación no opta explícitamente por no usar la globalización, también debe agregar libicuuc.so.{version} , libicui18n.so.{version} y libicudata.so.{version}

Me gusta "optar por no participar", así que no tengo que ir a desenterrar estos ups (aunque podría), así que puedo configurar CORECLR_GLOBAL_INVARIANT env var en 1, o puedo agregar System.Globalization.Invariant =true a supercheapaspnetsite.runtimeconfig .json, que usaré solo para ser desagradable.;)

Cuando lo ejecuto de nuevo, recibo otra queja sobre libuv. Otra biblioteca compartida que no está instalada en esta instancia. Yo podría vaya a buscarlo y póngalo en netcoredeps O, dado que estoy usando .NET Core 2.1, podría probar algo nuevo. Se realizaron algunas mejoras en .NET Core 2.1 en torno a los sockets y el rendimiento de http. En el lado del cliente, estas nuevas bibliotecas administradas se escriben desde cero en código administrado usando el nuevo Span de alto rendimiento y en el lado del servidor podría usar los UseSockets experimentales de Kestrel (Kestrel es el servidor web .NET Core). ) ya que están empezando a mover eso.

En otras palabras, puedo omitir el uso de libuv por completo cambiando mi Program.cs para usar UseSockets() de esta manera.

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

Vamos a ejecutarlo de nuevo. Agregaré la variable de entorno ASPNETCORE_URLS y la estableceré en un puerto alto como 8080. Recuerde, no soy administrador, por lo que no puedo usar ningún puerto por debajo de 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.

Mierda, realmente empezó.

Ok, pero no puedo acceder desde supercheapaspnetsite.com:8080 porque este es el alojamiento compartido administrado bloqueado de GoDaddy. No puedo simplemente abrir un puerto o reenviar un puerto en su panel de control.

Pero. Usan Apache, ¡y eso tiene el archivo .htaccess!

¿Puedo usar mod_proxy y probar esto?

ProxyPassReverse / http://127.0.0.1:8080/

Parece que no, no han activado esto. Es probable que no quieran desviar el proxy a dominios externos, pero sería bueno si permitieran localhost. Gorrón. Tan cerca.

Bien, yo mismo controlaré el tráfico. (No es perfecto, pero todo esto es un pico)

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

Genial, ahora un proxy cursi va en 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.
?>

Cursi, si. Funciona para GET? Además, sí. Este es realmente el trabajo de Apache, no el nuestro, pero felicitaciones a Tomas por esta malvada idea.

Auge. ¿Qué tal otra página en /about? Sí.

Hermoso. Pero tuve que ejecutar la aplicación yo mismo. No tengo supervisor ni administrador de procesos (una vez más, esto ya lo maneja GoDaddy para PHP, pero estoy en un mundo sin privilegios). Instalarlo y ejecutarlo es una mala idea y no es sostenible. (Bueno, todo esto no es sostenible, pero aun así).

Podríamos copiar la "pantalla" e iniciarla y separarla como la aplicación use screen ./supercheapaspnet, pero nuevamente, si falla, nadie la iniciará. Nosotros hacemos tiene crontab, así que por ahora, lanzaremos la aplicación de vez en cuando para hacer una verificación de estado y, si es necesario, mantenerla en funcionamiento. También se agregaron algunas herramientas de depuración en ~/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*

Con todo, no es tan difícil. ASP.NET Core y .NET Core debajo pueden ejecutarse prácticamente en cualquier lugar, como PHP, Python, lo que sea.

Si es un anfitrión y quiere hablar con alguien de Microsoft sobre cómo configurar el alojamiento compartido de ASP.NET Core, envíe un correo electrónico a [email protected] y hable con ellos. Si eres GoDaddy, te pido disculpas y también debes enviar un correo electrónico.;)

Patrocinador: Obtenga el último JetBrains Rider para depurar código .NET de terceros, Smart Step Into, más mejoras del depurador, C# Interactive, nuevo asistente de proyectos y formateo de código en columnas.


Linux
  1. ¿Visual Basic es compatible con .NET Core en Linux?

  2. Cómo eliminar versiones anteriores de .NET Core de Linux (CentOS 7.1)

  3. Cómo escribir un demonio de Linux con .Net Core

  4. NuGet para .NET Core en Linux

  5. ¿Existe F# Interactive para Linux en .NET Core, sin usar Mono?

Exploración de ASP.NET Core con Docker en contenedores de Linux y Windows

Mover un ASP.NET Core de Azure App Service en Windows a Linux probando primero en WSL y Docker

Probar .NET Core en Linux con solo un tarball (sin apt-get)

Publicación de un sitio web ASP.NET Core en un host de máquina virtual Linux económico

Cómo instalar (.NET Core) Dotnet Core en distribuciones de Linux

MX Linux:pruebe esta distribución de Linux para disfrutar de una experiencia de escritorio ágil