Friday, March 15, 2019

Fátima prepara manobra que garante adicional de férias e pagamento de 13º salários para deputados


O ultrajante Projeto de Lei de iniciativa da Mesa Diretora da Assembleia Legislativa do RN, que garante adicional de férias e pagamento de 13º salários para os deputados do Rio Grande do Norte, retroativo a 2015, está na mesa da Governadora Fátima Bezerra (PT).

A ilustre Governadora tem até o dia 20 de março (15 dias úteis desde a data de seu envio pela ALRN) para “canetar” o PL, sancionando ou vetando.

Corre a boca miúda que ela deverá sair pela tangente e não fará nem uma coisa nem outra.

Daí…

O PL voltaria para a ALRN para promulgação direta, sem que seja mais necessário sanção.

O desfecho sendo esse, o de sair pela tangente, a intenção de Fátima é não se comprometer com a pauta, que é vergonhosa e descabida. Ela quer sair ilesa dessa.

Mas…

Se ela fizer cara de paisagem e deixar que o PL retorne para a ALRN para promulgação, seria a mesma coisa de estar sancionando. Neste caso, a omissão não deixa de ser uma permissão. E o ônus seria somente do Legislativo e não do Executivo.

Vale lembrar que o Projeto de Lei, de autoria da Mesa Diretora da ALRN, foi aprovado no mesmo dia em que os deputados reconheceram a calamidade financeira do estado através de outra Lei.

Os sindicatos pressionam a governadora para vetar o PL, que mesmo ela sendo “coleguinha” deles, pretende cruzar os braços para deixar o presidente da ALRN promulgar e arcar sozinho com as responsabilidades do ato vergonhoso.

O SindSaúde é um dos que mais questionam a Lei, estando os servidores em greve pelos atrasos de seus salários.

Fátima prepara manobra que garante adicional de férias e pagamento de 13º salários para deputados publicado primeiro em: http://talesvale.blogspot.com

Wednesday, March 13, 2019

Do Waterfall ao DevSecOps

Desenvolver um software do zero e colocá-lo em produção é um grande desafio para muitas organizações. Principalmente se for um software complexo e que atenda a diversas áreas de negócios distintas.

Há algumas décadas esse problema não existia, pois bastava apenas entender o que precisava ser desenvolvido, escrever o código e então colocar em produção.

Naquela época a tecnologia era bem limitada, os problemas eram mais simples – poucas pessoas participavam do processo e o ritmo de evolução das necessidades e problemas não era frenético como é hoje em dia. Era muito mais fácil de se organizar e sair do outro lado.

Mas conforme o mundo foi evoluindo, a tecnologia, os problemas e as necessidades das organizações também foram, exigindo assim que as equipes de desenvolvimento de software buscassem por maneiras mais organizadas e padronizadas de realizar o seu trabalho, que estava se tornando cada vez mais complexo.

Waterfall

Etapas do modelo Waterfall

Etapas do modelo Waterfall

 

Em 1970, Winston Royce escreveu um artigo chamado Gerenciando o Desenvolvimento de Grandes Sistemas de Softwares, ou, originalmente, Managing the Development of Large Software Systems. Neste artigo, Royce descreve um processo para o gerenciamento de projetos de software de larga escala, que ficou conhecido mundialmente como Waterfall.

O autor cita que para desenvolver qualquer software, independente de seu tamanho e complexidade, existem duas atividades que sempre serão necessárias: análise e codificação.

Entretanto, com base em sua própria experiência profissional, ele afirma que no caso de softwares de larga escala que serão operados por outras pessoas, apenas essas duas atividades não são suficientes, sendo necessário adicionar ao processo mais algumas outras, para assim diminuir os riscos.

E com isso ele descreve um processo mais completo, que seria mais ideal ao lidar com projetos de software de larga escala, composto por sete etapas: Requisitos de Sistema -> Requisitos de Software -> Analise -> Design de Código -> Codificação -> Testes -> Operação.

Royce enfatiza que esse modelo é arriscado e sujeito a falhas, por conta de não haver feedback entre as etapas e também por conta dos testes ficarem para o final do ciclo, sendo que quaisquer ajustes necessários podem afetar todas as etapas anteriores, algo que certamente causaria um impacto no orçamento e no prazo.

O autor chega a citar que o ideal seria um modelo mais interativo, possibilitando com isso alguns pontos de feedback para eventuais ajustes necessários, mas poucas equipes deram atenção a esse detalhe.

Modelo Waterfall com ciclos de feedback

