Pelajaran diambil dari menggunakan aplikasi web tumpukan penuh pertama saya

Saya baru-baru ini mencapai salah satu tujuan jangka panjang saya: menggunakan aplikasi web tumpukan penuh pertama saya.

Dalam catatan ini, saya akan berkongsi pelajaran yang saya pelajari dari perspektif pemula, bersama dengan beberapa tutorial berguna yang saya ikuti, sekatan jalan utama yang harus saya atasi, dan kesilapan yang saya buat sepanjang perjalanan. Saya ingin membantu pembangun lain memahami apa yang terlibat dalam menyebarkan aplikasi web.

Setelah menghabiskan lebih dari enam minggu googling, mencuba, gagal, dan mencuba lagi, akhirnya saya berjaya menggunakan aplikasi web saya. Itu terdiri daripada backend Node.js bersama dengan frontend React ke mesin maya Amazon Web Services (AWS) EC2.

Itu adalah satu cabaran tetapi ia benar-benar memuaskan, kerana pada akhirnya aplikasi ini berjaya digunakan dan kini dapat diakses melalui nama domain awam.

Kesukaran terbesar bagi saya adalah mencari maklumat. Saya tidak faham apa yang terlibat dalam penyebaran. Oleh itu, saya berusaha untuk mencari jawapan yang berkesan di web. Saya gagal menemui satu panduan untuk keseluruhan proses.

Mudah-mudahan, saya dapat mempermudah keluk pembelajaran penyebaran untuk orang seterusnya dengan membawa semua maklumat yang saya pelajari ke satu tempat.

Jadi di sini ...

Apa maksudnya menggunakan aplikasi?

Aplikasi web terbahagi kepada dua bahagian.

  • Kod sisi pelanggan: Ini adalah kod UI frontend anda. Ini adalah fail statik yang tidak berubah sepanjang hayat aplikasi anda. Fail statik perlu ada di suatu tempat supaya pengguna anda dapat memuat turun dan menjalankannya di penyemak imbas mereka di sisi klien. Saya akan menerangkan dengan lebih terperinci mengenai tempat di mana mungkin nanti.
  • Kod sisi pelayan: Ini berkaitan dengan semua logik aplikasi anda. Ia harus dijalankan pada pelayan (mesin), biasanya yang maya seperti contoh EC2, seperti yang anda jalankan ketika membangun secara tempatan.

Untuk menjalankan kod tempatan anda, pelayan mesti mempunyai salinannya. Saya hanya mengklon Github repo saya ke pelayan dari antara muka baris perintah pelayan.

Anda juga perlu menyediakan pelayan anda. Ini termasuk:

  • menyediakan mesin untuk dapat mengakses internet dan menjalankan kod anda
  • mendedahkan port yang betul
  • mendengar permintaan HTTP (permintaan Internet)
  • menunjuk nama domain khusus ke pelayan yang digunakan oleh aplikasi anda

Anda akan tahu ia berfungsi apabila anda dapat mengakses aplikasi anda menggunakan nama domain khusus anda dari mana-mana mesin di Internet dan semua fungsi aplikasi anda berfungsi seperti yang diharapkan.

Jadi, itu gambaran keseluruhan. Tetapi, bagaimana kita melakukannya?

Bermula

Anda harus memecah permohonan dan memecahkan masalah. Anda menggunakan dua perkara yang berbeza: fail statik sisi pelanggan dan kod sisi pelayan.

Kesalahan pertama saya adalah memikirkan aplikasi saya secara keseluruhan, dan bukannya dua aplikasi berasingan yang saling berbual.

Ini menambah kerumitan dan membuat jawapan Google tidak berguna. Itu membuat saya merasa terharu.

Saya memecahkan masalah ke langkah-langkah ini. Walaupun setiap masalah selalu dapat dipecahkan lebih jauh.

  • Menyiapkan VM anda dan menggunakan Backend anda
  • Menggunakan Frontend anda
  • Mendapatkan Dua Aplikasi Berkomunikasi
  • Menunjuk Nama Domain anda

Dalam gambar di bawah, saya telah berusaha memasukkan proses lengkap dalam rajah.

Menyiapkan VM anda dan menggunakan Backend anda

Dalam kes saya, ini adalah pelayan Express.js yang digunakan pada mesin maya amazon EC2. Saya akan menerangkan bagaimana melakukannya, tetapi tutorial "Membuat dan Mengurus Pelayan Node.js di AWS - Bahagian 1" melakukan pekerjaan yang jauh lebih baik.

Ini adalah tutorial terbaik yang saya temui di ruangan ini dan merangkumi:

  • Memulakan mesin maya AWS
  • Mendapatkan kumpulan keselamatan yang betul untuk pelabuhan
  • Menarik kod dari GitHub ke mesin maya
  • Menjalankan pelayan anda
  • Menggunakan Nginx, pelayan HTTP, untuk meneruskan permintaan dari port 80
  • Menggunakan PM2 untuk meneruskan proses menjalankan pelayan anda

Itu adalah penyelamat hidup, dan tanpanya saya mungkin masih akan tersekat. Jadi terima kasih, Robert Tod.

Anda dapat dengan mudah menguji bahawa pelayan anda berjalan menggunakan Postman untuk mengirim permintaan ke salah satu titik akhir Backend anda.

Menggunakan Frontend anda

Oleh kerana sekarang anda mempunyai pelayan dengan backend anda berjalan (saya harap), anda perlu membuat Frontend anda berfungsi. Ini sangat mudah apabila anda memahami prosesnya.

Malangnya, saya tidak lama. Sebagai contoh, pada awalnya saya cuba menjalankan Frontend saya menggunakan npm start.

Npm start membuat pelayan pembangunan tempatan, melayani fail sehingga hanya dapat diakses menggunakan localhostyang tidak seperti yang kita mahukan.

Untuk menggunakan kod Frontend, anda harus menyimpan semua fail di mesin maya anda di lokasi yang diketahui oleh pelayan web anda. Pelayan web membolehkan pelanggan memuat turun kod dan menjalankannya di penyemak imbas mereka.

Apache dan Nginx adalah contoh pelayan web.

Pelayan web mendengarkan port tertentu, port 80 atau lebih biasa port 443 (selamat), dan sama ada menyajikan fail statik (kod Frontend anda) atau meneruskan permintaan ke port lain. Sebagai contoh, kami melihat permintaan ke Backend dalam tutorial Node.js di atas.

Oleh kerana kod Frontend hanyalah sekumpulan fail yang disimpan di pelayan web, kami ingin menjadikan fail ini sekecil dan dioptimumkan mungkin. Ini memastikan bahawa pelanggan dapat memuat turun dan menjalankannya secepat mungkin.

Halaman lebih cepat memuatkan pengguna gembira yang sama.

Semua fail JavaScript Frontend anda dapat digabungkan menjadi satu fail JavaScript. Ini biasanya dilakukan dengan menjalankan build npm run, dengan andaian anda mempunyai skrip ini yang ditentukan dalam package.json anda.

Anda boleh membaca lebih lanjut mengenai kod gabungan di sini.

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.