Azure Cli

Es un lenguaje para realizar comandos en Azure, viene a competir con el clásico Azure PowerShell. La principales ventajas que aporta:

  • Disponible para Linux, Mac además de Windows.
  • Codigo abierto
  • Compatible con Groovy, Python, Ruby y otros lenguajes de scripting.

Parte común inicial de un script

#login to Azure Container Registry
az acr login --name [ACRName]   
#obtain value from column login server
az acr list --resource-group acrgroup --output table 
#select default subscription
az account set --subscription [SubscriptionId] 
#avoid to configure --resource-group in commands.
az configure --defaults group=[GroupName] 

Ejemplo de Creación de una WebApp

#create a Resource Group
az group create --name [GroupName] --location westeurope 
#create ServicePlan
az appservice plan create --name [ServicePlan]--resource-group [GroupName] --sku S1 
#create WebApp
az webapp create --name [WebAppName]--resource-group [GroupName] --plan [ServicePlan]

Ejemplo de Creación de una Base de Datos

#Create Server
az sql server create --admin-password [password] --admin-user [user] --location westeurope --name [ServerName] --resource-group [GroupName]
#Create Firewall Rule for Allow access from Azure Services
az sql server firewall-rule create --resource-group [GroupName] --server [ServerNameInLowerCase] -n AllowAzureServices --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
#Create Firewall Rule for accessing to Server from Office
az sql server firewall-rule create --resource-group [GroupName] --server [ServerNameInLowerCase] -n [rulename] --start-ip-address [startip] --end-ip-address [endip]
#Create Database as Copy
az sql db copy --dest-name [DestinationDatabaseName] --dest-resource-group [DestinationGroupName] --dest-server [DestinantioServerName] --name [SourceDatabaseName] --resource-group [SourceGroupName] --server [SourceServerName]
Anuncios
Publicado en Azure, DevOps | Deja un comentario

Glosario de operativa de Docker

En la anterior entrada se explico la arquitectura de Docker. En esta entrada se describe los pasos básicos para ponerla en funcionamiento.

Guia Rápida de Comandos de Docker

.

  • docker –version: Versión de Docker.
  • docker version: Configuración del Docker Host disponible: Linux o Windows. Para cambiarlo sobre las propiedades del Docker Host.

    Cambiar la configuración del docker host a Container Linux.

  • docker info: Resumen general del Docker Host.
  • docker run hello-world: Container de ejemplo que se ejecuta “Hello world”.
  • docker ps: Containers ejecutándose en el Docker Host.
  • docker build -t [ContainerImageName] .: Crea una Container Image a partir del DockerFile.
  • docker images: Lista de Container Images creadas.
  • docker run [MultiplesParametros]: Crea el Container y lo ejecuta del Docker Host.
  • docker stop [ContainerNameOrId]: Para la ejecución del Container del Docker Host.
  • docker start [ContainerNameOrId]: Reinicia la ejecución del Container del Docker Host.
  • docker rm -f [ContainerNameOrId]: Para la ejecución y destruye el Container del Docker Host. No afecta la Container Image.
  • docker rmi : Elimina el Container Image del Docker Host.
  • docker tag [ContainerImageNameSource] [ContainerImageNameTarget]: Crea una nueva Container Image a partir de una Container Image.

Guia Rápida de DockerFile

  • FROM [ContainerImageBase]: Obtiene la Container Image base.
  • WORKDIR [Directorio]: Establece el directorio por defecto para otros comandos RUN, CMD, ENTRYPOINT y ADD.
  • COPY [Source] [Destination]: Copia de nuestro directorio en ruta relativa al Container Image.
  • ADD [Source] [Destination]: Copia de nuestro directorio, una Url o un Tar al Container Image.
  • RUN “[Ejecutable]”,”[Parametro1]”,”[Parametro2]”: Ejecuta un comando en el Container Image.
  • ENTRYPOINT [“[Ejecutable]”,”[Parametro1]”,”[Parametro2]”]: Establece un ejecutable que es el punto de entrada cuando se levante la Container Image creada. No puede ser sobrescrito al realizar el docker run aunque si sus parámetros.
  • CMD[“[Ejecutable]”,”[Parametro1]”,”[Parametro2]”]: Establece un ejecutable que es el punto de entrada cuando se levante la Container Image creada. Pero puede ser sobrescrito en el momento de realizar docker run [Comand] de la imagen.