Modelo Waterfall com ciclos de feedback

 

Muitas equipes no mundo inteiro adotaram o Waterfall como processo para desenvolvimento de software e após algum tempo alguns problemas foram surgindo.

Dentre os diversos problemas enfrentados pelas equipes de desenvolvimento de software que utilizavam o Waterfall, podemos destacar um: ciclo de release muito longo.

No modelo Waterfall a entrega é realizada apenas ao final do processo, quando o software estiver totalmente finalizado. O problema é que um software pode levar meses, ou até anos, para ser desenvolvido como um todo.

E durante todo esse tempo, infelizmente, o mundo não vai ficar “congelado”, esperando o software ficar pronto. O mundo continua a girar, evoluindo e mudando mais rapidamente a cada dia, sendo que isso vai exigir que as organizações se adaptem na mesma velocidade, para não ficarem para trás.

Por conta disso, o modelo Waterfall acabou caindo em desuso pelas equipes de desenvolvimento de software, que passaram a buscar por outros modelos mais leves e que favoreciam ciclos mais curtos.

Para resolver esses problemas, diversos outros modelos alternativos ao Waterfall foram surgindo com o tempo, como o modelo Espiral, o RAD e o RUP, mas o que se destacou e vem sendo utilizado pela grande maioria das equipes é o modelo que ficou conhecido como Agile.

Agile

Agile Manifesto

Agile Manifesto

 

Diversos processos leves foram sendo criados na década de 90, como o Scrum, XP, FDD e Crystal, sendo que seus criadores possuíam ideais e valores em comum, que acreditavam ser importantes no processo de desenvolvimento de software.

Em fevereiro de 2001, dezessete dessas pessoas se reuniram para discutir e chegar a um consenso sobre os valores e princípios que elas acreditavam serem mais adequados ao se trabalhar com desenvolvimento de software, bem diferente do que estava sendo feito no mercado, que focava muito em processos pesados e orientados a documentação.

Nasce assim o Agile Manifesto, considerado como um marco histórico pela indústria de desenvolvimento de software.

Agile na verdade é um conjunto de valores e princípios, que quando aplicados por uma equipe de desenvolvimento de software, e também pela organização como um todo, favorece o processo de desenvolvimento e entrega de software que gera valor para sua organização.

Dentre as metodologias e frameworks que seguem o manifesto, as principais e mais adotadas hoje em dia são: XP, Scrum e Kanban.

Ao utilizar tais metodologias, as equipes de desenvolvimento de software acabam reduzindo bastante os seus ciclos de release, para conseguir entregar valor desde cedo e de maneira contínua, para obter mais feedbacks e também para diminuir os riscos.

Além disso, é comum que a comunicação e a colaboração entre as pessoas melhore bastante, fazendo com que elas se organizem como um time, com transparência, colaboração e metas compartilhadas, não mais se dividindo em equipes isoladas.

Esses times costumam ser auto-organizados e cross-funcionais, compostos por pessoas com diferentes conhecimentos e habilidades, para que assim consigam executar o processo do inicio ao fim, de maneira quase totalmente independente.

Porém, um problema que é comum em quase todas as organizações é que existe uma equipe responsável pela parte de infra, também chamada de operações, que geralmente trabalha de maneira isolada do time de desenvolvimento, gerando com isso alguns conflitos.

Imagem representando o atrito entre as equipes de Dev e de Ops

Dev vs. Ops

 

O problema é que de um lado está o time de desenvolvimento, trabalhando de maneira ágil, buscando autonomia e necessitando de ciclos de release cada vez mais curtos, mas do outro lado está o time de operações, que possui outro ritmo de trabalho e processos que exigem mais controle, governança e estabilidade.

São duas áreas com ideias, necessidades e processos distintos, que às vezes podem entrar em conflito, gerando um atrito entre os times de desenvolvimento e operações.

Imagem representando o conflito entre os processos de desenvolvimento e operações

Conflito entre os processos de desenvolvimento e operações

 

Para evitar problemas, essas duas áreas devem trabalhar juntas, de maneira colaborativa e com objetivos comuns, sempre buscando por ferramentas, processos e práticas que possam simplificar o trabalho, gerando com isso melhores resultados para a organização como um todo.

Baseado nessas ideias, nasce assim um novo movimento chamado DevOps.

Imagem representando a união entre Dev e Ops

DevOps

DevOps

DevOps é a união entre os times de desenvolvimento e operações, que combina suas filosofias, práticas, processos e ferramentas com o objetivo de melhorar a colaboração entre essas duas áreas, para com isso ajudar a organização a conseguir entregar software de maneira mais ágil.

