Amazon Web Services

Prerequisites: AWS account!

IMPORTANT! Dupa terminarea modulului Cloud Computing, asigurati-va ca stergeti toate resursele AWS create pentru a evita costuri suplimentare. Puteti de asemenea sa stergeti detaliile de billing (ceea ce probabil va duce la suspendarea contului, ceea ce va doriti avand in vedere ca tot ce vom porni este de test)

Amazon Web Services este unul dintre ce mai mari furnizori de servicii in Cloud. Insumeaza acum peste 200 de servicii.

Unul dintre cele mai utilizate servicii este EC2 (Elastic Compute Cloud) care pune la dispozitie masini virtuale. Scopul nostru este de a porni o astfel de masina virtuala, a ne conecta la ea si a face disponibila aplicatia creata in pasii anteriori catre internet.

1. Lansare masina virtuala

  • Din pagina principala, accesam EC2 (search -> type EC2)

Asigurati-va ca sunteti in regiunea eu-central-1 (Frankfurt)

  • Dupa ce va asigurati ca sunteti in regiunea corecta, apasati Launch an instance

  • Denumiti instanta de masina virtuala cum doriti

  • Alegeti Ubuntu. 22.04. Instance type - t2.micro

  • Key pair (login) - Create a new key pair. Denumiti-o cum doriti -> save. Se va salva automat. Nu o pierdeti

  • Network settings - allow all

  • Launch si asteptam sa porneasca instanta

  • Puteti vedea instanta apasand pe Instances in meniul din stanga

2. Atasarea unui Elastic IP

AWS atribuie o adresa IP unica instantelor create. Aceasta este realocata altei instante in momentul in care inchidem instanta noastra, iar la repornire va primi alta. Acest comportament poate duce la confuzie si erori neprevazute. Pentru a ne asigura ca masina noastra virtuala are o adresa constanta, ii vom atribui o adresa IP Elastica (Elastic IP).

  • Din meniul din stanga, click Elastic IPs -> Allocate Elastic IP address

  • All default, click Allocate

  • Inapoi in Dashboard-ul Elastic IPs, selectati adresa nou creata -> Actions -> Associate Elastic IP address (sau apasati pe bannerul verde care ar trebui sa apara deasupra paginii)

  • Alegeti instanta nou creata, click Associate

  • In Dashboard-ul Instances veti vedea in dreptul instantei create, pe coloana Elastic IP (probabil va trebui sa scrolati), adresa IP Elastica asociata

  • Acum ne putem conecta la instanta nou creata

3. Conectarea la instanta EC2

Pentru usurinta, mutati cheia generata la pasul anterior intr-un folder apropiat de cel in care ati lucrat pana acum (ca sa nu o cautati in downloads de fiecare data cand aveti nevoie de ea)

  • Identificati adresa IP a instantei create (Elastic IP). Vom avea nevoie de ea pentru a ne conecta la instanta

  • In folderul in care ati salvat cheia, deschideti un terminal (eu folosesc git bash)

  • Rulati comanda: (-i indica faptul ca ne conectam utilizand o cheie (identity_file))

ssh -i <cheia>.<extensia> ubuntu@<adresa_ip>

exemplu:
ssh -i cloud-computing.pem ubuntu@4.18.2.77
  • Probabi veti fi intrebati daca doriti sa salvati adresa IP in known_hosts. Type yes.

  • We're in!

4. Configurarea instantei EC2

Folosind consola instantei create in pasul anterior...

4.1. Actualizam pachetele din instanta

  • Run sudo apt update

  • Run sudo apt upgrade

4.2. Instalam Nginx

  • Run sudo apt install nginx

  • Run sudo service nginx start

  • Accessing the server from a browser now shows a "Welcome to nginx!" message

4.3. Modificam configurarea Nginx

  • Run sudo nano /etc/nginx/sites-available/default pentru a accesa fisierul de configurare nginx

  • Stergeti tot ce este in fisier si copiati urmatorul cod. Astfel vom indica faptul ca ne dorim ca serverul nostru sa afiseze aplicatia care va rula pe portul 3000 (dupa ce o vom deschide)

