R e shiny na nuvem
Introdução
Neste tutorial, irei mostrar o caminho para instalar o R, o RStudio-server e o shiny-server de modo que você possa, não somente trabalhar com o RStudio do navegador, mas também publicar seus aplicativos shiny e nunca mais ter de contar com as 25 horas mensais do shinyapps.io.
Este tutorial é fruto de mais de três anos de experiência instalando dezenas de vezes o R, o Rstudio e o Shiny em máquinas virtuais. Obviamente, ele não está isento de erros, mas foi testado múltiplas vezes. Por outro lado, sugestões para aprimoramento são sempre bem-vindas.
Máquina virtual
Primeiramente, você deve criar uma máquina virtual. Para quem está começando, eu recomendo o Contabo. Por menos de 10 dólares mensais, você tem uma máquina rodando e com um ip público à sua disposição. Nesse tutorial, eu irei pressupor que você já criou uma máquina virtual (instância no AWS ou no GCP) ou VM no Contabo. Também estou assumindo que esta máquina foi criada com o Ubuntu 22.04 ou superior. Para criar uma máquina virtual (VM na sigla em inglês), você só precisa criar uma conta num desses serviços e selecionar a configuração que caiba no seu bolso.
Instalação do R
Os passos seguintes orientam a instalação atualizável do R no Ubuntu-server, ou seja, se você seguir esses passos, cada vez que der apt update
e apt -y upgrade
, a versão mais recente do R disponível para Ubuntu será instalada.
Assegure-se de que o lsb-release está instalado:
O lsb-release serve apenas para mostrar a versão da distribuição linux instalada. Se você já sabe a versão, esse passo é desnecessário. Eu uso para ajustar a url do R a fim de informar o sistema onde buscar a versão mais recente do R.
sudo apt update && sudo apt -y install lsb-release && sudo apt-get clean all
Adicione a chave GPG
A instalação da chave GPG preserva uma comunicação segura entre o cliente e o servidor. Ela é importante para assegurar a integridade dos dados e a autenticidade da fonte. Ou seja, os dados são criptografados antes de serem baixados por seu computador e decriptografados pela chave previamente instalada. Isso reduz significativamente as chances de que um terceiro intervenha no processo de transmissão e instale algo nocivo na sua máquina.
wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | sudo gpg --dearmor -o /usr/share/keyrings/r-project.gpg
Adicione o endereço do repositório do cran ao sources.list.d:
Aqui eu interpolo o resultado do lsb-release com a url a fim de adicioná-la adicioná-la ao sources.list.d, que nada mais é do que uma lista consultada pelo gerenciador do pacotes, o apt, a fim de saber o repositório de onde obter a versão mais recente do R ou de qualquer outro programa.
echo "deb [signed-by=/usr/share/keyrings/r-project.gpg] https://cloud.r-project.org/bin/linux/ubuntu `lsb_release -cs`-cran40/" | sudo tee -a /etc/apt/sources.list.d/r-project.list
Instalar o R
Enfim, podemos instalar R, utilizando o gerenciador de pacotes APT.
sudo apt -y update
sudo apt -y install r-base r-base-dev
Instalação de pacotes com dependência em c/c++ no R.
Se você é também usuário de Windows ou MAC, seguramente uma das coisas que lhe incomoda no Linux é a necessidade de instalar as bibliotecas em C das quais os pacotes do R dependem. Por exemplo, para usar o pacote httr
, você precisa antes instalar as bibliotecas libssl-dev
e libcurl4-openssl-dev
. Isso nem sempre é agradável, principalmente quando você não sabe que existe essa dependência, aguarda um bom tempo para instalar o pacote R, para descobrir que não foi instalado porque falta instalar essa ou aquela lib em C.
Instalação do Java - opcional
Esse passo é opcional, mas há muitos pacotes do R que dependem de Java.
sudo apt-get install -y default-jre
sudo apt-get install -y default-jdk
Informar onde o R deve encontrar o Java.
Para que o rJava, o qual instalaremos em seguida, possa encontrar o Java, você deve rodar o seguinte comando.
sudo R CMD javareconf
Instalação do rJava
Agora podemos instalar o rJava diretamente do shell, sem necessidade de entrar na interação do R, por ora.
Rscript -e 'install.packages("rJava")'
Instalação do libpoppler - opcional
Se você optou por instalar o tesseract, seguramente irá querer instalar o libpoppler também. Por meio dele, você extrai textos mesmos de pdfs. Recordo que pdf é um mero contêiner. O conteúdo pode perfeitamente ser texto, imagem ou mesmo gráficos.
sudo apt-get install -y libpoppler-cpp-dev libcurl4-openssl-dev
O pacote do R que chama o poppler é o pdftools
:
Rscript -e 'install.packages("pdftools")'
Instalação do tesseract - opcional
Esse passo também é opcional. Se você acredita que irá fazer leituras de textos em imagens, inclusive aquelas contidas em pdf, o tesseract é necessário. Por meio dele, é possível realizar a leitura ótica dos textos contidos em imagens.
sudo apt -y install libtesseract-dev libleptonica-dev tesseract-ocr-eng tesseract-ocr-por
Depois disso, você pode instalar o pacote tesseract
do R.
Rscript -e 'install.packages("tesseract")'
Instalação do devtools, tidyverse e companhia
Se você trabalha com ciência de dados, o conjunto de pacotes incluídos no tidyverse é de suma importância. Além disso, para instalar pacotes em desenvolvimento, o pacote remotes é muito importante. Ademais, esses dois pacotes se encarregam de instalar outros igualmente importantes, como o xml2 e o httr.
Para instalá-los, antes devemos instalar algumas dependências.
sudo apt install libssl-dev libxml2-dev \
\
libfontconfig1-dev libharfbuzz-dev libfribidi-dev libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev
Rscript -e 'install.packages(c("remotes","tidyverse"))'
Instalação do rstudio-server
Estamos em condições de instalar o rstudio-server. Vá para a página de download o rstudio-server para Ubuntu, copie e rode a sequência de comandos de maneira similar à que está abaixo:
sudo apt-get install gdebi-core
wget https://download2.rstudio.org/server/trusty/amd64/rstudio-server-1.2.5033-amd64.deb
sudo gdebi rstudio-server-1.2.5033-amd64.deb
Se tudo correr bem, você terá o Rstudio-server instalado. Para verificar se ele está rodando, chame o comando a seguir.
sudo systemctl status rstudio-server
Por padrão, o Rstudio-server é acessado via porta 8787. Nós faremos uso dela mais adiante quando formos configurar o proxy reverso no nginx.
Instalando o Shiny-server
Seguiremos procedimento similar para instalar o shiny-server. O passo adicional é a instalação do shiny previamente à instalação do shiny-server.
Rscript -e 'install.packages("shiny")'
Vá para a página de download do shiny-server para Ubuntu, copie e rode os comandos conforme a seguir. Note que eu apenas deixo de instalar o gdebi, porque isso já foi feito quando baixamos o rstudio-server.
wget https://download3.rstudio.org/ubuntu-12.04/x86_64/shiny-server-1.5.5.872-amd64.deb
sudo gdebi shiny-server-1.5.5.872-amd64.deb
Para verificar se está tudo bem, rode o seguinte comando:
sudo systemctl status shiny-server
O shiny-server é acessado, por padrão, via porta 3838. Logo faremos uso dessa informação.
Mantendo uma biblioteca comum
Quando instalamos o Rstudio-server, bem como, o shiny-server, possivelmente queremos dar acesso a vários usuários. O próprio shiny-server roda com o usuário shiny. Se você quiser permitir que todos os usuários partilhem da mesma biblioteca de pacotes, você deve editar o arquivo /etc/R/Renviron e comentar (adicionar # ao início) a linha similar a esta:
#R_LIBS_USER=${R_LIBS_USER-'~/R/x86_64-pc-linux-gnu-library/4.0'}
Protegendo o acesso via proxy reverso
Se você pretende acessar o rstudio, bem como, publicar seus shinyapps via navegador, é necessário tomar uma série de medidas de proteção. Quando você instalou o rstudio-server e o shiny-server, eles passaram a ser disponibilizados via portas 8787 e 3838, respectivamente. Assim, se quiser trabalhar no rstudio, basta você digitar http://ip:8787. Igualmente, para acessar o shinyapp, você digita http://ip:3838/meushinyapp.
Acontece que, deixar essas portas abertas torna sua máquina vulnerável a ataques. Além disso, as informações são transferidas sem qualquer criptografia. A seguir, mostraremos como instalar o certificado SSL/TSL, para que os dados em trânsito estejam criptografados e, melhor, como proteger essas portas via proxy reverso. O proxy reverso serve para, dentre outras tantas funções, distribuir as requisições para o local adequado.
Para facilitar a compreensão, pense na sua máquina virtual como uma dessas vilinhas com várias casas e que, uma dessas casas é o rstudio-server e outra o shiny-server. Os visitantes regularmente se dirigem às casas. Após alguns assaltos, os moradores decidem colocar um portão para acesso à vila, uma portaria e contratar um porteiro para controlar as saídas e entradas.
Pense no proxy reverso como a função do porteiro do condomínio, que recebe as encomendas direcionadas a cada casa e as distribui. O porteiro seria como o web-server. O web-server, como o próprio nome sugere, disponibiliza o conteúdo da sua máquina para a web. O rstudio-server e o shiny-server já são capazes de servir requisições sem carecer de um proxy, ou seja, um intermediário. No entanto, sem um proxy,i.e., o porteiro, eles ficam mais vulneráveis. O implementador de proxy reverso mais popular atualmente é o nginx (pronuncia-se engine-x), que é um o web-server, assim como o apache.
Outra vantagem de usar o nginx é que ele pode ser configurado para servir por meio de uma única porta, a porta 443, que geralmente é usada para transmissão de dados criptografados. A porta 443 funcionaria como o portão do condomínio. Ela possui algumas seguranças adicionais pois é única que ficaria exposta ao público. No entanto, como você já deve ter imaginado, ela não oferece absoluta proteção, apenas adiciona uma camada importante de segurança. Ela é acessada por meio do protocolo https.
Quando alguém escreve o seu endereço no navegador, os dados são transmitidos seguindo as regras desse protocolo, ou do http, cuja principal diferença é que este último não inclui a criptografia. Além disso, a transmissão por http se dá via porta 80. Por essa razão, esta porta deve também ficar aberta. No entanto, ao configurarmos a criptografia, esta orientará o nginx a redirecionar as tentativas de acesso por http para https.
A criptografia pode ser configurada por meio do programa openssl e certificada por várias entidades. Nós usaremos o Let’s encrypt, porque oferece esse serviço gratuitamente.
Uma outra porta que deve estar aberta é a porta para acesso remoto à VM. Geralmente isso fica sob responsabilidade da porta 22. Para acessá-la, usa-se o protocolo ssh, o qual dá acesso ao servidor por meio de senha ou via par de chaves criptografadas.
Dito isso, vamos instalar o nginx e proceder à configuração do SSL.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install nginx
Ao ser instalado, o nginx cria alguns arquivos de configuração. O principal deles é o /etc/nginx/nginx.conf
. Este arquivo chama outros localizados em subpastas do mesmo diretório /etc/nginx
. Nós iremos editar este e um outro, o /etc/nginx/sites-available
, a fim de configurar o proxy reverso para o rstudio-server e o shiny-server.
Firewall
Hora de habilitar o firewall para permitir acesso apenas ao nginx, portas 443 e 80 e ao acesso remoto via ssh. Para tanto, certifique-se de que você tem instalado o ufw
:
apt install ufw
Em seguida, autorize a porta ssh. Esse passo é fundamental, do contrário, ao habilitar o firewall, você perderá acesso remoto à VM.
ufw allow ssh
Agora podemos habilitar o firewall.
ufw enable
Por fim, autorize o nginx-full, ou seja, as portas 443 e 80.
ufw allow 'Nginx Full'
Se você tentar acessar o rstudio ou o shiny, não será possível porque as portas 3838 e 8787 têm seu acesso negado pelo firewall. Vamos emitir o certificado SSL. O certbot cuida de todo o processo. No entanto, o certificado SSL só pode ser emitido para um domínio. Por essa razão, antes de proceder aos passos seguintes, você deve obter um domínio e apontá-lo para o ip público da sua VM.
Configurando o SSL
Para adquirir o certificado ssl, iremos instalar o certbot
, o qual automatiza o processo.
apt -y install python3-certbot-nginx
O Let’s Encrypt não emite certificado para IP, somente para domínio. Se você não possui um domínio, você pode adquirir um por meio das tantas empresas denominadas registrars. Particularmente, eu recomendo o registro.br. Depois disso, direcione o domínio criado para serviço na nuvem que você contratou sua VM, ou seja o DNS, que ficará responsável por mapear o domínio para o ip da sua máquina. Se foi o Digital Ocean, você obtêm as orientações aqui.
Além disso, você tem de apontar o domínio para o droplet ou instância. Geralmente, no painel de controle do serviço onde você adquiriu a máquina, existe uma opção para apontar para o ip. Ainda, se for o Digital Ocean, você pode fazer isso por meio da opção networking. Selecione as opções A e AAAA para apontar o domínio para o ipv4 e o ipv6 respectivamente.
Feito isso, abra o seguinte arquivo com seu editor preferido. No caso, usarei o vim.
sudo vim /etc/nginx/sites-available/default
Procure a seguinte linha e substitua o sublinhado do server name:
server_name _;
pelo domínio:
server_name dominio.com.br;
Naturalmente, substitua o “domínio.com.br” pelo seu domínio.
Solicitar a certificação
Somente agora, estamos em condições de solicitar a certificação.
certbot --nginx -d dominio.com.br
Responda às perguntas solicitadas durante o processo de certificação e, pronto, o certificado será emitido e os arquivos de configuração do nginx serão propriamente alterados para contemplar a criptografia na transmissão de dados.
Proxy reverso
Estamos em condições de adicionar o rstudio-server e o shiny-server ao nginx para que este redirecione as requisições às respectivas portas. Abra o arquivo abaixo.
sudo vim /etc/nginx/sites-available/default
Isso deve ser adicionado em qualquer parte abaixo do html.index…
location /rstudio/ {
proxy_pass http://127.0.0.1:8787/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /shiny/ {
rewrite ^/shiny/(.*)$ /$1 break;
proxy_pass http://127.0.0.1:3838/;
proxy_redirect / $scheme://$http_host/shiny/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
proxy_buffering off;
}
location ~ /.well-known {
allow all;
}
Além disso, para que o shiny-server funcione, você tem de adicionar a seguinte diretiva no arquivo /etc/nginx/nginx.conf
, dentro da diretiva http {…}
http {
...
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
}
O Rstudio permite que você faça upload de arquivos ou pastas zipadas por meio da aba upload. No entanto, o nginx limita o tamanho dos uploads a 1MB. Para aumentar, acrescente a seguinte diretiva no arquivo /etc/nginx/nginx.conf
, também dentro da diretiva http {…}
http {
...
client_max_body_size 100M;
}
Verifique se não há erro na configuração:
nginx -t
Se tudo correr bem, você receberá uma mensagem assim:
configuration file /etc/nginx/nginx.conf test is successful
Recarregue o nginx para habilitar a edição:
sudo systemctl reload nginx
Segurança extra
Se quiser adicionar uma camada se segurança, configure o parâmetro de criptografia para 2048 bits em vez do padrão 1024.
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Gerenciamento de usuários
Irei criar um usuário que acessará o rstudio-server (você pode criar quantos quiser). Além disso, eu recomendo você criar um grupo e adicionar todos os usuários que usarão o rstudio-server, inclusive o usuário shiny, o qual foi criado quando você instalou o shiny-server, a este grupo. Depois disso, torne esse grupo o proprietário do diretório onde serão instalados o pacotes do R. Assim, você terá um diretório único com os pacotes do R para todos os usuários, de modo a evitar múltiplas bibliotecas.
Além disso, sugiro tornar esse grupo o proprietário da pasta onde se encontram os aplicativos shiny.
adduser jose
Após criar uma senha para o usuário. Crie o grupo:
addgroup usuarios
Adiciona usuário ao grupo
O código abaixo adiciono o usuário recém criado ao grupo usuarios e torna o grupo proprietário, com poderes de escrita e leitura à biblioteca de pacotes R.
sudo usermod -a -G usuarios jose
sudo chown -R :usuarios /usr/local/lib/R/site-library
sudo chmod -R g+w /usr/local/lib/R/site-library
sudo chmod -R o-x /usr/local/lib/R/site-library
Faça o mesmo com shiny
sudo usermod -a -G usuarios shiny
sudo chown -R :usuarios /srv/shiny-server
sudo chmod -R g+w /srv/shiny-server
sudo chmod -R o-x /srv/shiny-server
Pronto, agora você pode trabalhar livremente com o R e o shiny na nuvem. Se quiser testar se tudo está bem. Entre no demo shiny que já vem com a instalação:
https://dominio.com.br/shiny
E no Rstudio:
https://dominio.com.br/rstudio