Ao invés desses times trabalharem isoladamente, eles se unem de maneira que consigam trabalhar juntos por todo o ciclo de desenvolvimento do software, desde o desenvolvimento e testes, até o deploy e operação dele.

Ao trabalhar dessa maneira, o time de desenvolvimento passa a ter um melhor entendimento sobre os processos, dificuldades e problemas enfrentados pelo time de operações, e vice-versa. Um dos focos passa a ser a busca por maneiras de simplificar os processos, com o objetivo de aumentar a agilidade.

Tópicos como integração/entrega contínua, monitoramento, logs e escalabilidade acabam ganhando uma maior atenção, e a utilização de ferramentas e automatização acaba sendo essencial para isso.

Exemplo de ferramentas utilizadas no modelo DevOps

Exemplo de ferramentas utilizadas por times DevOps

 

Não há dúvidas de que o modelo DevOps auxilia muito os times de desenvolvimento e operações a serem mais ágeis, entregando software em ciclos mais curtos, evitando atritos e problemas, e promovendo asssim uma melhor colaboração.

Entretanto, os problemas ainda não acabaram, pois existe uma outra área que ficou de lado, sendo que ela também é muito importante, além de também possuir seus próprios valores, práticas e processos: a área de segurança.

É muito comum que a área de segurança seja formada por um time que trabalha de maneira isolada dos times de desenvolvimento e operações, algo que certamente pode gerar problemas e atritos.

Nesse tipo de cenário, o time de segurança acaba atuando como um “porteiro”, onde ao final de cada ciclo de release vai verificar se a entrega pode ou não ser liberada, baseado nas verificações de segurança que serão realizadas.

Isso pode impactar na tão desejada agilidade que o time DevOps deseja alcançar, além de também fazer com que o time de segurança seja visto como uma barreira para a agilidade e como responsável por ter que ficar arrumando a “bagunça” deixada pelo time DevOps.

Imagem representando o time de segurança limpando a bagunça deixada pelo time de DevOps

Sensação do time de segurança em relação ao time DevOps

 

E foi essa a motivação para o surgimento do movimento chamado DevSecOps, cujo objetivo é integrar também o time de segurança aos times de desenvolvimento e operações.

DevSecOps

Assim como o DevOps, o DevSecOps também é um modelo que tem como objetivo a integração entre os diferentes times envolvidos no processo de desenvolvimento de softwares.

No caso do DevSecOps, a ideia é integrar o time de segurança ao time DevOps, evitando assim que o tema de segurança seja tratado apenas ao final do processo e de maneira isolada.

O “coração” do DevSecOps é construir a ideia de que segurança é responsabilidade de todos.

Segurança não deve ser um tópico discutido e tratado apenas ao final do ciclo de cada release e apenas pelo time de segurança, mas também deveria ser discutido durante todo o ciclo de desenvolvimento, desde as discussões sobre as funcionalidades, até a fase de deploy e operação.

Com isso, os times de desenvolvimento e operações passam a ter um melhor entendimento sobre o assunto e sobre os processos, práticas e dificuldades enfrentadas pelo time de segurança.

Certamente isso vai melhorar a agilidade do time de desenvolvimento, que passará a tratar do tópico de segurança antes e durante o desenvolvimento, evitando assim implementar funcionalidades com diversas vulnerabilidades que precisariam ser corrigidas posteriormente.

Um time DevSecOps também deve buscar por soluções e ferramentas que facilitem e automatizem as tarefas relacionadas à segurança, para simplificar os processos dessa área e evitar que ela se torne um gargalo no ciclo de desenvolvimento ágil.

Novos tópicos surgirão e precisarão de atenção, dentre eles: desenvolvimento seguro, análise de código, pentesting, detecção de ataques e logs de segurança.

Um time que trabalha utilizando o modelo DevSecOps, integrando as áreas de desenvolvimento, operações e segurança, com suas práticas, processos e ferramentas, sempre buscando por melhorias e simplicidade, certamente consegue ser mais ágil e ajudar a sua organização a alcançar melhores resultados, tornando-a mais competitiva no mercado.

E você, trabalha em um time que segue o modelo DevSecOps? Deixe um comentário contando sua experiência e aprendizado nessa jornada. 🙂

The post Do Waterfall ao DevSecOps appeared first on Blog da Caelum: desenvolvimento, web, mobile, UX e Scrum.


