Lekcije naučene iz postavljanja moje prve web-aplikacije s punim hrpom

Nedavno sam postigao jedan od svojih dugoročnih ciljeva: postavljanje svoje prve web-aplikacije s punim hrpom.

U ovom postu podijelit ću lekcije koje sam naučio iz perspektive početnika, zajedno s nekoliko korisnih vodiča koje sam slijedio, ključnim preprekama koje sam morao prevladati i pogreškama koje sam tijekom puta počinio. Želim pomoći drugim programerima da shvate što je uključeno u postavljanje web aplikacije.

Nakon više od šest tjedana guglanja, pokušavanja, neuspjeha i ponovnog pokušaja, napokon sam uspio razmjestiti svoju web aplikaciju. Sastojao se od pozadine Node.js zajedno s React sučeljem virtualnog stroja Amazon Web Services (AWS) EC2.

Bio je to popriličan izazov, ali uistinu zadovoljavajući, jer je na kraju aplikacija uspješno postavljena i sada je dostupna putem imena javne domene.

Najveća mi je poteškoća bilo pronaći informacije. Nisam razumio što je sve uključeno u raspoređivanje. Tako sam se trudio pronaći učinkovite odgovore na webu. Nisam uspio pronaći niti jedan vodič za cijeli proces.

Nadam se da mogu pojednostaviti krivulju učenja primjene za sljedeću osobu tako što ću sve informacije koje sam naučio staviti na jedno mjesto.

Dakle, ide ...

Što znači postavljanje aplikacije?

Web aplikacija podijeljena je u dva dijela.

  • Kôd klijentske strane: Ovo je vaš sučelje UI koda. To su statične datoteke koje se ne mijenjaju tijekom života vaše aplikacije. Statičke datoteke moraju negdje postojati kako bi ih vaši korisnici mogli preuzeti i pokrenuti u svom pregledniku na strani klijenta. Kasnije ću detaljnije objasniti gdje bi to moglo biti.
  • Kôd na strani poslužitelja: Ovo se odnosi na svu logiku vaše aplikacije. Trebao bi se izvoditi na poslužitelju (stroju), obično virtualnom poput EC2 instance, slično kao što ga pokrećete kada se razvijate lokalno.

Da bi pokrenuo vaš lokalni kôd, poslužitelj mora imati njegovu kopiju. Upravo sam klonirao svoj Github repo na poslužitelj iz sučelja naredbenog retka poslužitelja.

Također morate postaviti svoj poslužitelj. Ovo uključuje:

  • postavljanje uređaja za pristup Internetu i pokretanje vašeg koda
  • izlažući ispravne priključke
  • slušanje HTTP zahtjeva (internetski zahtjevi)
  • usmjeravanje naziva prilagođene domene na poslužitelj s kojeg se pokreće vaš program

Znat ćete da funkcionira kad možete pristupiti svojoj aplikaciji koristeći svoje prilagođeno ime domene s bilo kojeg računala na Internetu i sve funkcije vaše aplikacije rade kako se očekuje.

Dakle, to je pregled. Ali, kako to zapravo radimo?

Početak rada

Trebali biste podijeliti svoju aplikaciju i riješiti problem. Razmještate dvije različite stvari: statičke datoteke na strani klijenta i kod na strani poslužitelja.

Moja prva pogreška bila je razmišljati o svojoj aplikaciji kao cjelini, a ne o dvije zasebne aplikacije koje međusobno razgovaraju.

To je dodalo složenost i učinilo guglanje odgovora beskorisnim. Zbog toga sam se osjećao shrvano.

Razbio sam problem na ove korake. Iako se svaki problem uvijek može dalje raščlaniti.

  • Postavljanje vašeg VM-a i postavljanje vašeg Backenda
  • Postavljanje vašeg Frontenda
  • Komuniciranje dviju aplikacija
  • Ukazivanje na vaše ime domene

Na donjoj slici pokušao sam prikazati cijeli postupak u dijagramu.

Postavljanje vašeg VM-a i postavljanje vašeg Backenda

U mom slučaju ovo je bio Express.js poslužitelj postavljen na virtualnom stroju Amazon EC2. Objasnio bih kako to učiniti, ali vodič "Stvaranje i upravljanje Node.js poslužiteljem na AWS-u - 1. dio" daje daleko bolji posao.

To je najbolji vodič koji sam naišao u ovom prostoru i pokriva:

  • Pokretanje AWS virtualnog stroja
  • Uspostavljanje ispravnih sigurnosnih grupa za portove
  • Povlačenje koda iz GitHub-a na virtualni stroj
  • Pokretanje vašeg poslužitelja
  • Korištenje Nginxa, HTTP poslužitelja, za prosljeđivanje zahtjeva s porta 80
  • Korištenje PM2 za ustrajavanje u procesu izvođenja vašeg poslužitelja

Bio je to spasitelj života, a bez njega bih i dalje vjerojatno zapeo. Zato hvala, Robert Tod.

Možete jednostavno testirati da vaš poslužitelj radi pomoću programa Postman za slanje zahtjeva na jednu od vaših Backend krajnjih točaka.

Postavljanje vašeg Frontenda

Dakle, sada kada imate poslužitelj s pokrenutom pozadinom (nadam se), trebate pokrenuti svoj Frontend. To je stvarno lako kad razumijete postupak.

Nažalost, dugo nisam. Na primjer, na početku sam pokušao pokrenuti svoj Frontend koristeći npm start.

Npm start stvara lokalni razvojni poslužitelj koji opslužuje datoteke tako da im je moguće pristupiti samo pomoću njih localhostšto nije ono što želimo.

Da biste postavili kôd Frontenda, morate pohraniti sve datoteke na virtualnom stroju na mjesto za koje vaš web poslužitelj zna. Web poslužitelj omogućuje klijentu da preuzme kôd i pokrene ga u svom pregledniku.

Apache i Nginx primjeri su web poslužitelja.

Web poslužitelj preslušava određene priključke, priključak 80 ili češće priključak 443 (siguran) i poslužuje statičke datoteke (vaš Frontend kôd) ili prosljeđuje zahtjev na drugi priključak. Na primjer, vidjeli smo zahtjev za Backend u gore navedenom vodiču za Node.js.

Kako je Frontend kôd samo zbirka datoteka pohranjenih na web poslužitelju, želimo te datoteke učiniti što manjima i optimiziranima. To osigurava da ih klijent može preuzeti i pokrenuti što je brže moguće.

Brža stranica učitava jednake sretne korisnike.

Sve vaše Frontend JavaScript datoteke mogu se povezati u jednu JavaScript datoteku. To se obično radi pokretanjem npm run build, pod pretpostavkom da ste ovu skriptu definirali u paketu.json.

Ovdje možete pročitati više o grupiranju koda.

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.