Neste artigo vou demonstrar como criar uma aplicação web Model-view controller (MVC) que vai ler o Feed RSS dos artigos da Revista PROGRAMAR em C# .NET Core 1.1 para Docker. A aplicação vai ser disponibilizada no Azure Web App em Linux através Docker Hub.
Azure Web App
O serviço Azure Web App permite que uma aplicação web desenvolvida em .NET, .NET Core, Java, Node.js, PHP, Python e Ruby esteja disponível em qualquer utilizador através da Internet. Para alguns o Web App é uma forma de disponibilizar uma página de Internet ou framework mas permite muito mais do que isso mais a frente vou demonstrar algumas funcionalidades.
O Web Apps está integrado no Azure App Service que é um conjunto de serviços.
- Web Apps, permite alojar websites e aplicações Web.
- Mobile Apps, alojar aplicações mobile a back-ends.
- Logic Apps, automatizar processos empresariais e integrar sistemas e dados no Azure sem escrever código.
- API apps, para alojar RESTful APIs.
Functions, executa pequenos pedaços de código ou “funções” no Azure.
Os recursos não são reservados a cada serviço os mesmos podem utilizar as funcionalidades dos outros serviços.
O Web App tem tudo o que necessita para construir uma aplicação esta oferece ao administrador de sistema, desenvolvedor ou DevOps uma plataforma totalmente gerida em que se tem acesso as várias funcionalidades por exemplo:
- Always On, mantém a Web App ativa está disponível a partir do Standard tier.
- Definições da aplicação e Connection Strings.
- Registos de auditoria de servidor Web, ficheiros, mensagens de erro detalhadas e pedidos solicitados.
- Backups Manuais e/ou agendados.
- Gestão através de linhas de comandos com Azure PowerShell ou Azure CLI.
- Deployment a partir do Visual Studio Team Services, OneDrive, Git, GitHub, Bitbucker, Dropbox, e outros repositórios externos.
- Monotorização e diagnósticos.
- Múltiplas Framework disponíveis .NET, PHP, Java, Python e Node.js.
- Testes de desempenho.
- Debug remota e por consola.
- Controlo de acesso por funções, Role-Based Access Control (RBAC).
- Scaling Up, Out ou automático.
- Plataforma 32 ou 64 bit.
- Extensões, por exemplo “Let’s Encrypt” que está disponível a partir do tier básico requer Server Name Indication (SNI).
- Site Slots. pode ser utilizado como silo de vida da aplicação.
- Certificados SSL.
- WebJobs, executa tarefas manuais, agendadas, trigger ou contínuo.
Através da plataforma pode ativar ou desativar funcionalidades pretendidas e o Azure automaticamente faz toda essa configuração por nós. Isto é possível porque o Web App é uma plataforma como serviço (Plaform-as-a-Service) apenas gerimos a aplicação e os dados todos. A infraestrutura desde da rede, armazenamento, máquina virtual, sistema operativos, software necessário para executar a aplicação desde do IIS, Apache, Tomcat, ou outro é totalmente gerido pelo Azure e não temos que nos preocupar com manutenção e atualizações, mas a segurança da aplicação é da nossa responsabilidade.
O Azure já dispõe da sua versão em Linux que funciona com máquinas virtuais em Linux, antes estava apenas disponível em Windows. Agora podemos escolher se queremos executar a aplicação num ambiente Windows ou Linux. A versão em Linux foi um dos pedidos mais solicitadas pelos clientes/utilizadores porque há frameworks como o WordPress que funciona muito melhor e mais rapidamente em Linux do que em Windows.
A versão Windows e Linux não são iguais, existem diferenças entre eles. A grande diferença é que em Linux é utilizado o Docker o que permite que se possa utilizar o nosso próprio container que é um recipiente que contem todo o que é necessário para a aplicação ser executada. O Docker Hub é um repositório permite que a Web App seja atualizada automaticamente quando atualizamos a aplicação no Docker Hub, mas também podemos fazer o deployment da aplicação por FTP, Git, Bitbucket.
Outra diferença entre a opção Windows e Linux é o suporte de linguagens de programação em Linux apenas suporta (quando este artigo foi escrito) Node.js 4.4, 4.5, 6.2, 6.6, 6.9-6.11 e 8.0-8.1, o PHP 5.6 e 7.0, .NET Core 1.0-1.1 e o Ruby 2.3. Enquanto a versão Windows tem mais suporte e inclui o Java 7 e 8 e Python 2.7 e 3.4 mas não suporta Ruby.
Como funciona a arquitetura do serviço
O Azure tem dois clusters de computação na mesma rede virtual (VNET) o cluster primário é composto principalmente por tecnologia Microsoft que dispõem de um frontend load balancer que recebe todo tráfego Hypertext Transfer Protocol (HTTP) recebido que por sua vez reencaminha para máquinas ou serviços em ambiente Windows ou Linux, tem o Windows Web Workers que é utilizado para aplicações Windows, um serviço de armazenamento e muito mais. O segundo cluster apenas tem máquinas virtuais com Linux e é neste cluster que vão estar as aplicações Web App em Linux.
O que contém a máquina virtual em Linux?
A máquina contem um proxy que recebe todo o tráfego recebido pelo FrontEnd do cluster principal e o mesmo vai encaminhar para a aplicação a informação solicitada e enviada pelo Site Routing mas este faz muito mais do que enviar a informação ao cliente. O Site Routing gera a aplicação, se verificar que existe uma nova versão ele vai atualizar a mesma.
O container não inclui a informação persistente da aplicação. Cada Web App tem um serviço SCM associado, esse serviço é o Kudu que permite ter acesso a painéis de controlo com linhas de comandos, debug, diagnósticos, processos em execução ou seja permite fazer o deployment rápido. Kudu é um projeto de código aberto e que está disponível no GitHub (https://github.com/projectkudu/kudu) este serviço é executado num contentor a parte.
Os dois containers estão separados através do isolamento de segurança do Docker mas integrados numa única bridge e todas as bridges estão associadas a um plano do serviço (Azure Service Plan).
Os dois containers acedem ao conteúdo da aplicação através do Message Block (SMB) de forma persistente o que significa que quando existe uma alteração é refletida em todos os lugares. Se estiver a executar uma segunda aplicação Web App é criado uma segunda Bridge e por sua vez é criado um novo contentor Docker para aplicação e SCM.
Azure Web App para Containers
Além do Azure Web App em Linux também existe o Azure Web App para Containers mas qual é diferença entre eles? Basicamente o Web App para Containers permite utilizar o nosso próprio Container e efetuar deployment automaticamente, por nós, numa Web App para Linux, ou seja, é uma solução baseada em Web App em Linux mas com a vantagem que todo o processo vai ser feito automaticamente pelo Azure o que permite eliminar as tarefas de gestão. Continuamos a ter acesso à configuração do domínio, certificados SSL e muito mais. É um ambiente ideal para desenvolvedores e DevOps.
Deployment de um Docker Container para Azure Web App em Linux
Antes de iniciar é necessário ter instalado o Docker Community Edition que pode obter na página oficial do Docker Store em https://store.Docker.com/ é compatível com vários sistemas operativos, o .NET Core pode ser obtido em https://www.microsoft.com/net/download/core apesar de ser compatível com o Linux por experiência própria não funciona muito bem com o Fedora 23 e 24, devido a bibliotecas que o próprio Fedora utiliza. Pode alterar mas algumas aplicações instaladas podem deixar de funcionar. Para ambiente de desenvolvimento integrado (IDE) recomendo a utilização do Microsoft Visual Studio 2017. Se utilizar ambientes Linux recomendo o Microsoft Visual Studio Code. Sobre o Visual Studio a versão Community 2017 é igual à versão Professional mas apenas pode ser utilizado por estudantes, projetos de código aberto e desenvolvedores individuais, o Code pode ser utilizado por todos incluindo qualquer projeto empresarial. Neste artigo utilizei o Microsoft Visual Studio 2017. Se utilizar o Visual Studio Code recomendo que instale as seguintes duas extensões Azure Extensions Pack e Docker.
Criação do projeto C# .Net Core 1.1
No Visual Studio é criado um novo projeto ASP.Net Core 1.1 Web Application MVC este projeto já inclui código para efeitos de demonstração pode manter-se esse código ou fazer alterações ao mesmo. O Visual Studio fornece a hipótese de adicionar suporte ao Docker para o sistema operativo em que vai ser executado.
No projeto do Visual Studio criado vai ser adicionado código para ler o RSS do feed dos artigos da página de Internet da Revista PROGRAMAR. Primeiro é necessário criar o modelo de dados que vai ser utilizado para listar a informação como se pretende. Por defeito um feed é composto por um título, o endereço de internet, descrição e a data de publicação. Cria-se uma classe com o nome RSSFeedModel.cs
ou outro se preferir no Models que vai contém o seguinte conteúdo:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace revista_programar.Model { public class RSSFeedModel { public string ArticleTitle { get; set;} public string ArticleLink { get; set;} public string ArticleDescription { get; set;} public string ArticleDate { get; set;} } }
Com o modelo criado é necessário criar o Controler, o projeto já tem uma View inicial com à identificação HomeController.cs
pode utilizar-se e adicionar o código que vai ler o XML com os artigos e armazenar uma lista do modelo criado.
public List<RSSFeedModel> GetFeed() { return Feed().Result; } [HttpPost] public async Task<List<RSSFeedModel>> Feed() { var articles = new List<RSSFeedModel>(); string rssFeedURL = "https://www.revista-programar.info/feed/"; HttpClient httpClient = new HttpClient(); var httpContent = await httpClient.GetStringAsync(rssFeedURL); XDocument xml = XDocument.Parse(httpContent); var RSSFeedData = (from x in xml.Descendants("item") select new RSSFeedModel { ArticleTitle = ((string)x.Element("title")), ArticleLink = ((string)x.Element("link")), ArticleDescription = ((string)x.Element("description")), ArticleDate = ((string)x.Element("pubDate")) }); articles = RSSFeedData.ToList(); return articles; }
Em IActionResult Index()
adiciona-se o seguinte:
public IActionResult Index() { ViewBag.RSSFeed = GetFeed(); return View(); }
Na View principal com a identificação Index.cshtml
que é a página inicial pode personalizar à sua maneira para ler o RSS chama-se o ViewBag.RSSFeed
do que contém a lista do Controller e transforma-se a lista numa tabela:
<div class="row"> <table class="table table-hover"> <thead> <tr> <th>Título</th> <th>Link</th> <th>Descrição</th> <th>Data</th> </tr> </thead> <tbody> @if (ViewBag.RSSFeed != null) { foreach (var item in ViewBag.RSSFeed) { <tr> <td>@item.ArticleTitle</td> <td><a href="@item.ArticleLink">@item.ArticleLink</a></td> <td>@item.ArticleDescription</td> <td>@item.ArticleDate</td> </tr> } } else { <tr> <td>Sem informação</td> <td>Sem informação</td> <td>Sem informação</td> <td>Sem informação</td> </tr> } </tbody> </table> </div>
E o projeto está concluído. Mas antes de criar o Docker container para ser enviado para o Docker HUB eu recomendo testar primeiro na própria máquina. Para testar apenas é necessário executar a compilação do projeto e ter o Docker em execução.
Erros de compilação e/ou execução
Se ao executar e der o seguinte erro:
Docker-compose -f "[Localização do projeto]\Docker-compose.yml" -f "[Localização do projeto]\Docker-compose.override.yml" -f "[Localização do projeto]\obj\Docker\Docker-compose.vs.debug.g.yml" -p Dockercompose3404700638243216757 config .IOError: [Errno 2] No such file or directory: u'[Localização do projeto]\obj\Docker\Docker-compose.vs.debug.g.yml'
Isto deve-se aos seguintes motivos: não tem o Docker instalado, não tem o Docker em execução ou não permitiu ao Docker aceder à unidade de disco onde se encontra o projeto. Neste último problema para permitir ao Docker o acesso ao disco tem de iniciar o Docker com privilégios administrativos e nas definições em Shared Drives tem que selecionar o disco e aplicar. O Docker vai solicitar as credenciais da conta de administrador.
Com o Shared Drives definidos os utilizadores sem privilégios administrativos que pretendam utilizar o Docker apenas têm que iniciar o Docker selecionar a unidade e aplicar. Não vai ser solicitada nenhuma credencial.
Se der o seguinte erro:
UnicodeDecodeError 'ascii' codec can't decote byte [byte] in position [posição] not in range
Isto deve-se ao facto de em todo o caminho do projeto estarmos a usar caracteres especiais como o ‘ç’.
Se encontrar mais erros e não está a conseguir resolver pode consultar a comunidade de desenvolvedores do Visual Studio em https://developercommunity.visualstudio.com.
Com a execução concluída com sucesso o navegador de Internet predefinido vai abrir o projeto MVC criado conforme a seguinte imagem.
Docker
Em Docker existem imagens Docker e Docker containers. A imagem Docker é como um executável que inclui tudo o que é necessário para ser executado e é compatível com os vários sistemas operativos. A vantagem das imagens é que são executados isoladamente assim previne conflitos de software e outros problemas. O Docker container é um recipiente que se encontra na 7ª camada do modelo OSI (Aplicação) que é a camada que está mais próxima do utilizador. Múltiplos containers podem ser executados na mesma máquina e os mesmos partilham o kernel do sistema operativo, mas cada um deles são executados isoladamente. Um Docker container não é a mesma coisa que uma máquina virtual. Enquanto nas máquinas virtuais não é possível partilhar recursos com outras máquinas virtuais (os mesmos têm de ser reservados), o Docker container permite partilhar os recursos. Por exemplo em cada máquina virtual é necessário instalar o sistema operativo e definir o armazenamento e memória RAM e outros recursos. O Docker utiliza o próprio sistema operativo instalado na máquina e os container utilizam os recursos disponíveis. Pode utilizar um Docker container em máquinas locais, virtuais ou em nuvem.
As operações no Docker são executas através de linhas de comandos. O Visual Studio cria automaticamente a imagem Docker e Docker container. Para criar apenas tem de executar a compilação se fizer em Debug vai criar a imagem de desenvolvedor (dev) se fizer em Release vai criar a imagem final (latest).
Para consultar as imagens Docker na máquina executa-se o comando Docker images
se pretende remover uma imagem executa-se o comando Docker rmi [identificação da imagem]
.
Para criar um container a partir de uma imagem executa-se o comando Docker run
, mas é necessário definir qual a imagem, o porto exterior e interior que se pretende utilizar. Para definir a imagem utiliza-se o parâmetro --name [nome da imagem]
, o porto de entrada e saída é o parâmetro -d -p [porto exterior]:[porto interior]
. Existem mais parâmetros como o utilizador, palavra-passe, aceitação dos termos de licenciamento (EULA) e outros pode consultar os comandos a partir da ajuda com o comando Docker run --help
. Para criar o container com o nome revista-programar
em que vai receber pedidos no porto externo 5632 que vão ser reencaminhados para o porto interno 80 e define-se a imagem pela sua identificação o comando é Docker run --name revista-programar -d -p 5632:80 [identificação da imagem]
.
Quando cria a compilação no Visual Studio o mesmo cria automaticamente a imagem e a seguir o container.
Para consultar os Docker container em execução executa-se o comando Docker ps
. Se pretender remover um container utiliza-se o comando Docker rm [identificação do container]
, mas se a mesma estiver em execução não é possível remover. Para parar utiliza-se o comando Docker stop [identificação do container]
. Para forçar a remoção de Docker container utiliza-se o parâmetro -f
.
Docker Hub
O Docker Hub (https://hub.docker.com/) é um repositório em nuvem onde pode ter as suas imagens Docker. O repositório pode ser público ou privado. Este serviço permite ter um repositório privado gratuitamente e repositórios públicos gratuitos. Com este serviço pode distribuir as suas imagens a partir de um único lugar assim quando atualiza o repositório pode atualizar automaticamente os clientes se os mesmos aceitarem atualizações automáticas.
Para criar um repositório Docker Hub tem de ter uma conta no Docker Hub, selecionar Create Repositor, escolher namespace, definir o nome do repositório, adicionar uma descrição curta e longa definir se pretende que o repositório seja público ou privado e para finalizar criar em Create.
Com o repositório criado pode enviar a imagem do projeto para o Docker Hub com o comando docker push
. Primeiro tem que identificar-se no Docker Hub com o comando Docker login
, a seguir tem que definir o tag docker tag [identificação da imagem existente na máquina] [nome do namespace]/[nome do repositório]
, para enviar utilize o comando docker push [nome do namespace]/[nome do repositório]
.
Para sair do Docker utilize o comando docker logout
. Se algum dia pretender definir um repositório público para privado ou apagar o repositório estas operações são executadas nas definições do próprio repositório.
Se pretender descarregar a imagem execute o comando Docker pull [nome do namespace]/[nome do repositório]
. Pode pesquisar imagens com o comando Docker search [nome da imagem]
.
Azure App em Linux
Para consegui utilizar os serviços no Azure é necessário ter uma subscrição, no entanto se nunca utilizou o Azure pode testar o serviço durante 30 dias em https://azure.microsoft.com/pt-pt/free ou experimentar durante 30 minutos sem custo e explicarei adiante com pode fazê-lo.
Normalmente trabalho com sistemas com o idioma em Inglês todas as seguintes imagens estão em Inglês. Para criar uma nova Web App em Linux selecione Novo/New e depois selecione Web + Mobile e escolher Web App. Tem de definir o subdomínio que é único no universo do Azure em azurewebsites.net, se tiver mais do que uma subscrição escolha a subscrição que pretende utilizar, pode escolher um grupo de recursos existente ou criar um novo. Um grupo de recursos é um recipiente de recursos e/ou serviços de Azure quando quiser apagar todos os recursos e/ou serviços no recipiente em vez de apagar um a um pode apagar o grupo de recursos e todos eles serão eliminados. No sistema operativo escolha Linux e tem de escolher ou criar um novo plano de serviço que é o plano de alojamento do serviço. Em Web App em Linux não existe nenhum plano gratuito ao contrário do Web App em Windows que dispõe do plano gratuito o Free Tier. O plano mais baixo em Linux é o Basic B1 mas não tem acesso a todas as funcionalidades como por exemplo slots.
A Web App demora alguns minutos a ser criada e quando finalizar está pronto a ser utilizada. Depois de criar selecione Docker container em definições para definir o repositório da imagem Docker. Selecione Docker Hub e tem que definir o tipo de acesso do seu repositório e a imagem e tag se utilizar [identificação do namespace]/[identificação do repositório]:[Tag]
. Para uma atualização continua pode usar o Web Hock.
Após a definição tem de aguardar que o Azure atualize o Web App, pode demorar uns minutos, no entanto pode verificar o relatório de atividade.
Depois de atualizado com sucesso se aceder ao URI do Web App pode verificar que a mesma já esta em funcionamento com a imagem do repositório definido.
Com a aplicação a correr pode experimentar aceder ao KUDU, terá apenas que adicionar o subdomínio scm depois do subdomínio definido [subdomínio definido].scm.azurewebsites.net
.
Com o Kudu em Linux consegue ver informação do sistema, variáveis de ambiente e parâmetros, executar comandos numa consola Bash. Apesar de permitir o acesso SSH normalmente este encontra-se bloqueado devido à segurança porque consegue fazer qualquer alteração na máquina até apagar definições que o próprio Azure define o que pode danificar a máquina virtual.
Está concluído o deployment da aplicação em Docker para Web App em Linux.
Azure Web App Roadmap
As funcionalidades dos serviços no Azure estão sempre em constante atualização e o Azure Web App em Linux não é exceção. No GitHub pode consultar as últimas notas de lançamento em https://aka.ms/linux-release-notes. Na página do Azure consegue consultar outras novidades em https://azure.microsoft.com/en-us/updates/?product=web-sites. Por exemplo desde de maio de 2017 está disponível ao público em geral uma aplicação para Android e iPhone que permite consultar estados, métricas, notificações e alertas dos serviços que estão a ser utilizado na sua subscrição. Esta aplicação ainda se encontra em desenvolvimento.
Quando é devemos escolher o Web App em Windows ou Linux?
Depende dos requisitos da aplicação, se a carga de trabalho funciona muito bem em Linux então deve escolher Linux. Se a aplicação foi desenvolvida em Java então deve escolher Windows por enquanto ainda não é possível usar Java em Linux. Se pretende testar a aplicação em desenvolvimento sem custos apenas o Windows tem o plano de alojamento Free Tier.
É preciso analisar muito bem a aplicação, necessidades e funcionalidades. No entanto pode testar a aplicação durante 30 minutos gratuitos.
Como testar Azure Web App Linux gratuitamente
Para finalizar se pretende testar o Azure Web App Linux gratuitamente durante 30 minutos sem nenhum custo a oferta está disponível em https://aka.ms/tryappservice, apenas tem de escolher Web App e a linguagem de programação. Também pode experimentar o Web App para Containers apenas tem que providenciar a imagem Docker por exemplo rramoscabral/revista-programar
e utilizar até a duração expirar. Ambos vão solicitar uma conta Microsoft existente. Recomendo que não abuse desta opção porque serão contactados pela equipa de vendas do Azure.