ECE366 - Lesson 9

Hosting on the Cloud, Testing

Instructor: Professor Hong

Review & Questions

## React and Docker
## Adding React to Docker Compose Dockerfile ``` # pull official base image FROM node:18 # set working directory WORKDIR /app # add `/app/node_modules/.bin` to $PATH ENV PATH /app/node_modules/.bin:$PATH # install app dependencies COPY package.json ./ COPY package-lock.json ./ RUN npm install --silent RUN npm install react-scripts@3.4.1 -g --silent # add app COPY . ./ # start app CMD npm start ```
## Docker-Compose docker-compose.yaml ``` services: ui: build: . ports: - 3000:3000 ```
## Putting it all together
## DB SQL Files - Initializing db ``` CREATE DATABASE rps; GRANT ALL PRIVILEGES ON DATABASE rps TO postgres; ```
## DB SQL Files - Player table ``` \c rps CREATE TABLE player ( player_name varchar(50) NOT NULL, password varchar(50) NOT NULL, win int DEFAULT 0, loss int DEFAULT 0, draw int DEFAULT 0, PRIMARY KEY (player_name) ); ```
## DB SQL Files - Move table ``` \c rps CREATE TABLE move ( move varchar(50) NOT NULL, PRIMARY KEY (move) ); ```
## DB SQL Files - Game table ``` \c rps CREATE SEQUENCE game_id_seq start with 1; CREATE TABLE game ( game_id int NOT NULL DEFAULT nextval('game_id_seq'), p1 varchar(50) NOT NULL, p2 varchar(50) NOT NULL, current_turn int NOT NULL DEFAULT 1, num_turn int NOT NULL DEFAULT 5, p1_points int NOT NULL DEFAULT 0, p2_points int NOT NULL DEFAULT 0, winner varchar(50) NULL, PRIMARY KEY (game_id), FOREIGN KEY (p1) REFERENCES player(player_name), FOREIGN KEY (p2) REFERENCES player(player_name), FOREIGN KEY (winner) REFERENCES player(player_name) ); ```
## DB SQL Files - Game History table ``` \c rps CREATE TABLE game_history ( game_id int NOT NULL, turn int NOT NULL, p1_move varchar(50) NOT NULL, p2_move varchar(50) NOT NULL, winner varchar(50) NOT NULL, PRIMARY KEY (game_id, turn), FOREIGN KEY (game_id) REFERENCES game(game_id), FOREIGN KEY (p1_move) REFERENCES move(move), FOREIGN KEY (p2_move) REFERENCES move(move), FOREIGN KEY (winner) REFERENCES player(player_name) ); ```
## DB SQL Files - Sample Data ``` \c rps ALTER SEQUENCE game_id_seq RESTART; DELETE from move WHERE 1=1; DELETE from game_history WHERE 1=1; DELETE from game WHERE 1=1; DELETE from player WHERE 1=1; INSERT INTO move (move) VALUES ('rock'); INSERT INTO move (move) VALUES ('paper'); INSERT INTO move (move) VALUES ('scissors'); INSERT INTO player (player_name, password) VALUES ('isaiah', 'password'); INSERT INTO player (player_name, password) VALUES ('malek', 'password'); INSERT INTO player (player_name, password) VALUES ('irene', 'password'); INSERT INTO game (p1, p2, current_turn) VALUES ('isaiah', 'malek', 1); INSERT INTO game (p1, p2, current_turn) VALUES ('isaiah', 'irene', 1); INSERT INTO game_history (game_id, turn, p1_move, p2_move, winner) VALUES (2, 1, 'rock', 'scissors', 'isaiah'); UPDATE game SET current_turn = 2 WHERE game_id = 2; INSERT INTO game_history (game_id, turn, p1_move, p2_move, winner) VALUES (2, 2, 'rock', 'scissors', 'isaiah'); UPDATE game SET current_turn = 3 WHERE game_id = 2; INSERT INTO game_history (game_id, turn, p1_move, p2_move, winner) VALUES (2, 3, 'scissors', 'paper', 'isaiah'); UPDATE game SET current_turn=4, winner='isaiah' WHERE game_id = 2; ```
## Initializing database Dockerfile ``` FROM postgres # Copy the SQL files to the container COPY init.sql /docker-entrypoint-initdb.d/0_init.sql COPY users.sql /docker-entrypoint-initdb.d/1_users.sql COPY game.sql /docker-entrypoint-initdb.d/2_game.sql ```
## Spring Boot Service ``` FROM maven:3.9.6-eclipse-temurin-21 AS build ADD . /project WORKDIR /project RUN mvn -e -Dmaven.test.skip package FROM eclipse-temurin:latest COPY --from=build /project/target/rpsjpa-0.0.1-SNAPSHOT.jar /app/rps.jar ENTRYPOINT java -jar /app/rps.jar ```
## Update Proxy package.json, main part of json ``` "proxy": "http://app:8080/", ```
## React UI Dockerfile ``` # pull official base image FROM node:20 # set working directory WORKDIR /app # add `/app/node_modules/.bin` to $PATH ENV PATH /app/node_modules/.bin:$PATH # install app dependencies COPY package.json ./ COPY package-lock.json ./ RUN npm install --silent RUN npm install react-scripts@3.4.1 -g --silent # add app COPY . ./ # start app CMD npm start ```
## Docker-Compose docker-compose.yaml ``` services: db: image: postgres build: context: db environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=password expose: - 5432:5432 ports: - 5432:5432 restart: always app: build: server/rps expose: - 8080:8080 ports: - 8080:8080 environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=password depends_on: - db ui: build: client ports: - 3000:3000 depends_on: - app ```
## RPS Game Logic - Add server side logic - Add UI to communicate with server
## Your First Azure Container
## Installing CLI - [https://learn.microsoft.com/en-us/cli/azure/install-azure-cli](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) - Azure Login: - WSL: ```az login --use-device-code``` - Mac: ```az login```
## Your First Container - [https://learn.microsoft.com/en-us/azure/container-instances/container-instances-quickstart](https://learn.microsoft.com/en-us/azure/container-instances/container-instances-quickstart) ``` $ az group create --name myResourceGroup --location eastus $ az container create --resource-group myResourceGroup --name mycontainer --image mcr.microsoft.com/azuredocs/aci-helloworld --dns-name-label aci-demo --ports 80 $ az container show --resource-group myResourceGroup --name mycontainer --query "{FQDN:ipAddress.fqdn,ProvisioningState:provisioningState}" --out table ``` - Run the site provided - You will have to update your dns label name
## Azure With Docker Compose
## Sample [https://learn.microsoft.com/en-us/azure/container-instances/tutorial-docker-compose](https://learn.microsoft.com/en-us/azure/container-instances/tutorial-docker-compose) ```$ az acr repository show --name --repository azure-vote-front``` - remove the initial directory in the above command - wait a few minutes after pushing before the IP address works
## Hosting a React App
## Create a New React App ``` npx create-react-app myapp cd myapp npm install npm start ```
## Dockerfile ``` FROM node:16.13.1-alpine as build RUN npm install -g serve # A simple webserver WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . RUN npm run build EXPOSE 80 CMD ["serve", "-s", "build", "-l", "80"] ```
## Docker-compose.yaml ``` version: '3' services: ui: build: . image: samplereactacr.azurecr.io/ui container_name: samplereact ports: - "80:80" ``` ``` docker compose build docker compose up ``` Note: We're using port 80
## Create Azure Parts - Create an Azure Resource Group - Create an Azure Container Registry - Create an Azure Container Instance docker context ``` az login --use-device-code az acr login --name samplereactacr docker context create aci samplereactaci docker context ls ```
## Push to Azure and Run Container Instances ``` docker-compose push docker context use samplereactaci docker compose up docker ps ```
## Azure With Docker Compose
## RPS - Removed firebase authentication for simplicity ``` curl localhost:8080/api/getUsers ``` Dockerfile ``` FROM maven:3.8.7-eclipse-temurin-19 AS build ADD . /project WORKDIR /project RUN mvn -e package FROM eclipse-temurin:latest COPY --from=build /project/target/rps-0.0.1-SNAPSHOT.jar /app/rps.jar ENTRYPOINT ["java","-jar","/app/rps.jar"] ```
## Create Azure Parts - Create an Azure Resource Group - Create an Azure Container Registry - Create an Azure Container Instance docker context ``` az login --use-device-code az acr login --name rpsacr docker context create aci rpsaci docker context ls ```
## docker-compose.yaml ``` services: db: build: db image: rpsacr.azurecr.io/db container_name: db environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=password expose: - 5432:5432 ports: - 5432:5432 restart: always app: build: server/rps image: rpsacr.azurecr.io/app container_name: app ports: - 8080:8080 environment: - POSTGRES_DB=postgres - POSTGRES_PASSWORD=password depends_on: - db ```
## Push to Azure and Run Container Instances ``` docker-compose push docker context use rpsaci docker compose up docker ps ```
## Check db and server - Check dbeaver - host: IP address - port: 5432 - database: rps - username/password: postgres/password - Curl the IP address and API ``` curl 4.156.198.75:8080/api/getUsers ```
## Adding the React UI Separately Dockerfile ``` FROM node:16.13.1-alpine as build RUN npm install -g serve # A simple webserver WORKDIR /usr/src/app COPY package*.json ./ RUN npm install COPY . . RUN npm run build EXPOSE 80 CMD ["serve", "-s", "build", "-l", "80"] ``` - Update IP address of server
## Adding the React UI Separately docker-compose.yaml ``` version: '3' services: ui: build: . image: rpsacr.azurecr.io/ui container_name: uitest ports: - "80:80" ```
## Push to Azure and Run Container Instances ``` docker compose build docker-compose push docker context use rpsaci docker compose up docker ps ```