Documentation on my success to deploy web application to a featured Kubernetes environment.
Tags: docker, kubernetes, deploy
Published: 2023-05-21 22:18:51

### Prerequisites
- Download and Install Docker 
- Download and install Docker desktop
- IDE (Visual Studio Code)
- Sign-up to Docker Hub 
- Install compose plugin

### Get app
- Cloned node.js todo wep app [github](https://github.com/Mokhutso-dev/containerise-todo) 

### Build the app’s container image
- In the app directory created a Dockerfile
- Added the folowing content to the Dockerfile [image]
- Build the container image `docker build -t sca-project`
- Started the app container `docker run -dp 3000:3000 sa-project`
- Opened web browser to [localhost](http://localhost:3000) to see the app

![localhost3000](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ybktqg30vjhsj28hh37w.png)

### Share application

- Created docker repository [image] on Docker Hub [docker-repo](https://hub.docker.com/r/mokhutso/sca-project/tags)
- `Docker login -u my_username`
- `docker tag sca-project my_username/sca-project`
- `docker push my_username/sca-project`

### Persist the database
- `docker volume create todo-db`
- `docker run -dp 3000:3000 –mount type-volume, src=todo-db,target=/etc/todos sa-project`
- Got to see my list being stored 
- `docker volume inspect todo-db` 
 
### Run app in a development container with a bind mount

```
docker run -dp 3000:3000 \
    -w /app --mount type=bind,src="$(pwd)",target=/app \
    node:18-alpine \
    sh -c "yarn install && yarn run dev"
```

```
docker run -dp 3000:3000 `
    -w /app --mount "type=bind,src=$pwd,target=/app" `
    node:18-alpine `
    sh -c "yarn install && yarn run dev"
```

- `docker logs -f <container-id>`
- Make changes to app.js , save file (restarts the app inside the container automatically)
- Refresh the pages and saw my changes being reflected almost immediately

### Multi container apps

- `docker network create todo-app`
- ```
docker run -d \
     --network todo-app --network-alias mysql \
     -v todo-mysql-data:/var/lib/mysql \
     -e MYSQL_ROOT_PASSWORD=secret \
     -e MYSQL_DATABASE=todos \
     mysql:8.0
```

- `docker exec -it <my-sql-container-id> myqsl -u root -p`
- Into mysql shell -> show databases; (don’t forget the semi-colons or else nothing will be displayed)
- `Exit` the mysql shell

### Connect mysql

- `docker network create todo-app`
- ```
docker run -d `
     --network todo-app --network-alias mysql `
     -v todo-mysql-data:/var/lib/mysql `
     -e MYSQL_ROOT_PASSWORD=secret `
     -e MYSQL_DATABASE=todos `
     mysql:8.0
```

- `Docker logs -f <container-id>`
- `docker exec -it <my-sql-container-id> myqsl -p todos`

![mysql](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8agb3r8kmjhd20nxo20.png)
- Into mysql shell -> `select * from todos_items`
- `Exit` the mysql shell
### Docker compose

- `docker compose version`
- In the root folder created docker-compose.yml
- Insert into docker-compose.yml file 
```
services:
```
### Define the app service

- docker-compose.yml file should look like:

```
services:
  app:
    image: node:18-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:8.0
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:
```


### Run the application stack

- `docker compose up -d`
- See the app stack in docker desktop dashboard
### Describe apps using kubernetes yaml 

- Create deployment.yaml in the app root folder
- Fill deploment.yaml with this code 

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bb-demo
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      bb: web
  template:
    metadata:
      labels:
        bb: web
    spec:
      containers:
      - name: bb-site
        image: getting-started
        imagePullPolicy: Never
---
apiVersion: v1
kind: Service
metadata:
  name: bb-entrypoint
  namespace: default
spec:
  type: NodePort
  selector:
    bb: web
  ports:
  - port: 3000
    targetPort: 3000
    nodePort: 30002
```
### Create and monitor deployment

- Enabled Kubernetes on Docker Desktop setting
- `Kubectl apply -f deplyment.yaml`
- `Kubectl rollout status deployment/app-deployment`

![deploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/04d48w5eslix3dvn1kt9.png)

- Now can access the app with the yaml configuration nodePort :30002

![30002](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1u12bxy1r3pzduvlb4w.png)
- `Kubectl get deployments` -> view pods configured by yaml file]
- `Kubectl get pods`
- `Kubectl get services`
- `Kubectl describe deploments`

![monitor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wls4xwibu9ho3dyxva18.png)
### Scale deployment

- `Kubectl scale deployment/app-deployment –replicas=3`
- Horizontal pod autoscaling
- `Kubectl autoscale deployment/app-deployment –min=3 –max–10 –cpu-percentage=80`

![scaling](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ru6x0bfrcc67l01v8lul.png)