Az első teljes veremű webalkalmazás telepítéséből levont tanulságok

Nemrégiben elértem egyik hosszú távú célomat: az első teljes verem webes alkalmazásom bevezetését.

Ebben a bejegyzésben megosztom a kezdő szemszögéből tanult leckéimet, valamint néhány hasznos oktatóanyagot, amelyeket követtem, a legfontosabb akadályokat, amelyeket le kellett küzdenem, és az általam elkövetett hibákat. Segíteni szeretnék más fejlesztőket, hogy megértsék, mi jár egy webalkalmazás telepítésével.

Miután több mint hat hétig töltöttem a guglizást, próbálkozást, kudarcot és újra próbálkozást, végül sikerült telepítenem a webalkalmazásomat. Ez egy Node.js háttérképet és egy React kezelőfelületet tartalmazott az Amazon Web Services (AWS) EC2 virtuális géphez.

Nagy kihívást jelentett, de valóban kielégítő volt, mivel végül az alkalmazást sikeresen telepítették, és ma már nyilvános néven érhető el.

Számomra a legnagyobb nehézséget az információk megtalálása jelentette. Nem értettem, mi jár a bevetéssel. Ezért küzdöttem, hogy hatékony válaszokat találjak az interneten. Nem sikerült egyetlen útmutatót találnom az egész folyamathoz.

Remélhetőleg leegyszerűsíthetem a következő személy telepítési tanulási görbéjét azáltal, hogy az összes tanult információt egy helyre hozom.

Tehát itt megy ...

Mit jelent egy alkalmazás telepítése?

A webalkalmazás két részre oszlik.

  • Ügyféloldali kód: Ez a kezelőfelület UI-kódja. Ezek statikus fájlok, amelyek nem változnak az alkalmazás élettartama alatt. A statikus fájloknak valahol létezniük kell, hogy a felhasználók letölthessék és futtathassák őket a böngészőben az ügyfél oldalon. Részletesen kitérek arra, hogy hol lehet ez valahol később.
  • Szerveroldali kód: Ez az alkalmazás összes logikájával foglalkozik. Kiszolgálón (gépen) kell futtatni, általában virtuális gépen, mint például az EC2 példány, hasonlóan ahhoz, ahogy lokálisan fejlesztve futtatja.

A helyi kód futtatásához a szervernek rendelkeznie kell annak másolatával. Most klónoztam a Github repót a kiszolgálóra a kiszolgáló parancssori felületéről.

Be kell állítania a szervert is. Ebbe beletartozik:

  • a gép beállítása az internet eléréséhez és a kód futtatásához
  • a megfelelő portok felfedése
  • HTTP kérések figyelése (internetes kérések)
  • egyéni domain nevet mutat arra a kiszolgálóra, amelyről az alkalmazás fut

Tudni fogja, hogy akkor működik, amikor az interneten bármely gépről hozzáférhet az alkalmazásához az egyéni domainnév használatával, és az alkalmazás minden funkciója a várakozásoknak megfelelően működik.

Szóval, ez egy áttekintés. De valójában hogyan csináljuk?

Elkezdeni

Szét kell bontania az alkalmazását és meg kell bontania a problémát. Két különböző dolgot telepít: kliensoldali statikus fájlokat és szerveroldali kódokat.

Az első hibám az volt, hogy az egész alkalmazásra gondoltam, nem pedig két különálló alkalmazásra, amelyek egymással beszélgetnek.

Ez növelte a bonyolultságot, és haszontalanná tette a válaszok guglizását. Engem túlterheltnek éreztem.

A problémát ezekre a lépésekre bontottam. Bár minden probléma mindig tovább bontható.

  • A virtuális gép beállítása és a háttérprogram telepítése
  • A Frontend telepítése
  • A két alkalmazás kommunikációja
  • Mutatja a domain nevét

Az alábbi ábrán megkíséreltem a teljes folyamatot diagramba helyezni.

A virtuális gép beállítása és a háttérprogram telepítése

Esetemben ez egy Express.js szerver volt, amelyet egy amazon EC2 virtuális gépre telepítettek. Elmagyaráztam volna, hogyan kell csinálni, de a „Node.js kiszolgáló létrehozása és kezelése AWS-en - 1. rész” bemutató sokkal jobb munkát végez.

Ez a legjobb oktatóanyag, amellyel találkoztam ezen a téren, és lefedi:

  • AWS virtuális gép indítása
  • Megfelelő biztonsági csoportok felállítása a portok számára
  • Kód húzása a GitHub-ról a virtuális gépre
  • A szerver futtatása
  • Az Nginx, egy HTTP kiszolgáló használata a 80-as portról érkező kérések továbbítására
  • A PM2 használatával a kiszolgálót futtató folyamat fennmaradhat

Életmentő volt, és nélküle valószínűleg még mindig elakadtam volna. Tehát köszönöm, Robert Tod.

Könnyen tesztelheti, hogy a kiszolgáló fut-e a Postman segítségével, kérelem küldésére a Backend egyik végpontjára.

A Frontend telepítése

Tehát most, hogy van egy szerver, a háttérben fut (remélem), működtetnie kell a Frontendjét. Ez nagyon egyszerű, ha megérted a folyamatot.

Sajnos sokáig nem. Például az elején megpróbáltam futtatni a Frontendemet az npm start segítségével.