Por ejemplo:

FROM microsoft/dotnet-framework:4.6.2
WORKDIR /app
COPY bin/Release/net462 .
ENTRYPOINT ["dotnetapp-4.6.2.exe"]

Guia Rápida de Comandos de Docker-compose

  • docker-compose –version: Versión de docker-compose.
  • docker-compose up: Crea la Container Image definida DockerFile (si previamente no exite). Crea y ejecuta la configuración de servicios en el cluster definida en el fichero docker-compose.yaml
  • docker-compose stop: Para la ejecución de los contenedores y destruye los Containers del Cluster. No afecta las Container Images.
  • docker-compose down: Para la ejecución de los contenedores y destruye los Containers del Cluster y las Container Images.

Guía Rápida de docker-compose.yaml

Es un fichero en formato YAML.

version: '3'
services:
  [NombreServicio]:
    build: .  #For DockerFile and take name of build image. 
#   build: [NameImage]    For not DockerFile.
      

Azure Container Registry (ACR)

Azure ofrece un registro privado donde almacenar nuestros Container Images.

  • Create ACR:
    #az login  #if we use Azure CLI
    az account list --output table #list subscriptions
    az account set --subscription [SubscriptionId] #select default subscription
    az group create --name [GroupName] --location westeurope #create a resource group
    az acr create --resource-group [GroupName] --name [ACRName]--sku Basic #create an azure container registry
    
  • Upload a Image to ACR:
    az acr login --name [ACRName]   #login to Azure Container Registry
    az acr list --resource-group acrgroup --output table #obtain value from column login server
    docker images #obtain the container images
    docker tag [ImageSource] [LoginServerUrl/ImageSource] #create new Container Image that contains connection to login server
    docker push [LoginServerUrl/ImageSource] #upload the Container Image to Azure Container Registry
    az acr repository list --name [ACRName]--output table #see the image on Azure Container Registry
    

Azure Container Service

Azure ofrece dos Servicios de Containers:

  • Azure Container Service (AKS): basado en el cluster de Kubernetes. Es el cluster que parece que se va imponer en el mercado. Para crearlo es mejor Azure Cloud Shell (ya que por el Portal de Azure se tienen que generar manualmente las claves SSH) 😉
    La principal ventaja de este Servicio es que se actualiza automáticamente por Azure. Pero por el momento no admite nodos Windows, es decir Container Images basadas en Windows.

    az login  #use Azure CLI in order to install kubercl on local machine
    az provider register -n Microsoft.ContainerService  #assign rights to use aks commands
    az provider register -n Microsoft.Compute
    az group create --name [GroupName] --location westeurope #create a resource group
    az aks create --resource-group [GroupName] --name [AKSName] --node-count 1 --generate-ssh-keys  #create the AKS
    az aks install-cli #download kubercl to local machine
    az aks get-credentials --resource-group=[GroupName] --name=[AKSName] #download de AKS credentials to local machine
    "c:\Program Files (x86)\kubectl" get nodes #test connection to AKS
    "c:\Program Files (x86)\kubectl create secret docker-registry [NameConfigurationSecret] --docker-server=[ServerAcrUrl] --docker-username=[UserAcr] --docker-password=8THfDltjerCKl=[PasswordAcr] --docker-email=[Email] #register connection to private container registry, see PD below.
    

    PD: Fix to connect to Azure Container Registry (ACR).

  • Azure Container Service (ACS): basado en Docker Swarm, DC/OS o Kubernetes. Para crearlo es mejor Azure Cloud Shell. El principal inconveniente es que somos responsables de actualizar el cluster; no acaba de ser un servicio ya que únicamente abarca el despliegue de la infraestructura.
    az login  #use Azure CLI in order to install kubercl on local machine
    az group create --name [GroupName] --location westeurope #create a resource group
    az acs create --orchestrator-type=kubernetes --resource-group [GroupName] --name=[ACSName] --agent-count=1 --generate-ssh-keys --windows --admin-username [UserAcs] --admin-password [PasswordAcs]  #create the ACS
    az acs kubernetes install-cli #download kubercl to local machine
    az acs kubernetes get-credentials --resource-group=[GroupName] --name=[ACSName] #download de ACS credentials to local machine
    "c:\Program Files (x86)\kubectl" get nodes #test connection to ACS
    "c:\Program Files (x86)\kubectl create secret docker-registry [NameConfigurationSecret] --docker-server=[ServerAcrUrl] --docker-username=[UserAcr] --docker-password=[PasswordAcr] --docker-email=[Email] #register connection to private container registry
    