// /etc/nginx/sites-available/default
server {
        location / {
                proxy_pass http://localhost:3000/;
        }
}
  • Ctrl + S ca sa salvati

  • Ctrl + X ca sa iesiti din fisier

  • Run sudo service nginx reload pentru a incarca fisierul de configurare modificat

  • Accesand acum adresa serverului, vom primi mesajul de eroare 502. Este in regula

4.4. Instalam Docker

Instructiunile detaliate pentru instalarea Docker pe o instanta EC2 cu Ubuntu 22.04 le puteti gasi si aici: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-22-04

Pentru a fi siguri ca nu uitam o comanda, le voi lista si in aceasta documentatie

  • Run sudo apt install apt-transport-https ca-certificates curl software-properties-common

  • Run curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

  • Run echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

  • Run sudo apt update

  • Run apt-cache policy docker-ce

  • Run sudo apt install docker-ce

  • Run sudo systemctl status docker

  • Output should look like this now:

  • Ctrl + C to exit

4.5. Enable Docker usage without sudo

Inainte de a asigura acces sudo pentru comenzile docker, va trebui sa adaugam o parola pentru userul ubuntu (creat de AWS la pornirea instantei EC2)

  • Run sudo su -

  • Run passwd ubuntu

  • Setati o parola (si notati-o intr-un fisier local / nu o pierdeti)

  • Ne intoarcem la userul ubuntu. Run: su -l ubuntu

Acum putem asigura acces sudo pentru comenzile docker

  • Run sudo usermod -aG docker ${USER}

  • Run su - ${USER}

  • Introduceti parola pe care ati setat-o la pasul precedent

  • Done!

  • Pentru a testa ca totul a mers conform planului, rulati docker images

  • Output should look like this:

4.6. Pregatim proiectul pentru a fi introdus intr-o imagine Docker

  • Modificam fisierul next.config.js pentru a indica faptul ca pregatim proiectul pentru a fi trimis in productie. Inseram linia output: "standalone"

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  output: "standalone",
}

module.exports = nextConfig
  • In root-ul proiectului NextJS din calculatorul personal, vom crea fisierul Dockerfile (atentie, denumirea trebuie sa fie exact Dockerfile) cu urmatorul continut (copy paste - documentatia oficiala Vercel)

FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  elif [ -f package-lock.json ]; then npm ci; \
  elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
  else echo "Lockfile not found." && exit 1; \
  fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN yarn build

# If using npm comment out above and use below instead
# RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["node", "server.js"]

In root-ul proiectului NextJS, vom crea fisierul .dockerignore (atentie, denumirea trebuie sa fie exact Dockerfile) cu urmatorul continut (copy paste - documentatia oficiala Vercel)

Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
  • Salvam si trimitem in repository-ul remote modificarile pentru ca le vom accesa din instanta noastra EC2 (git add . , git commit -m "Docker init" , git push origin [numele branch-ului] in terminal)

4.7. Aducem proiectul in instanta noastra

Inapoi in consola instantei EC2 configurate vom aduce proiectul NextJS cu ajutorul Git. Pentru aceasta avem nevoie de link-ul de clonare al repository-ului nostru. Il gasiti in GitHub - clone (am trecut prin acest proces aici)

  • Clonam repository-ul - git clone [link_repo] (un folder cu numele repository-ul va fi creat automat)

  • Run ls pentru a vedea continutul folderului curent. Ar trebui sa vedeti numele folderului care contine repository-ul

  • Run cd [nume_repo] pentru a accesa folderul

  • Adaugam fisierul .env:

    • Run touch .env

    • Run sudo nano .env

    • Copiati continutul fisierului .env de pe calculatorul vostru in fisierul .env creat in instanta

    • Ctrl + S to save

    • Ctrl + X to exit

  • Run docker build -t nextjs-docker . (Atentie, este un punct (.) dupa numele imaginii, nu il uitati)

  • Asteptam

  • Daca rulam docker images vom vedea imaginea nou creata

  • Pornim un proces utilizand imaginea creata. Run docker run -d --restart always -p 3000:3000 nextjs-docker

  • Daca accesam adresa instantei, vom vedea aplicatia noastra!

Last updated