A partire dalla release v16.6 di React è possibile splittare il codice in diversi file che verranno caricati dinamicamente a seconda della navigazione, rendendo la nostra applicazione più leggera.
Lo scenario più comune di utilizzo è quando il nostro modulo o componente è esportato come default, quindi la conversione è la seguente
// Caricamento standard di un componente
import Component from './component'
const Home = () => {
return <div>
<Component />
</div>
}
// con React.lazy rendiamo dinamico il caricamento
const Component = React.lazy(() => import("./component"));
const Home = () => {
return <div>
<Component />
</div>
}
Ora, che succede se il nostro modulo non è esportato come default?
Secondo la regolare sintassi, il modulo o componente, lo potremmo importare in questo modo:
//component.jsx
export const Component = <h1>Sono il tuo componente</h1>
// home.jsx
import {Component} from './component'
const Home = () => {
return <div>
<Component />
</div>
}
React.lazy, sfrutta il dynamicimport che ritorna una Promise che deve restituire sempre un modulo esportato come default.
Allora a noi ci basta semplicemente risolvere tale Promise e riassegnare il nuovo valore come default.
Abbiamo bisogno di mettere in produzione la nostra applicazione NextJs e ci serve un’immagine Docker leggera su dove farla girare?
Creiamo il nostro Dockerfile in questo modo
# Se stai facendo copia ed incolla, abbi cura di realizzare un .dockerignore!
# Iniziamo il deploy come dipendenza
FROM node:16.13.0-alpine AS deps
# Se ti serve libc per le tue dipendenze, togli il commento dalla riga sottostante:
# RUN apk add --no-cache libc6-compat
# Copiamo solamente il package.json ed installiamo i moduli!
WORKDIR /app
COPY package.json ./
RUN npm install --frozen-lockfile
# END DEPS IMAGE
# Ora creiamo un container solamente per la Build
FROM node:16.13.0-alpine AS BUILD_IMAGE
# Setting della nostra work directory
WORKDIR /app
# Copiamo dalla nostra DEPS, aggiungiamo la'pplicazione
# ed eseguiamo la nostra build di produzione
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Rimuoviamo tutte le dipendenze
# e rieseguiamo l'install ma questa volta con il flag --production.
RUN rm -rf node_modules
RUN npm install --production --frozen-lockfile --ignore-scripts --prefer-offline
# END OF BUILD_IMAGE
# Adesso startiamo la nostra immagine finale.
FROM node:16.13.0-alpine
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# Andiamo a prenderci i file necessari dalla BUILD_IMAGE - e ci servirà:
# 1. il package.json
# 2. la Next build e tutti gli static files
# 3. i node_modules.
WORKDIR /app
COPY --from=BUILD_IMAGE --chown=nextjs:nodejs /app/package.json ./
COPY --from=BUILD_IMAGE --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=BUILD_IMAGE --chown=nextjs:nodejs /app/public ./public
COPY --from=BUILD_IMAGE --chown=nextjs:nodejs /app/.next ./.next
# 4. Opzionale se la tua applicazione ha un next.config.js
COPY --from=BUILD_IMAGE --chown=nextjs:nodejs /app/next.config.js ./
USER nextjs
EXPOSE 3000
CMD [ "npm", "start" ]
Spesso capita di dover eseguire il dump di dati che sono salvati in un container MySql, altrettanto spesso capita di dover eseguire un’importazione massiva.. come fare?
Keycloak è un prodotto software open source per consentire il single sign-on con Identity and Access Management rivolto ad applicazioni e servizi moderni.
Da un punto di vista pratico è un software che permette di gestire i criteri di autenticazione di applicazioni o servizi attraverso i protocolli SAMLv2 o OpenID connect /OAuth2 in perfetta sicurezza.
Scenario d’uso
Immaginiamoci di avere un network di applicazioni ognuna con i propri clienti. In questo modo i diversi applicativi del network, non solo non possono condividere informazioni dell’utente, ma ogni applicazione potrebbe seguire una propria logica di autenticazione.
In uno scenario in cui vorremmo che l’utente fosse federato al nostro network e di conseguenza l’autenticazione fosse centralizzata, avendo criteri di accesso diversificati per applicazioni, come faremmo?
Sappiate che, oltre ad essere un bel rompicapo è anche piuttosto difficile da realizzare mantenendo degli standard di sicurezza elevati.
Gli altri cosa fanno in merito?
Poniamo l’esempio più lampante: Google!
Google ha in pancia una miriade di applicazioni a cui possiamo farne accesso semplicemente avendo un account in Google Account.
Quindi perchè anche noi, non possiamo fare grosso modo la stessa medesima cosa? Ed ecco che Keycloak ci viene in aiuto
Nota
Keycloak è uno dei tanti IM (Identity Manager) esistenti, lo stesso Google (Google IAM) o Microsoft (Azure AD B2C) ne possiedono, ma sono solamente a pagamento perchè gestiti dai rispettivi fornitori.
In realtà Keycloak essendo un prodotto di RedHat ne esiste una versione gestita in toto da RedHat stesso ed anche questa a pagamento.
Dato che noi vogliamo innanzitutto prendere confidenza con questo applicativo al solo scopo didattico, non ci interessa pagare nessuno, ma capirne l’importanza mettendo in piedi un servizio Keycloak localmente così da poter sperimentare quanto detto sopra.
Mettiamo in piedi l’applicativo
Requisiti:
Docker
docker-compose
Aprite la vostra shell e digitate quanto segue:
# a partire della nostra $HOME creiamo una nuova directory e accediamo in essa
mkdir ~/keycloak-test
cd ~/keycloak-test
# scarichiamo il docker-compose di esempio
curl -s https://gist.githubusercontent.com/stefanopascazi/f6ca929194cbf57f228d78ca03b94d54/raw/cc2cfbb66f049c0bab3917e774f5de273e6ab46f/keycloak-docker-compose.yml -o docker-compose.yml
# lanciamo i nostri container
docker-compose up --build
Al termine della procedura di installazione, potremmo visionare il nostro Keycloak appena deployato visitando la url: http://localhost:8481
Clicchiamo su Administration Console ed accediamo con le credenzilai:
admin
password
E benvenuto nel vostro Master Realm
Step by Step: creiamo un reame, un utente di test, un client e tentiamo un autorizzazione
Step 1: Creiamo un nuovo Reame in Keycloak
Cerchiamo di spiegare cosa sono i Realms o reami (in Italiano).
Keycloak si divide in Realms (altri applicativi chiamano la medesima funzione Tenants) ovvero un’applicazione interna che può includere diversi client che condividono gli stessi utenti. Perchè non lavorare sul Master? Beh molto semplice, il realm master è quello con privilegi amministrativi globali.
Quindi, dalla barra a sinistra, posizioniamoci sulla voce Master e clicchiamo sul pulsante “add realm“, diamo un nome al nostro realm (realmtest) e clicchiamo create
Otterrete una schermata come questa
Step 2: creiamo un utente
Dal nostro realm di test nella barra di sinistra clicchiamo su users e nella schermata successiva add user.
Riempiamo i campi richiesti come segue e clicchiamo save:
Si ricaricherà la pagina, mostrando delle nuove tab aggiuntive.
Clicchiamo sulla tab Credientials e compiliamo i campi come in immagine e clicchiamo set password
Step 3: realizziamo un client per la nostra applicazione
Dalla barra di sinistra, clicchiamo su clients e nella nuova schermata clicchiamo create
Assegniamo un ID al nostro client (myclient) e clicchiamo su save
Compiliamo come in schermata l’access-type impostandolo su confidential e la valid redirect url, successivamente clicchiamo save
A questo punto abbiamo finito.
Preleviamo il client_secret dalla tab Credentials, facendo molta attenzione che Client Authenticator sia impostato su Client ID and secret e copiamo il secret
Step 4: eseguiamo la nostra prima autenticazione
Apriamo un terminale ed eseguiamo la nostra cURL in questo modo modificando il client_secret con il vostro appena prelevato:
Nella prossima guida, vedremo di realizzare una piccola applicazione che si connetterà al servizio di autenticazione, ma per adesso, le basi le abbiamo realizzate.
In questa mini guida realizzeremo un’applicazione da zero in Symfony 6.x .
Per prima cosa se ancora non l’abbiamo fatto è necessario installare PHP 8.1.x ed i moduli necessari che sono:
Ctype
Iconv
PCRE
session
SimpleXML
Tokenizer
Ad installazione dei moduli ultimata, assicuriamoci di avere composer installato e la Symfony CLI ( dato che ci permetterà di fare un check dei requirements del framework).
Se avete installato la Symfony CLI potete eseguire il comando:
$ symfony check:requirements
Se avete eseguito correttamente le installazioni vedrete una schermata simile a questa
Bene, siamo pronti a creare la nostra prima applicazione.
Eseguiamo il comando:
$ symfony new my_project_directory --version=6.1.*
# In caso non avessimo la Symfony CLI installata,
# possiamo usare composer in modo da ottenere il medesimo risultato:
$ composer create-project symfony/skeleton:"6.1.*" my_project_directory
A seguito dell’installazione, la nostra prima applicazione symfony è stata creata, spostiamoci nella root del progetto ed eseguiamo l’applicazione appena realizzata
$ cd my_project_directory
# Eseguiamo il web server di Symfony
$ symfony server:start --port=8080
# Se non abbiamo la Symfony CLI installata,
# possiamo eseguire il PHP server dalla cartella public del progetto
$ cd public && php -S localhost:8080
Accediamo all’indirizzo http://localhost:8080 e visualizziamo la nostra applicazione Symfony
Nota
Se è proprio il vostro primo approccio a Symfony, vi consiglio di dare uno sguardo all’applicazione di Demo che gli sviluppatori di Symfony hanno realizzato perchè è un grosso punto di partenza per uno studio iniziale di Symfony, dato che il codice è ampiamente commentato e vengono utilizzati tantissimi componenti. Installare la demo è molto semplice:
$ symfony new my_symfony_demo --demo
Extra: Creiamo il nostro primo IndexController
Se ancora non lo avete fatto, fermate il web server, aprite il progetto con il vostro IDE, posizionatevi con la vostra shell nella root principale del vostro progetto ed installiamo il componente annotation, che ci eviterà di configurare le nostre route a mano
$ composer require annotations
Ora spostiamoci all’interno della root src/Controller e creiamo il nostro primo controller:
$ touch IndexController.php
Apriamo il file appena creato con il nostro IDE ed editiamo in questo modo:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class IndexController
{
/**
* @Route("/")
*/
public function IndexAction(): Response
{
return new Response(
'<html><body><h1>Benvenuto nella tua prima pagina</h1></body></html>'
);
}
}
Ora, eseguiamo di nuovo il nostro server e vedremo il nostro primo Controller in azione.
Ho scritto e testato questa immagine, tenendomi solo lo stretto necessario, eliminando quante più cose possibili ed utilizzando una versione alpine di php8.x
Chiaramente è solo un punto di partenza per applicazioni basate su Symfony 6.x.
FROM php:8.1.5-fpm-alpine
# Install other dependencies
RUN apk add --no-cache unzip \
libxml2-dev \
nano \
icu-dev \
bash \
util-linux \
g++ \
git \
zip \
libzip-dev
RUN apk add --no-cache libpq-dev;
RUN apk add --no-cache php8-dev;
RUN docker-php-ext-install \
pdo \
intl \
soap \
mysqli \
pdo_mysql \
opcache
RUN docker-php-ext-configure zip \
&& docker-php-ext-install zip
# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN docker-php-ext-enable opcache; \
{ \
echo "opcache.preload=/var/www/html/config/preload.php"; \
echo "opcache.preload_user=www-data"; \
echo 'opcache.memory_consumption=256'; \
echo 'opcache.max_accelerated_files=20000'; \
echo 'opcache.validate_timestamps=0'; \
echo 'opcache.enable=1'; \
echo 'opcache.jit_buffer_size=100M'; \
echo 'opcache.jit=1255'; \
echo "realpath_cache_size=4096K"; \
echo "realpath_cache_ttl=600"; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
RUN { \
echo "upload_max_filesize=128M;"; \
echo "post_max_size=256M;"; \
echo "memory_limit = 512M;"; \
echo "max_execution_time=300;"; \
echo "session.cookie_httponly=1"; \
echo "short_open_tag=Off"; \
} > /usr/local/etc/php/conf.d/uploads.ini
# install gd library
RUN apk add --update --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev libwebp-dev
RUN docker-php-ext-configure gd \
--with-freetype \
--with-jpeg \
--with-webp \
NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1)
RUN docker-php-ext-install -j$(nproc) gd \
&& apk del --no-cache freetype-dev libpng-dev libjpeg-turbo-dev
# install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Install symfony-cli
RUN apk add --no-cache bash
RUN curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.alpine.sh' | bash
RUN apk add symfony-cli
# post installation
RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
WORKDIR /var/www/html
EXPOSE 9000
CMD ["php-fpm"]