![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
Cando chegou o momento de implementar a aplicación probei AWS, pero sinceramente quedei un pouco desconcertado coa cantidade de información e servizos que proporcionan, e realmente quería ver a miña aplicación en liberdade. Entón atopeime con Vercel. Ademais, estiven aprendendo sobre Docker e quería poñer en práctica o que aprendín ata agora, esta era a oportunidade adecuada.
Vercel é moi coñecido pola súa implementación de configuración cero. Con só un par de clics podes implementar a túa aplicación. Tamén podes conectar o teu repositorio e Vercel creará e implementará o teu proxecto ao instante despois de cada commit. Non pode ser máis cómodo que iso 😀 . Outra razón pola que escollín Vercel sobre AWS foi a súa función "sen servidor", que usei para renderizar os documentos da miña base de datos a través dunha API Express. Para ser honesto, non podo queixarme do seu servizo. Nunca tiven ningún problema co meu proxecto. A cousa aquí é que quería saber máis sobre o backend da miña aplicación e pensei que entender a súa implementación podería axudarme con iso. Vin a moita xente elixir AWS en lugar de Vercel polo seu plan de prezos. Non se aplica ao meu caso xa que a miña aplicación non ten tanto tráfico e úsoa principalmente para estudos. Pero é bo mencionar que Vercel ten un "problema" coa escalada cando se trata de prezos.
A aplicación Toronto Food Basket pódese dividir en tres partes diferentes:
Webscraper para recoller información dun supermercado local
API Express que organiza a información e pode realizar operacións matemáticas para facelo.
Aplicación React que mostra a aplicación e toda a información necesaria.
Polo momento só estou implementando o Webscraper en AWS xa que aínda teño que aprender máis sobre servidores e rutas para implementar a API Express e a aplicación React. Para comezar, lancei unha instancia de AWS EC2 e configurei unha alarma de orzamento para que cada vez que o gasto na miña instancia supere os 0,01 dólares reciba unha notificación. /2023 e non tiña nin idea 😂. Amazon ofrece niveis gratuítos con 750 horas de t2.micro (ou t3.micro nas rexións nas que t2.micro non está dispoñible), 30 Gib de almacenamento EBS, 2 millóns de IO, 1 GB de instantáneas e 100 GB de ancho de banda para Internet.
Mentres aprendía a implementar a miña aplicación dockerizada en AWS, decateime de que hai polo menos dous enfoques diferentes; pode haber máis:
constrúe o contedor docker localmente e envíe só o contedor a AWS.
enviar todo a AWS e construír o meu contedor de forma remota.
Elixín o segundo enfoque porque quería ter a experiencia de traballar de forma totalmente remota na miña aplicación se fose necesario. Non sempre estou no meu propio ordenador e ter a miña aplicación nunha instancia EC2 sería moi útil nesas situacións. Ademais, veríame obrigado a traballar con Vim, que é algo que teño moitas ganas de facer. Antes de enviar os ficheiros á miña instancia EC2, preparei o meu ambiente remoto instalando Node.js e Docker.
Para enviar os ficheiros á miña instancia EC2 usei o protocolo de copia segura (scp). O comando parecía algo así:
scp -i ubuntu.pem -r LOCAL_DIRECTORY [email protected]:/home/ubuntu/downloads/webscraperdockeraws
-i ubuntu.pem
: esta marca especifica o ficheiro de identidade (chave privada) a usar para a autenticación de chave pública. Neste caso, ubuntu.pem
é o ficheiro de chave privada que se usa para autenticarse no servidor remoto.-r
: esta marca indica que a operación debe ser recursiva, o que significa que copiará os directorios e os seus contidos de forma recursiva.[email protected]:/home/ubuntu/downloads/webscraperdockeraws
: esta é a especificación do destino. Inclúe o nome de usuario ( ubuntu
) e o enderezo IP ( 35.183.21.127
) do servidor remoto, seguidos da ruta do directorio ( /home/ubuntu/downloads
) onde se copiarán os ficheiros.
Unha vez que todos os ficheiros foron transferidos á miña instancia EC2, puiden construír o meu contedor docker. E aquí comezaron os erros, xa! A biblioteca máis importante do meu Webscraper é Puppeteer, que ofrece unha API de alto nivel para controlar Chrome/Chromium a través do protocolo DevTools. Puppeteer corre en modo sen cabeza, o que fai que a súa execución sexa máis rápida. Pero ao tentar acoplar a miña aplicación atopeime con algúns problemas:
De forma predeterminada, cando Puppeteer está instalado, descarga o Chrome para probar e un binario chrome-headless-shell. O navegador descárgase no cartafol $HOME/.cache/puppeteer. O problema é que AWS non inclúe un $HOME/.cache na súa instancia de Ubuntu. Descubrín este problema despois de investigar, e para resolver todo o que tiña que facer era mover o cartafol /.cache ao directorio raíz; este problema está ben documentado no portal npm de Puppeteers.
Unha cousa obvia da que non me decatei foi que ata agora estaba executando a miña aplicación en sistemas operativos como Windows e MacOs. Pero agora estaba lidando con Ubuntu. E como era unha instancia baleira, non tiña ningún paquete/aplicación preinstalado, é por iso que instalei node e docker tan pronto como executei a instancia por primeira vez. Pero esquecíame unha aplicación moi importante para que o meu Webscraper funcione: Google Chrome. Lembras o que dixen antes sobre Titiriteiro? Ben, necesitaba asegurarme de ter a versión correcta de Chromium na miña instancia . Todas as versións principais de Node.js están construídas sobre unha versión de Debian, e esa versión de Debian inclúe unha versión antiga de Chromium, que ás veces non é compatible coa versión máis recente de Puppeteer. Despois de investigar, descubrín que tiña que incluír unha instrución no meu Dockerfile para que se puidese descargar a versión correcta de Chromium antes de que Docker instalase todas as dependencias da miña aplicación e a executase. O meu ficheiro Docker parecía algo así:
Despois de solucionar o problema anterior xurdiu outro. Agora a mensaxe de erro indica: "Non se pode usar ningún sandbox". Para solucionalo todo o que tiña que facer era cambiar o meu código e incluír un argumento –no-sandbox na función puppeteer.launch() para cada un dos meus produtos de comestibles.
Feito. Agora o meu Webscraper execútase nun contedor na miña instancia de AWS EC2. Non obstante, non raspará os 65 produtos. Despois do quinto produto, a aplicación falla. Creo que ten algo que ver cos recursos dispoñibles que teño nesta instancia: afrontaba o mesmo problema ao executar o scraper con accións github. De todos os xeitos, o meu obxectivo era lanzar unha instancia de AWS EC2 e que a miña aplicación se executase de forma remota, e así o fixen. Moitos por vir!