Az Npm start létrehoz egy helyi fejlesztőkiszolgálót, amely kiszolgálja a fájlokat úgy, hogy azok csak akkor érhetők el localhost, ha nem ezt szeretnénk.

A Frontend kód telepítéséhez az összes fájlt el kell tárolnia a virtuális gépen egy olyan helyen, amelyről a webkiszolgáló tud. A webszerver lehetővé teszi az ügyfél számára a kód letöltését és a böngészőben történő futtatását.

Az Apache és az Nginx példák a webkiszolgálókra.

A webszerver meghallgat bizonyos portokat, a 80-as vagy még gyakrabban a 443-as portot (biztonságos), és vagy statikus fájlokat (az Ön Frontend-kódját) szolgáltatja, vagy továbbítja a kérést egy másik portnak. Például láttunk egy kérést a Backendhez a fenti Node.js oktatóanyagban.

Mivel a Frontend kód csak egy webszerveren tárolt fájlok gyűjteménye, ezeket a fájlokat a lehető legkisebbé és optimalizáltabbá akarjuk tenni. Ez biztosítja, hogy az ügyfél a lehető leggyorsabban letölthesse és futtassa őket.

A gyorsabb oldal ugyanolyan boldog felhasználókat tölt be.

Minden Frontend JavaScript-fájlja egyetlen JavaScript-fájlba csomagolható. Ezt általában az npm run build futtatásával végezzük, feltéve, hogy ezt a szkriptet definiáltuk a package.json fájlban.

A csomagcsomagolásról itt olvashat bővebben.

Basically, bundling your application removes anything that isn’t essential. This includes shortening names and placing all JavaScript code in one file. It will also compile your code into the correct JavaScript version. This is so all web browsers can understand and run it (for example, converting TypeScript to JavaScript).

When your code is bundled, you just have to copy the files into your web server. Then configure your web server to serve files stored at that location.

Here is a good article on deploying static files to an Nginx web server.

Hopefully, if all is going well (which it never does), your Frontend code is now working.

Visit the public DNS for the virtual machine to verify that the static information from the site loads.

Getting the Two Applications Communicating

So I had both my applications running individually, but something wasn’t right. I couldn’t get rid of a network request error.

This was the most frustrating point for me. I was so close, but I ran into some setbacks that ended up taking weeks to solve.

Cross-Origin Resource Sharing (CORS) is a mechanism that allows communication between different IP addresses or ports. You want your Backend to be allowed to send data back to your Frontend.

To enable this, your Frontend must include the correct headers when requesting resources. This can be done in two ways:

  • The headers can be added in Nginx although it takes some figuring out. You can start here.
  • You can use the cors npm module to include the headers.

A great way to test this if it is working is by looking within the network tab of your browser’s developer tools. This shows all the requests your application is making. If you select a request you can see where the request went to and what headers it included.

Once you have the right request headers being sent with your request, you have to make sure the requests are going to the correct place. This should be the address and port of your EC2 Backend server and not the address and port of your local Backend server like mine was.

Your Frontend communicates with your Backend using HTTP requests. Somewhere in your Frontend, code you will tell it where your Backend is located.

const networkInterface = createNetworkInterface({ uri: ‘//0.0.0.0:5000/graphql', });

Mine looked like this, which clearly was not going to be correct for my production server.

Annoyingly this made my application seem like it worked when I first navigated to it on my local machine, as my local server was running and able to return the required information.

To fix this, you can simply change the URI defined, but that means having to change it back every time you do further development, which is not the best approach (I know because I did it).

A more sophisticated solution is to include both URIs and use environment variables to select the appropriate one.

const networkInterface = createNetworkInterface({ uri: process.env.NODE_ENV === 'production' ? '//thecommunitymind.com/graphql' : '//0.0.0.0:5000/graphql', });

Simple but effective. Just make sure you set your NODE_ENV to production when using it for your production server.

We’re almost there. In fact, your deployment might work now.

But I had one last problem to overcome.

Even though my CORS setup was correct, the required headers were not being included consistently and were only getting added sometimes. For some POST requests, the CORS headers were not always present. Very odd!

This error lead me on a frustrating goose chase trying to fix my CORS setup in Nginx, when actually it had nothing to do with CORS.

Actually, I didn’t even need to do anything with CORS in Nginx, because I was using the CORS npm module.

The error was due to two other issues:

  • My database was included as an sqlite file in the Backend and
  • My process manager, PM2, was watching for file changes

So writing to the database file on a POST request caused PM2 to restart the server. This was leading to the correct headers not getting picked up which resulted in misleading errors.

A great tip and one I wish I had known earlier is to check your server logs on your EC2 instance. Whether you’re using PM2 or something else there will always be a way to check your logs. Just Google it!

These logs provided the key to solve my issue.

I simply had to turn off the watch ability of PM2. Bingo. And finally, it worked.

Pointing your Domain Name

This is the icing on the cake. You want a nice clean URL for your newly deployed application.

I bought my domain name through Amazon and used Route 53 to point it to the correct EC2 instance. This was a surprisingly painless experience.

Amazon’s tutorial was quite sufficient.

Summary

I hope this post has helped you understand the web application deployment process and ultimately get your amazing project online — whatever that may be.

At least you should have a better idea of what to Google for!

Good Luck.