Guia Rápida de Comandos de Kubernetes


Kubernetes incorpora un nuevo concepto Pod. Un Pod es la aplicación, configuración de red y storage que se añade al cluster (que puede estar compuesta de varios servicios en diferentes Containers). Podemos interactuar con el cluster mediante linea de comandos con kubectl.

  • kubectl get nodes: Lista de nodos en el cluster.
  • kubectl create secret docker-registry [NameConfigurationSecret] –docker-server=[ServerAcrUrl] –docker-username=[UserAcr] –docker-password=8THfDltjerCKl=[PasswordAcr] –docker-email=[Email]:
    Crea una configuración para permitir a Kubernetes acceder a repositiros de Container Images como Azure Container Registry.
  • kubectl create -f [file]: Crea y ejecuta la configuración de servicios en el cluster definida en el kubernetes manifest file.
  • kubectl get pods: Muestra los servicios en el cluster.
  • kubectl delete pod [NombrePod]: Elimina el servicio existen en el cluster.
  • kubectl describe pod [NombrePod]: Muestra el servicio y si ha existió algún problema en la creación se muestra trazas de eventos.
  • kubectl logs [NombrePob]: Muestra los logs (output) del servicio ejecutado.

Guía Rápida de Comandos de Minikube


Para trabajar en local; esta minikube muestra un cluster de kubernetes de un solo nodo. Por defecto configura kubectl para trabajar con él. De momento solo soporta nodo Linux, es decir no admite Container Images basadas en Windows.

  • minikube-windows-amd64.exe start –vm-driver=hyperv: Crea el cluster usando hyperv.
  • minikube-windows-amd64.exe dashboard: Abre Web con el Dashboard del cluster.
  • minikube-windows-amd64.exe delete: Destruye el cluster.

Guía Rápida de Kubernetes manifest file

Es un fichero en formato YAML.

apiVersion: v1
kind: Pod
metadata:
  name: [NombreServicio]
spec:
  containers:
  - name: [NombreServicio]
    image: [LoginServerUrl/ImageSource]
  restartPolicy: [RestarPolicy]      
  imagePullSecrects:
  - name: [NameConfigurationSecret]
  nodeSelector: 
    beta.kubernetes.io/os: windows

Por ejemplo:

apiVersion: v1
kind: Pod
metadata:
    name: dotnetapp462-app
spec:
    containers:
    - name: dotnetapp462-app
      image: acrnamepepe.azurecr.io/dotnetapp462_app
    restartPolicy: Never      
    imagePullSecrets:
    - name: acrnamepepesecret
    nodeSelector:
        beta.kubernetes.io/os: windows
Publicado en DevOps | Deja un comentario

General Data Protection Regulation (GDPR)

Que es la GDPR?

Es la ley europea que regula los datos que recogen y analizan las empresas de los usuarios de la Unión Europea. El objetivo es regular la privacidad de los datos y la protección de los derechos sobre ellos. Entra en activo el 25 Mayo de 2018. Provoca que se deban actualizar los procesos de seguridad relacionados con los datos personales.

Cuales son los datos personales?

Aquellos que permiten identificar al usuario.

  • Identificación personal: nombre, id (dni), teléfono, dirección, datos bancarios…
  • Identificación física: genético, física, datos médicos…
  • Identificación digital: email, ips, cookies, user id,…