Do Waterfall ao DevSecOps publicado primeiro em: http://blog.caelum.com.br

Tuesday, March 12, 2019

O mínimo que você deve saber de Java 8

Sem dúvida as mudanças do Java 8 foram as mais profundas na plataforma depois de muito tempo. Aproveitamos para atualizar esse post para também linkar as mudanças do Java 9 e as do Java 10 que, mesmo menores, também são interessantes. Na Caelum trabalhamos por bastante tempo com as versões beta do Java, por isso conseguimos manter o nosso curso de Java e orientação a objetos atualizado, com uma seção de classe anônimas e lambdas, além de seu uso em outras APIs, como as Collections e Streams que veremos aqui. Também escrevemos um livro de Java 8 e a na nossa carreira Java Júnior da plataforma Alura. São muitas as novidades e sumarizamos aqui as principais modificações na linguagem e na API. Vamos direto a um código para enxergar os três principais novos conceitos da linguagem.

Ordenando coleções

Dada uma lista de Strings:

List<String> palavras = Arrays.asList("rodrigo", "paulo", "caelum"); 

Queremos ordená-la de acordo com o tamanho de cada String. Para isso criamos um Comparator através de uma classe anônima, como já estamos habituados:

Comparator<String> comparador = new Comparator<>() {
    public int compare(String s1, String s2) {
        return Integer.compare(s1.length(), s2.length());
    }
}

E em seguida utilizamos o Collections.sort para ordenar a lista com o critério de comparação definido:

Collections.sort(palavras, comparador);

A primeira novidade do Java 8 é que podemos fazer essa chamada desta forma:

palavras.sort(comparador);

Sim, há um novo método em java.util.List, que é o sort. Por que não fizeram antes? Pois adicionar métodos novos em uma interface pode quebrar muito código já existente em quem implementa List. E o que tem de diferente no Java 8?

Conhecendo os default methods

Abrindo o código da interface List podemos ver como é o sort:

default void sort(Comparator<? super E> c) {
        Collections.sort(this, c);
}

Podemos ter métodos concretos em interfaces a partir do Java 8! Basta utilizar o modificador default. Eles serão ‘herdados’ por todos que implementarem essa interface. Esse recurso, chamado default method, permite evoluir uma interface sem quebrar compatibilidade. É uma técnica já bem conhecida no C#, Scala e outras linguagens. Há muitos outros métodos default que foram adicionados a API de coleções, como Collection.removeIf, Map.getOrDefault e até mesmo no Comparator, como o Comparator.reversed, que devolve um novo comparador que ordena ao contrário.

Expressão Lambda

Além de ficar mais prático de escrever o código sem o uso direto da Collections, podemos também criar o Comparator de maneira bem mais enxuta sem utilizar a sintaxe de classe anônima:

Comparator<String> comparador = (s1, s2) -> {
        return Integer.compare(s1.length(), s2.length());
};

Essa é a sintaxe do Lambda no Java 8. Ela pode ser utilizada com qualquer interface funcional. Uma interface funcional é aquela que possui apenas um método abstrato (semanticamente falando pode haver diferenças). Dessa forma o compilador consegue inferir qual método está sendo implementado nessas linhas. Diferente da geração de classes em tempo de compilação, como é feito para as classes anônimas, o lambda do Java 8 utiliza MethodHandles e o invokedynamic.

Reduzindo mais ainda o código

O código pode ficar ainda mais enxuto. Como há apenas uma instrução dentro desse lambda, não precisamos nem do return, nem do uso das chaves:

Comparator<String> comparador = (s1, s2) -> Integer.compare(s1.length(), s2.length());

Ou ainda passar tudo isso diretamente como argumento para o sort:

palavras.sort((s1, s2) -> Integer.compare(s1.length(), s2.length()));

Você pode utizar o lambda em qualquer interface antiga que seja considerada funcional:

new Thread(() -> System.out.println("thread nova rodando")).start();

Como um dos construtores de Thread recebe uma interface funcional, o compilador sabe que deve tentar converter esse lambda para um Runnable! É sempre necessário o envolvimento de uma interface funcional. O seguinte código não compila:

Object o = () -> System.out.println("thread nova rodando");

Compilaria se tivéssemos declarado como um Runnable. Muitos dos novos métodos inseridos nas interfaces das collections recebem um argumento que é uma interface funcional, como o Collection.forEach:

palavras.forEach(s -> System.out.println(s));

