ECE366 - Lesson 9
Hosting on the Cloud
Instructor: Professor Hong
## 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-demo324 --ports 80 --os-type Linux --cpu 1 --memory 1.5
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
## Creating and Deploying a Container Image
## Creating and Deploying a Container Image
[https://learn.microsoft.com/en-us/azure/container-instances/container-instances-tutorial-prepare-app](https://learn.microsoft.com/en-us/azure/container-instances/container-instances-tutorial-prepare-app)
```
az acr create --resource-group myResourceGroup --name yourACRName --sku Basic
az acr update -n yourACRName --admin-enabled true
az container create --resource-group myResourceGroup --name aci-tutorial-app --image yourACRName.azurecr.io/aci-tutorial-app:v1 --cpu 1 --memory 1 --registry-login-server yourACRName.azurecr.io --registry-username yourACRName --registry-password $(az acr credential show --name yourACRName --query passwords[0].value -o tsv) --ip-address Public --dns-name-label yourDNSLabel --ports 80 --os-type Linux
```
- Replace `yourACRName` with a globally unique name (alphanumeric only)
- Replace `yourDNSLabel` with a unique DNS label
## Create a New React App
```
npm create vite@latest myapp -- --template react
cd myapp
npm install
npm run dev
```
## Dockerfile
```
FROM node:22-alpine AS build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine
RUN npm install -g serve
WORKDIR /usr/src/app
COPY --from=build /usr/src/app/dist ./dist
EXPOSE 80
CMD ["serve", "-s", "dist", "-l", "80"]
```
## Docker-compose.yaml
```
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
```
## Push to Azure and Run Container Instances
```
docker-compose push
```
## Deploying with a deploy-aci.yaml file
```
apiVersion: 2019-12-01
location: eastus
name: myContainerGroup5
properties:
containers:
- name: ui
properties:
image: myacr.azurecr.io/prepreact:latest
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 80
- port: 8080
osType: Linux
ipAddress:
type: Public
dnsNameLabel: myappdnslabel3233 # Add your desired DNS name label here
ports:
- protocol: tcp
port: 80
- protocol: tcp
port: 8080
imageRegistryCredentials:
- server: myacr.azurecr.io
username: 00000000-0000-0000-0000-000000000000
password: yourpassword
tags: {exampleTag: tutorial}
type: Microsoft.ContainerInstance/containerGroups
```
```
az container create --resource-group myResourceGroup --file deploy-aci-react.yaml
```
## Deploying a Multi-Container Group
[https://learn.microsoft.com/en-us/azure/container-instances/container-instances-multi-container-yaml](https://learn.microsoft.com/en-us/azure/container-instances/container-instances-multi-container-yaml)
```
apiVersion: 2019-12-01
location: eastus
name: myContainerGroup3
properties:
containers:
- name: aci-tutorial-app
properties:
image: myacr.azurecr.io/aci-tutorial-app:v1
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 80
- port: 8080
osType: Linux
ipAddress:
type: Public
dnsNameLabel: myappdnslabel323 # Add your desired DNS name label here
ports:
- protocol: tcp
port: 80
- protocol: tcp
port: 8080
imageRegistryCredentials:
- server: myacr.azurecr.io
username: 00000000-0000-0000-0000-000000000000
password: yourtoken
tags: {exampleTag: tutorial}
type: Microsoft.ContainerInstance/containerGroups
```
## Deploying a Multi-Container Group
```
apiVersion: 2019-12-01
location: eastus
name: myContainerGroup4
properties:
containers:
- name: aci-tutorial-app
properties:
image: myacr.azurecr.io/aci-tutorial-app:v1
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 80
- port: 8080
- name: ui
properties:
image: myacr.azurecr.io/ui:latest
resources:
requests:
cpu: 1
memoryInGb: 1.5
osType: Linux
ipAddress:
type: Public
dnsNameLabel: myappdnslabel3232 # Add your desired DNS name label here
ports:
- protocol: tcp
port: 80
- protocol: tcp
port: 8080
imageRegistryCredentials:
- server: myacr.azurecr.io
username: 00000000-0000-0000-0000-000000000000
password: yourpassword
tags: {exampleTag: tutorial}
type: Microsoft.ContainerInstance/containerGroups
```
## Database
```
docker compose build
docker tag postgres:latest myacr.azurecr.io/postgres:latest
docker push myacr.azurecr.io/postgres:latest
```
```
apiVersion: 2019-12-01
location: eastus
name: postgresContainerGroup
properties:
containers:
- name: db
properties:
image: myacr.azurecr.io/postgres:latest
environmentVariables:
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: password
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 5432
osType: Linux
ipAddress:
type: Public
dnsNameLabel: postgresdnslabel # Add your desired DNS name label here
ports:
- protocol: tcp
port: 5432
imageRegistryCredentials:
- server: myacr.azurecr.io
username: 00000000-0000-0000-0000-000000000000
password: yourpassword
tags: {exampleTag: tutorial}
type: Microsoft.ContainerInstance/containerGroups
```
```
az container create --resource-group myResourceGroup --file deploy-aci.yaml
```
## Check db with dbeaver
- Check dbeaver
- host: postgresdnslabel.eastus.azurecontainer.io
- port: 5432
- database: rps
- username/password: postgres/password
## UI Docker File Update
```
# Stage 1: Build the React application
FROM node:22-alpine AS build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Serve with nginx + reverse proxy
FROM nginx:alpine
# Copy built static files
COPY --from=build /usr/src/app/dist /usr/share/nginx/html
# Copy nginx config with /api proxy
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
```
## nginx.conf
```
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
## Adding the spring boot layer and react UI
docker-compose.yaml
```
services:
db:
image: myacr.azurecr.io/postgres:latest
build: db
environment:
- POSTGRES_DB=postgres
- POSTGRES_PASSWORD=password
expose:
- "5432"
ports:
- "5432:5432"
restart: always
app:
image: myacr.azurecr.io/springboot-app:latest
build: svc/rpsjpa
environment:
- POSTGRES_HOST=db
- POSTGRES_DB=rps
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
expose:
- "8080"
ports:
- "8080:8080"
depends_on:
- db
ui:
image: myacr.azurecr.io/rpsui:latest
build: ui
ports:
- "80:80"
depends_on:
- app
```
## Building and Pushing
```
docker compose build
docker compose push
```
## Updating the deploy-aci.yaml
```
apiVersion: 2019-12-01
location: eastus
name: fullStackContainerGroup
properties:
containers:
- name: db
properties:
image: myacr.azurecr.io/postgres:latest
environmentVariables:
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: password
- name: POSTGRES_DB
value: postgres
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 5432
- name: springboot-app
properties:
image: myacr.azurecr.io/springboot-app:latest
environmentVariables:
- name: POSTGRES_DB
value: postgres
- name: POSTGRES_PASSWORD
value: password
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 8080
- name: ui
properties:
image: myacr.azurecr.io/rpsui:latest
resources:
requests:
cpu: 1
memoryInGb: 1.5
ports:
- port: 80
osType: Linux
ipAddress:
type: Public
dnsNameLabel: fullStackDns # Add your desired DNS name label here
ports:
- protocol: tcp
port: 5432
- protocol: tcp
port: 8080
- protocol: tcp
port: 80
imageRegistryCredentials:
- server: myacr.azurecr.io
username: 00000000-0000-0000-0000-000000000000
password: yourpassword
tags: {exampleTag: tutorial}
type: Microsoft.ContainerInstance/containerGroups
```
- Update IP address of server
## Deploy to Azure
```
az container create --resource-group myResourceGroup --file deploy-aci.yaml
```