Que aplica sobre estos datos

  • Debe solicitarse para al usuario su consentimiento y este puede eliminarlo o rectificar los datos en cualquier momento.
  • Los datos no pueden salir de la empresa, salvo consentimiento explicito.
  • Asegurar la privacidad ((encriptación) y seguridad de los mismos. En caso violación de los datos, notificarse al agente supervisor y cuando reviste especial gravedad también a los usuarios.
Publicado en Seguridad | 2 comentarios

Productos de Seguridad Microsoft

Es un poco caótico; voy a intentar hacer un pequeña estructuración y resumen de la multitud de productos de seguridad disponibles. 😉

Office 365

  • Productos específicos para Exchange:
    • Exchange Online Protection (EOP): Evita spam (tanto evita el de entrada como el de envio) y adjuntos maliciosos (malware, virus…) en los mensajes de correo.
    • Office 365 Advanced Threat Protection (ATP): Evita los adjuntos maliciosos (malware, virus…) y enlaces no seguros en los mensajes de correo. Este incorpora características detección adjuntos maliciosos más avanzadas que no incorpora el anterior (EOP).
    • Exchange Online Archiving (EOA): Permite almacenar en la nube el correo a modo de backup, recuperación de mensajes borrados… Este se encuentra en otro almacén secundario (pst). Además incorpora funcionalidad de eDiscovery (permite verificar legalmente los correos).
  • Office 365 Data Loss Prevention (DLP): Permite controlar la información sensible (tarjetas de crédito, número de la seguridad social…) que circula en la empresa. Se audita tanto la información confidencial que se publica (SharePoint y OneDrive), se envía (Exchange) y/o se añade en las aplicaciones de Office (Outlook, Word, Excel y PowerPoint).
  • Azure Information Protection (AIP): Permite clasificar/etiquetar los documentos y mensajes basándose en recomendaciones (detección de información sensible) o clasificación directa por parte de los usuarios. En función de la clasificación permite su protección y compartición.
  • Office 365 Cloud App Security: Permite detectar uso anormal de los usuarios en aplicaciones cloud. Este incluye el subproducto especifico para Office 365:
  • Office 365 Lockbox: Permite controlar el acceso a la información cuando un agente de soporte accede a la información.

SQL Azure

Azure Active Directory (AAD)

Sistema Operativo

Azure

  • Azure Security Center: Permite auditar la seguridad de las maquinas, redes y servicios de Azure. Incorpora controles y protección frente ataques y exploits.
  • Azure Key Vault: Servicio que permite almacenar claves para las aplicaciones o servicios. Se describió en detalle en la entrada Azure Key Vault.
  • Azure site Recovery: Replica maquinas físicas/virtuales en otra ubicación de manera que si se produce un corte automáticamente se activa la replica.
  • Azure Backup y Recovery Services vault: Permite realizar backup de ficheros, servidores o base de datos en SQL en la nube.
  • Microsoft Antimalware: Extensión de seguridad que se añade a maquinas virtuales o Cloud Services de Azure para proteger del malware.
  • Azure DDoS Protection: Monitoriza el trafico evitando ataques DDOS a IPs por volumen y violación de protocolos capa de comunicación.
  • Web application firewall (WAF): Monitoriza el trafico evitando ataques en la capa de aplicación (inyección de SQL, cross site scripting y violación de HTTP).
  • Network Security Groups: Permite definir reglas de filtrado en la red; viene a ser al equivalente a firewall físico en un entorno de Azure.
  • Application Gateway: Balanceador de carga que permite la distribución del trafico entre varias maquinas y proteger frente a caídas de alguna maquina.
  • Storage Service Encryption: Permite encriptar los discos y datos del Azure storage.
Publicado en Azure, Seguridad, Sql Azure | Etiquetado , | Deja un comentario

Graph API

Graph API

La Graph API permite acceder a los múltiples servicios cloud de Microsoft (Azure Active Directory, Sharepoint, Exchange, OneDrive…) de una manera simple y unificada. Básicamente permite extender Office 365 mediante API.
El nombre de Graph es debido a que la información se obtiene navegando entre nodos. Por ejemplo del nodo usuario a su nodo de correos. Además incorpora Office Graph Insights que analiza el contenido, configuración y comportamiento del usuario. Y permite un acceso navegando mediante el análisis calculado.
Grafo de objetos Graph API
Hay disponibles SDK para diferentes lenguajes o Rest API.

Acceso Rest API

Se puede probar directamente en el Graph Explorer.

  • Url: https://graph.microsoft.com/{version}/{resource}/{odata_query_parameters}
    • donde {versión} es v1.0 o beta.
    • donde {resource} indica el recurso. Por ejemplo: me (mi usuario), users (todos los usuarios), users/pepe@contonso.com (usuario pepe@consoto) , me/messages (mis correos)…
    • donde {odata_query_parameters} indica opcionalmente filtros adicionales. Por ejemplo: $select=ID (retorna únicamente el ID), $orderby=id&top=1 (retorna el primer id menor), $filter=givenname+eq+%27pepe%27 (objeto con la propiedad givenname igual a pepe)…
  • Http Method: el tipo de operación Get, Post… que queremos realizar.
  • Se accede mediante un token OAuth con el header Bearer en la petición.
  • Respuesta: JSON.

Funcionalidades Avanzadas

  • Delta: Permite realizar múltiples llamadas que conservan el estado anterior para mostrar tan solo los nuevos objetos.
  • Webhooks: Permite definir callbacks cuando ocurre algún evento.
Publicado en Graph | Deja un comentario

Particionar Tablas en SQL Server

Cuando el numero de registros de una tabla es muy elevado, el rendimiento puede degradarse. Tenemos la posibilidad de dividirla en trozos; es decir particionarla. En ciertos escenarios permite mejorar el rendimiento en consultas y en operaciones masivas de mantenimiento.

  • 1.- En SQL OnPremise debemos definimos las particiones (espacios donde ubicar los datos). Por ejemplo a nivel físico podemos distribuir las particiones en diferentes unidades de disco.
    ALTER DATABASE [BackupOfCSPBillingSoftengPartition2]
    ADD FILEGROUP HalfYear1
    GO
    ALTER DATABASE [BackupOfCSPBillingSoftengPartition2]
    ADD FILEGROUP HalfYear1b
    GO
    ALTER DATABASE [BackupOfCSPBillingSoftengPartition2]
    ADD FILEGROUP HalfYear2
    GO
    ALTER DATABASE [BackupOfCSPBillingSoftengPartition2]
        ADD FILE 
        (
        NAME = HalfYear1,
        FILENAME = 'd:\Backup\PartitioningDB1.ndf',
            SIZE = 3072 KB, 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 10024 KB
        ) TO FILEGROUP HalfYear1
    
    ALTER DATABASE [BackupOfCSPBillingSoftengPartition2]
        ADD FILE 
        (
        NAME = HalfYear1b,
        FILENAME = 'd:\Backup\PartitioningDB2.ndf',
            SIZE = 3072 KB, 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 10024 KB
        ) TO FILEGROUP HalfYear1b
    
    ALTER DATABASE [BackupOfCSPBillingSoftengPartition2]
        ADD FILE 
        (
        NAME = HalfYear2,
        FILENAME = 'd:\Backup\PartitioningDB3.ndf',
            SIZE = 3072 KB, 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 10024 KB
        ) TO FILEGROUP HalfYear2
    
  • 2.- Crear la función que genera la distribución de Hash. Por ejemplo, genera valores diferentes para cada periodo de medio año.
    CREATE PARTITION FUNCTION [iluUssageDatePartition](datetime) 
    AS RANGE LEFT FOR VALUES (N'2017-01-01T00:00:00', N'2017-06-01T00:00:00', N'2019-01-01T00:00:00')
    
  • 3.- Asigna para cada valor de Hash que partición le corresponde.
    • En SQL OnPremise. Asigna cada valor la partición:
      CREATE PARTITION SCHEME [iluUssageDatePartition] 
      AS PARTITION [iluUssageDatePartition] ALL TO ([PRIMARY]);TO ([HalfYear1], [HalfYear1b], [HalfYear2], [PRIMARY])
      
    • En SQL Azure se asigna todas a la PRIMARIA ya que no tenemos acceso al disco del servidor. Pero asignar las particiones genera internamente optimizaciones en el motor de almacenamiento de SQL Azure. 😉
      CREATE PARTITION SCHEME [iluUssageDatePartition] 
      AS PARTITION [iluUssageDatePartition] ALL TO ([PRIMARY]);
      
  • 4.- Indicar en la tabla que vamos usar la partición.
    • En Tabla Nueva:
      CREATE TABLE [dbo].[InvoiceLineUssage](
      	[InvoiceLineUssageId] [bigint] IDENTITY(1,1) NOT NULL,
              [UsageDate] [datetime] NOT NULL,
              ....
              
              CONSTRAINT [PK_InvoiceLineUssage] PRIMARY KEY NONCLUSTERED 
      (
      	[InvoiceLineUssageId] ASC
      )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
      ) ON ON [iluUssageDatePartition]([UsageDate])
      
    • En Tabla Existente:
      ALTER TABLE [dbo].[InvoiceLineUssage] ADD  CONSTRAINT [PK_InvoiceLineUssage] PRIMARY KEY NONCLUSTERED 
      (
      	[InvoiceLineUssageId] ASC
      )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
      
      
      CREATE CLUSTERED INDEX [ClusteredIndex_on_iluUssageDatePartition_636416817899691987] ON [dbo].[InvoiceLineUssage]
      (
      	[UsageDate]
      )WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [iluUssageDatePartition]([UsageDate])
      
      
      DROP INDEX [ClusteredIndex_on_iluUssageDatePartition_636416817899691987] ON [dbo].[InvoiceLineUssage]
      
Publicado en Sql Azure | Deja un comentario

Optimizaciones con WebPack

En esta entrada se describen las mejoras que podemos obtener WebPack.

Transpilador

Permite usar javascript ES6/7 transformandolo a javascript ES5. Para ello usamos babel-loader.

  • 1.- Instalar el paquete:
    npm i babel-loader babel-core babel-preset-env --save
    
  • 2.- Añadir en la configuración en el webpack.config.js.
        module: {
            rules: [
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['env']
                        }
                    }
                }]
        }
    