O forEach recebe um Consumer<T> como argumento, que é uma das muitas novas interfaces do pacote java.util.function. Ele tem apenas um método, o accept, que recebe T e não devolve nada. Como o método recebe apenas um argumento, repare que não foi necessário declarar s entre parenteses no lambda s -> System.out.println(s).

Ordenando as coleções com a expressão lambda

Podemos fazer a nossa ordenação ficar ainda mais sucinta. Interfaces podem ter métodos default estáticos, agrupando melhor métodos utilitários. O Comparator possui o factory method comparing. Ele recebe uma Function que, no nosso caso, recebe uma String e devolve algo que queiramos usar como critério de comparação. Vamos passar um lambda que, dado a String, devolve seu length:

palavras.sort(Comparator.comparing(s -> s.length());

Escrevendo a expressão lambda com method reference

É muito comum um lambda simplesmente invocar um único método. Um lambda também pode ser escrito como forma de method reference. Em vez de s -> s.length() fazemos simplesmente String::length, ficando implícito que queremos, para a String passada como argumento, que o length seja invocado:

palavras.sort(Comparator.comparing(String::length);

Isso é possível pois as duas linhas a seguir são equivalentes:

Function<String, Integer> function = s -> s.length();
Function<String, Integer> function = String::length;

A segunda é até mais fácil para o compilador inferir, já que algumas vezes pode haver ambiguidade e a necessidade de tipar os argumentos do lambda, como (String s) -> s.length(). E você poderia passar essa function como argumento para o Comparator.comparing, mas obviamente é desnecessário, pois podemos passar diretamente o lambda, como fizemos. Para aplicar um filtro nessa lista, como por exemplo retornar apenas as palavras com menos de 6 caracteres, gostaríamos de fazer algo como palavras.filter(...). Porém o método filter não foi adicionado em nossa API de Collection! Existem várias razões para isso, como não querer misturar métodos sem efeitos colaterais em coleções mutáveis, além de evitar deixar as coleções muito poluídas com tantas novas funcionalidades.

Aumentando o poder com Stream

Para fazer essa e outras transformações comuns em nossas coleções, contamos agora com uma nova API, o Stream. Para criar um Stream com os elementos de nossa lista só precisamos chamar o método defaut .stream() presente na interface Collection (e em outros lugares!). Fazemos palavras.stream() para ter um Stream<string>. Essa API traz uma forma mais funcional de trabalhar com nossas coleções. Ela possui diversos métodos, como o filter, map e reduce, que recebem uma interface funcional como parâmetro, nos possibilitando tirar proveito dos novos recursos de lambda e method reference.

Filtrando coleções

Para filtrar as Strings com menos de 6 caracteres em nossa lista podemos fazer:

palavras.stream()
        .filter(s -> s.length() < 6)
        .forEach(System.out::println);

O método filter recebe a interface funcional Predicate como parâmetro. Essa interface possui apenas o método test que recebe T e retorna um boolean. Você nem precisava saber disso! Com o lambda, os nomes das interfaces funcionais perdem um pouco a importância e tornam o código mais simples de ler.

Utilizando o map

Outro método que será muito utiizado em nosso dia a dia é o map, podemos e devemos utilizá-lo quando precisamos aplicar transformações em nossa lista sem a necessidade de variáveis intermediárias. Para mapear as palavras pelo seu tamanho (length), podemos fazer:

Stream<Integer> stream = palavras.stream().map(String::length);

Porém recebemos um Stream<Integer> como retorno. Para evitar esse boxing desnecessário dos tipos primitivos a API de Streams possui implementações equivalentes ao %%Stream%% para eles: IntStream, LongStream, e DoubleStream. Para utilizar um IntStream neste nosso caso, podemos substituir a chamada do método map por mapToInt:

IntStream intStream = palavras.stream().mapToInt(String::length);

Em outros locais é possível evitar o boxing e unboxing. Há em Comparator o método comparingInt que recebe um IntFunction. Podemos fazer aquele sort do inicio do artigo com palavras.sort(Comparator.comparingInt(String::length)).

Mais sobre o Stream

As implementações de Stream para os tipos primitivos possuem diversos métodos para auxiliar na manipulação de seus valores, como é o caso do sum, min, max, count, average, entre diversos outros. O interessante desse ultimo é que o seu retorno será um Optional, outra importante introdução do java 8:

Optional<Double> media = palavras.stream()
        .mapToInt(String::length)
        .average();

System.out.println(media.orElse(0));

Note que o OptionalDouble é a implementação de Optional para esse tipo primitivo, essa estratégia é utilizada em grande parte das novas interfaces! Voltando ao nosso filtro, vimos que ao fazer palavras.stream().filter(s -> s.length() < 6) isso nos retornou um Stream<string>. Para que o retorno seja uma List<string> contamos com o método collect(). Esse método espera receber a interface funcional Collector como parâmetro. Para simplificar nosso trabalho, já existem diversos factory methods de collectors prontos na classe Collectors, como é o caso do toList():

List<String> resultado = palavras.stream()
        .filter(s -> s.length() < 6)
        .collect(Collectors.toList());

Ufa! Esse é um pequeno resumo essencial do que entrou nessa versão. Se você tiver interesse, pode ver como era a sintaxe proposta para o Java 8 em 2011 nesse antigo post. Das novidades que ficaram de fora do post, temos o suporte a múltiplas anotações do mesmo tipo, a API de java.time baseada no Joda Time, melhorias na inferência do generics e do operador diamante além de inúmeros ajustes nas APIs. Muitas features ficaram de fora, como collection literals e value objects. Você pode ver o que entrou e ficou de fora. Mas quem sabe isso tudo não aparece junto com a reificação do generics no Java 9?

The post O mínimo que você deve saber de Java 8 appeared first on Blog da Caelum: desenvolvimento, web, mobile, UX e Scrum.


O mínimo que você deve saber de Java 8 publicado primeiro em: http://blog.caelum.com.br

Monday, March 11, 2019

Como compartilhar seu localhost de forma simplificada com o Ngrok

Introdução

Olá, eu me chamo Mario Souto, trabalho como desenvolvedor e instrutor no Grupo Caelum Alura e nas horas vagas faço consultoria e algumas doideras.

Quando estou trabalhando em algum projeto normalmente trabalho com uma versão do código rodando na minha máquina para só depois mandar isso para produção. Em alguns casos não possuo um servidor de testes antes de ir para prod, logo eu preciso garantir que na minha máquina está funcionando tudo certinho e depois é ver como ta em produção.

Para facilitar o processo de validar com o cliente eu comecei a utilizar uma ferramenta bem bacana chamada Ngrok que me permite compartilhar meu localhost com qualquer pessoa \o

Preparando o ambiente

Para começarmos, primeiramente vamos precisar instalar o ngrok, para fazer isso devemos ir até o site da ferramenta na área de download (https://ngrok.com/download)

Site do ngrok na área de download

Vale ressaltar que no windows, é baixado um .exe que você irá precisar sempre que for utilizar o ngrok.

Testando na prática

Agora que temos o ngrok instalado, vou pegar um exemplo de um site em wordpress para trabalharmos. O freela que estou desenvolvendo está rodando em: http://localhost:9080/

Site de exemplo aberto

Para poder permitir que o cliente visualize o que eu fiz até agora, basta ir até o terminal (no caso do windows, rodar o executável baixado do site) e digitar **ngrok http 9080**

Terminal com o ngrok rodando

Agora, basta acessar o endereço no navegador e…

URL do Ngrok aberta

Nada apareceu 🙁

Bom isso acontece porque o WordPress tem uma URL padrão que é definida no banco de dados. Para tudo funcionar com o ngrok, devemos mudar essa URL manualmente no arquivo wp-config.php


define( "WP_HOME", "http://61dc494a.ngrok.io/" );

define( "WP_SITEURL", "http://61dc494a.ngrok.io/" );

Ou você pode pegar automaticamente a URL que estiver acessando (lembre-se de alterar o https caso queira liberar o acesso como HTTPs):


define( "WP_HOME', "http://" .$_SERVER["HTTP_HOST"]. "/" );

define( "WP_SITEURL", "http://" .$_SERVER["HTTP_HOST"]. "/" );

Site abrindo publicamente através do Ngrok

Com isso conseguimos liberar nosso site para o cliente visualizar de forma simples e para cancelar a URL basta apertar Ctrl + C no processo rodando do ngrok no terminal 🙂

Um outro uso bem bacana do ngrok é conseguir testar o comportamento de uma PWA que depende de uma conexão HTTPs sem precisar publicá-la.

Espero que tenha gostado do post, em breve trarei mais dicas, não deixe de me seguir nas minhas redes sociais e acompanhar meus outros posts em meu site pessoal https://mariosouto.com até mais \o

The post Como compartilhar seu localhost de forma simplificada com o Ngrok appeared first on Blog da Caelum: desenvolvimento, web, mobile, UX e Scrum.


Como compartilhar seu localhost de forma simplificada com o Ngrok publicado primeiro em: http://blog.caelum.com.br