Pamokos, išmoktos diegiant mano pirmąją pilnos žiniatinklio programą

Neseniai pasiekiau vieną iš savo ilgalaikių tikslų: įdiegiau savo pirmąją pilnos žiniatinklio programą.

Šiame įraše pasidalysiu pamokomis, kurias išmokau pradedantiesiems, kartu su keliomis naudingomis pamokomis, kurių laikiausi, pagrindinėmis kliūtimis, kurias turėjau įveikti, ir klaidomis, kurias padariau kelyje. Noriu padėti kitiems kūrėjams suprasti, kas susiję su žiniatinklio programos diegimu.

Praleidęs daugiau nei šešias savaites google, bandymas, nesėkmė ir bandymas dar kartą, man galiausiai pavyko įdiegti savo žiniatinklio programą. Jį sudarė „Node.js“ vidinė įranga ir „React“ priekinė „Amazon Web Services“ (AWS) EC2 virtualiosios mašinos sąsaja.

Tai buvo nemenkas iššūkis, tačiau jis tikrai tenkino, nes galiausiai programa buvo sėkmingai įdiegta ir dabar prieinama per viešojo domeno vardą.

Didžiausias sunkumas man buvo rasti informaciją. Aš nesupratau, kas susiję su dislokavimu. Taigi aš stengiausi rasti efektyvių atsakymų internete. Man nepavyko rasti vieno vadovo visam procesui.

Tikiuosi, kad galėsiu supaprastinti kito asmens mokymosi diegimo kreivę, sukaupdama visą išmoktą informaciją į vieną vietą.

Taigi čia eina ...

Ką reiškia diegti programą?

Interneto programa yra padalinta į dvi dalis.

  • Kliento pusės kodas: Tai jūsų sąsajos vartotojo sąsajos kodas. Tai yra statiniai failai, kurie nesikeičia per visą jūsų programos gyvenimą. Statiniai failai turi kažkur egzistuoti , kad vartotojai galėtų juos atsisiųsti ir paleisti savo naršyklėje kliento pusėje. Aš išsamiau paaiškinsiu, kur tai gali būti vėliau.
  • Serverio pusės kodas: tai apima visą jūsų programos logiką. Jis turėtų būti paleistas serveryje (mašinoje), paprastai virtualiame, pavyzdžiui, EC2 egzemplioriuje, panašiai kaip jūs jį paleidžiate kurdami lokaliai.

Norėdami paleisti vietinį kodą, serveris turi turėti jo kopiją. Aš tiesiog klonavau savo „Github“ atpirkimą į serverį iš serverio komandinės eilutės sąsajos.

Taip pat turite sukonfigūruoti savo serverį. Tai įtraukia:

  • nustatykite mašiną, kad galėtumėte prisijungti prie interneto ir paleisti savo kodą
  • atskleidžiant teisingus prievadus
  • klausytis HTTP užklausų (interneto užklausų)
  • nurodydami pasirinktinį domeno vardą į serverį, kuriame veikia jūsų programa

Jūs žinosite, kad jis veikia, kai galite pasiekti savo programą naudodami pasirinktinį domeno vardą iš bet kurios interneto mašinos ir visos jūsų programos funkcijos veikia taip, kaip tikėtasi.

Taigi, tai apžvalga. Bet kaip mes iš tikrųjų tai darome?

Darbo pradžia

Turėtumėte suskaidyti savo programą ir išskaidyti problemą. Jūs diegiate du skirtingus dalykus: kliento pusės statinius failus ir serverio pusės kodus.

Pirmoji mano klaida buvo galvoti apie visą savo programą, o ne apie dvi atskiras programas, kurios tarpusavyje kalba.

Tai dar labiau padidino sudėtingumą ir neteko ieškoti atsakymų. Tai lėmė, kad jaučiuosi priblokšta.

Aš suskirstiau problemą į šiuos veiksmus. Nors kiekvieną problemą visada galima išskaidyti toliau.

  • VM nustatymas ir „Backend“ diegimas
  • „Frontend“ diegimas
  • Kaip bendrauti dviem programomis
  • Nurodykite savo domeno vardą

Žemiau esančiame paveikslėlyje bandžiau pateikti visą procesą diagramoje.

VM nustatymas ir „Backend“ diegimas

Mano atveju tai buvo „Express.js“ serveris, įdiegtas „Amazon EC2“ virtualioje mašinoje. Aš būčiau paaiškinęs, kaip tai padaryti, bet pamoka „Node.js serverio kūrimas ir valdymas AWS - 1 dalis“ atlieka daug geresnį darbą.

Tai geriausia pamoka, su kuria susidūriau šioje erdvėje, ir apima:

  • AWS virtualiosios mašinos paleidimas
  • Tinkamų uostų saugos grupių nustatymas
  • Kodo ištraukimas iš „GitHub“ į virtualią mašiną
  • Jūsų serverio paleidimas
  • Naudojant „Nginx“, HTTP serverį, peradresuoti užklausas iš 80 prievado
  • Naudojant PM2, norint tęsti jūsų serverio procesą

It was a life saver, and without it I would still probably be stuck. So thank you, Robert Tod.

You can easily test that your server is running using Postman to send a request to one of your Backend endpoints.

Deploying your Frontend

So now that you have a server with your backend running (I hope), you need to get your Frontend working. This is really easy when you understand the process.

Unfortunately, I didn’t for a long time. For example, at the beginning I tried to run my Frontend using npm start.

Npm start creates a local development server, serving the files so that they are only accessible using localhost which is not what we want.

To deploy the Frontend code, you have to store all the files on your virtual machine in a location your web server knows about. The web server lets a client download the code and run it in their browser.

Apache and Nginx are examples of web servers.

A web server listens to certain ports, port 80 or more commonly port 443 (secure), and either serves static files (your Frontend code) or passes the request to a different port. For example, we saw a request to the Backend in the Node.js tutorial above.

As Frontend code is just a collection of files stored on a web server, we want to make these files as small and optimized as possible. This ensures that the client can download and run them as fast as possible.

Faster page loads equal happy users.

All your Frontend JavaScript files can be bundled into a single JavaScript file. This is usually done by running npm run build, assuming you have this script defined in your package.json.

You can read more about bundling code here.

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.