Minificar

Genera un javascript de tamaño más reducido.

  • Elimina espacios adicionales, saltos de línea y sangrías.
  • Elimina comentarios.
  • Cambia nombres de nombres de variables y funciones haciendolos más cortos.

Para ello usamos UglifyJsPlugin:

  • 1.- Instalar el paquete:
    npm i uglifyjs-webpack-plugin --save
    
  • 2.- Añadir en la configuración en el webpack.config.js.
    plugins: [
        new webpack.optimize.UglifyJsPlugin()
    ]
    

Compresión

Los servidores de aplicación sirven los ficheros de javascript comprimidos (gzip), pero el nivel de compresión no es el óptimo (también se requiere capacidad de proceso para realizar la compresión). Podemos generar los javascript comprimidos con un menor tamaño usando un nivel más elevado de compresión y evitando procesado en el servidor. Por ejemplo usando CompressionWebpackPlugin.

  • 1.- Instalar el paquete:
    npm i compression-webpack-plugin --save
    
  • 2.- Añadir en la configuración en el webpack.config.js.
                new CompressionPlugin({
                    asset: "gz/[file].gz[query]",
                    algorithm: "gzip",
                    test: /\.(js|html)$/,
                    threshold: 10240,
                    minRatio: 0.8  //Default
                })
    
  • 3.- Para evitar que el IIS vuelva a comprimir los ficheros ya comprimidos. Añadir las siguientes entraras en el web.config.
    <system.webServer>
        <staticContent>
           <mimeMap fileExtension=".js.gz" mimeType="application/javascript" />
        </staticContent>
    </system.webServer>
    
      <location path="dist/gz">
        <system.webServer>
          <urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" />
          <httpProtocol>
            <customHeaders>
              <add name="content-encoding" value="gzip" />
            </customHeaders>
          </httpProtocol>
        </system.webServer>
      </location>
    
  • 4.- Se generan dos ficheros el normal y el nuevo fichero comprimido de extensión .js.gz. En el html referenciaremos este nuevo fichero.
Publicado en web | Deja un comentario