(Visual studio code windows, Debian 10 Buster, Virtual Box, Nginx, Proxy inverso Kestrel, MariaDB, HeidiSQL)
1. Visual Studio Code
Installiamo visual studio code e le estensioni C# e C# Extensions

2. Creiamo un progetto vuoto
Apriamo una finestra dos (prompt dei comandi) o PowerShell, spostarsi nella directory in cui si vuole creare il progetto e inizializzarne uno vuoti con il comando:
dotnet new web -n WebApi01
per la lista completa dei template disponibili digitare dotnet new -–help

3. Impostiamo il progetto in Visual Studio Code
Apriamo Visual Studio Code e selezioniamo la cartella del progetto appena creato

Verrà visualizzato il progetto vuoto appena creato in VS Code

4. Creiamo un installazione di Linux Debian 10 in Virtual Box
Per l’installazione utilizzeremo un immagine iso minimale dato che useremo solo la console e non installeremo nessuna interfaccia grafica
L’immagine iso è prelevabile dal sito ufficiale
https://www.debian.org/CD/netinst/
5. Installiamo il web server nginx
apt update apt install nginx
avviamo nginx con il comando
service nginx start
e verifichiamo che sia raggiungibile con il browser della macchina host puntando l’ip (ip a per visualizzare le informazioni della scheda di rete)
Per comodità si può configurare un indirizzo ip fisso modificando il file di configurazione /etc/network/interfaces
6. Configuriamo il proxy inverso kestrel
Editiamo e modifichiamo il file di configurazione /etc/nginx/sites-available/default
server { listen 80; server_name example.com *.example.com; 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; } } server { listen 80 default_server; # listen [::]:80 default_server deferred; return 444; }
Verifichiamo la sintassi del file di configurazione con il comando
nginx -t
nel caso si riscontrino errori potrebbero essere indicati i numeri delle righe in cui sono presenti (se si utilizza l’editor nano si possono visualizzare, in fase di editing, i numeri delle righe digitando ALT+à)
se non sono presenti errori si può far rileggere il file di configurazione al server
nginx -s reload
7. Installiamo il runtime aspnet core
Aggiungere la chiave di firma del pacchetto Microsoft all’elenco delle chiavi attendibili:
wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb
installiamo il runtime 3.1
apt-get install -y aspnetcore-runtime-3.1 apt-get install -y dotnet-sdk-3.1
8. Installiamo e configuriamo MariaDB
Per installare il database server eseguiamo il comando:
apt install -y mariadb-server
eseguiamo il seguente script per disabilitare l’accesso da remoto per l’utente root
mysql_secure_installation Change the root password - n Remove anonymous users - y Disallow root login remotely – y Reload privilege tables now – y
Creiamo un nuovo utente con gli stessi privilegi dell’utente root accedendo alla shell del database
mysql MariaDB [(none)]> GRANT ALL ON *.* TO 'admin'@'192.168.1.%' IDENTIFIED BY 'password' WITH GRANT OPTION; MariaDB [(none)]> FLUSH PRIVILEGES; MariaDB [(none)]> exit;
9. Abilitiamo l’accesso remoto al database MariaDB
Di default MariaDB accetta connessioni solo dal localhost quindi controlliamo se è possibile accedere da remoto al database server, con il comando
netstat -an | grep 3306

Se il database risulta in ascolto nel localhost (127.0.0.1) dovremmo modificare il file di configurazione
/etc/mysql/mariadb.conf.d/50-server.cnf
modificando il valore del bind-address da 127.0.0.1 a 0.0.0.0
Dopo aver effettuato la modifica riavviamo il servizio di MariaDB
systemctl restart mariadb
ed eseguendo nuovamente il comando
netstat -an | grep 3306
controlleremo l’avvenuta modifica

10. Installazione HeidiSQl e accesso al database server
Scarichiamo ed installiamo il client HeidiSQL per accedere al database dall’indirizzo
creiamo una nuova sessione compilando i dati per l’accesso al database server

Nel caso si stia tentando di accedere con l’utente admin e non si riesca ad accedere, bisogna verificare come è stato configurato l’utente.
Al punto 8 abbiamo creato l’utente admin specificando che fa parte della rete 192.168.1.% (% wildcard che indica tutti gli ip) quindi se si sta tentando di accedere da un client di una rete differente, bisogna aggiornare i dettagli dell’utente accedendo alla shell del database server:
mysql
visualizziamo i dati dell’utente admin:
MariaDB [(none)]>SELECT Host, User FROM mysql.user WHERE User=’admin’;
e nel caso aggiorniamo il dettaglio dell’host:
MariaDB [(none)]>UPDATE mysql.user SET Host=’%’ WHERE User=’admin’;
MariaDB [(none)]>FLUSH PRIVILEGES;
11. Creiamo un database di test
Accedendo alla sessione di HeidiSQL creata, clicchiamo con il tasto destro sul nome del server, selezioniamo nuovo database e impostando il nome TestDB

Allo stesso modo, cliccando con il tasto destro del mouse sul nome del database appena creato, creiamo una tabella chiamata Utenti

Cliccando ora con il tasto destro nell’area relativa alle colonne, possiamo creare le colonne:

Creiamo due colonne:
Id – int – not null
Descrizione – varchar – not null

Clicchiamo il tasto Salva per memorizzare le colonne create
12. Creiamo il servizio
Apriamo VS Code e il progetto vuoto precedentemente creato
Impostiamo la connessione al database nel file appsettings.json

Installiamo i pacchetti per utilizzare l’entity framework nel progetto.
Dal menù Terminal di vs code selezioniamo New Terminal e dalla finestra di terminale creata installiamo i seguenti pacchetti:
D:\...\WebApi01> dotnet add package MySql.Data.EntityFrameworkCore D:\...\WebApi01> dotnet add package Microsoft.EntityFrameworkCore.Design
Utilizziamo il comando dotnet-ef (da netcore 3.0) per la creazione dei files Model del database
D:\...\WebApi01> dotnet-ef dbcontext scaffold "server=IP_SERVER;port=3306;user=admin;password=USER_PASSWORD;database=TestDB" MySql.Data.EntityFrameworkCore -o Models -f
nel progetto verrà creata la cartella Models e i files TestDBContext.cs e Utenti.cs

Nel file TestDBContext.cs viene creata la classe derivata da DbContext dove viene esposta la proprietà DbSet
Nel file Utenti.cs viene creata la classe che rappresenta gli oggetti presenti nel database
Nel file TestDBContext.cs c’è un warning relativo alla stringa di connessione che espone in chiaro la password dell’utente, per la connessione. Possiamo cancellare tutto il metodo OnConfiguring dato che la stringa di connessione al database l’abbiamo impostata nell’appsettings.json e configureremo la connessione nel file Startup.cs
File Startup.cs
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using WebApi01.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace WebApi01 { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddDbContext<TestDBContext>(options => options.UseMySQL(Configuration.GetConnectionString("DefaultConnection"))); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
File TestController.cs
using Microsoft.AspNetCore.Mvc; using WebApi01.Models; using System.Linq; namespace WebApi01.Controllers { [ApiController] [Route("api/test")] public class TestController : ControllerBase { private TestDBContext dBContext; // L'instanza di DbContext è passata via dependency injection public TestController(TestDBContext context) { this.dBContext = context; } [HttpGet] public IActionResult test() { return Ok(dBContext.Utenti.ToList()); } } }
File Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace WebApi01 { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>() .UseUrls(new[] {"http://0.0.0.0:5001"}); }); } }
13 Aggiorniamo il database
dotnet-ef migrations add CreateIdentityModels dotnet-ef database update
14. Pubblichiamo l’applicazione
dotnet publish -c Release -r linux-x64
Copiamo i files presenti nella cartella
D:\..\WebApi01\bin\Release\netcoreapp3.1\linux-x64\publish
nella directory del server
/var/www/webapi01
15. Creiamo il servizio Linux
nano /etc/systemd/system/kestrel-webapi01.service [Unit] Description=Example .NET Web API App running on Ubuntu [Service] WorkingDirectory=/var/www/helloapp ExecStart=/usr/bin/dotnet /var/www/helloapp/helloapp.dll Restart=always # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 KillSignal=SIGINT SyslogIdentifier=dotnet-example User=www-data Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target
avviamo il servizio
systemctl start kestrel-helloapp.service
il servizio creato è raggiungibile all’indirizzo
http://192.168.1.184:5001/api/test
è possibile controllare lo stato del servizio con il comando
systemctl status kestrel-helloapp.service
RIFERIMENTI:
https://docs.microsoft.com/it-it/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-3.1
https://docs.microsoft.com/it-it/dotnet/core/install/linux-debian
https://www.digitalocean.com/community/tutorials/how-to-install-mariadb-on-debian-10
https://webdock.io/en/docs/how-guides/how-enable-remote-access-your-mariadbmysql-database