Okteto: Using docker-compose
Tags: kubernetes, okteto
Published: 2022-08-08 07:40:17

Okteto can understand and interpret docker-compose files into kubernetes objects. Let us understand with an example
```bash
❯ tree
.
├── Dockerfile
├── app.py
├── docker-compose.yaml
├── okteto.yml
└── requirements.txt

❯ cat Dockerfile
FROM python:3.11.0a6-alpine3.15

WORKDIR /code

COPY requirements.txt /code
RUN pip install -r requirements.txt --no-cache-dir
COPY . /code

EXPOSE 5000

CMD python app.py

❯ cat docker-compose.yaml
services:
  redis:
     image: redislabs/redismod
     ports:
       - '6379:6379'
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
    depends_on:
      - redis

❯ cat app.py
from flask import Flask, jsonify
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    counter = str(redis.get('hits'),'utf-8')
    return { "message": "This webpage has been viewed {} time(s)".format(counter)}

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

❯ cat requirements.txt
flask
redis
```
Let us instantiate with `okteto init`
```bash
❯ okteto init
 i  Using default @ kind-macbook as context
 ✓  Okteto manifest (okteto.yml) deploy and build configured successfully
 ?  Do you want to configure your development containers? [y/n]: y
 ✓  Development container 'redis' configured successfully
 ✓  Development container 'redisinsight' configured successfully
 ✓  Okteto manifest (okteto.yml) configured successfully
 i  Run 'okteto up' to activate your development container
```
Update the generated `okteto.yaml`
```bash

```

Activate DEV container and test
```bash
❯ okteto up
 i  Using default @ kind-macbook as context
 i  Development environment 'docker-compose' already deployed.
 i  To redeploy your development environment run 'okteto deploy' or 'okteto up [devName] --deploy'
 ✓  Development container 'web' selected
 i  Images were already built. To rebuild your images run 'okteto build' or 'okteto deploy --build'
 ✓  Images successfully pulled
 ✓  Files synchronized
    Context:   kind-macbook
    Namespace: default
    Name:      web
    Forward:   5000 -> 5000
    Reverse:   9000 <- 9000

/code # ls
Dockerfile           app.py               docker-compose.yaml  okteto.yml           requirements.txt
/code # python app.py
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Serving Flask app 'app'
 * Debug mode: on
 * Running on all addresses (0.0.0.0)
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://127.0.0.1:5000
 * Running on http://10.244.1.24:5000 (Press CTRL+C to quit)
 * Restarting with stat
 ...

# localhost
❯ curl localhost:5000
{
  "message": "This webpage has been viewed 1 time(s)"
}
```
Check the kubernetes objects created
```bash
❯ kubectl get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/redis-6fb6c999bd-v7bxw          1/1     Running   0          21h
pod/web-okteto-578ffd7b8c-79scd     1/1     Running   0          11m

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP    7d19h
service/redis          ClusterIP   10.96.197.159   <none>        6379/TCP   21h
service/web            ClusterIP   10.96.250.54    <none>        5000/TCP   21h

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/redis          1/1     1            1           21h
deployment.apps/web            0/0     0            0           21h
deployment.apps/web-okteto     1/1     1            1           21h

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/redis-6fb6c999bd          1         1         1       21h
replicaset.apps/web-6444f97788            0         0         0       21h
replicaset.apps/web-6c45f74b85            0         0         0       21h
replicaset.apps/web-8849d7c               0         0         0       11m
replicaset.apps/web-okteto-578ffd7b8c     1         1         1       11m
replicaset.apps/web-okteto-654fd944fd     0         0         0       21h
```
Stop the DEV container 
```bash
❯ okteto down
 i  Using default @ kind-macbook as context
 ✓  Development container 'web' selected
 ✓  Development container 'web' deactivated
```
Destroy deployment
```bash
❯ okteto destroy
 i  Using default @ kind-macbook as context
 ✓  Development environment 'docker-compose' successfully destroyed

```
###### Advanced configuration options
```bash
❯ cat docker-compose.yaml
services:
  redis:
     image: redislabs/redismod
     ports:
       - '6379:6379'
  web:
    # replica count
    scale: 2
    # environment variables (present in same dir as docker-compose.yaml)
    env_file: app.env
    # probe - command is also supported
    healthcheck:
      interval: 10s
      timeout: 10m
      retries: 5
      start_period: 30s
      http:
       path: /healthz
       port: 5000
    # annotations   
    labels:
      app: web
      label_one: value_one
    # resource requirements  
    deploy:
      resources:
        reservations:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 200m
          memory: 256Mi
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
    depends_on:
      - redis

❯ cat app.env
DEBUG=1
FOO=bar
```
Apply and verify
```bash
❯ okteto deploy
 i  Using default @ kind-macbook as context
 i  Images were already built. To rebuild your images run 'okteto build' or 'okteto deploy --build'
 ✓  Endpoint 'web' created
 ✓  Service 'redis' created
 ✓  Service 'web' created
 ✓  Compose 'docker-compose' successfully deployed
There are no available endpoints for 'docker-compose'
 ✓  Development environment 'docker-compose' successfully deployed
 i  Run 'okteto up' to activate your development container

❯ kubectl get pod web-7fb866df6c-jl4bx -o jsonpath='{.spec.containers[0].resources}{.spec.containers[0].env}{.metadata.annotations}{.spec.containers[0].readinessProbe}'
{"limits":{"memory":"256Mi"},"requests":{"memory":"128Mi"}}[{"name":"DEBUG","value":"1"},{"name":"FOO","value":"bar"}]{"app":"web","label_one":"value_one"}{"failureThreshold":5,"httpGet":{"path":"/healthz","port":5000,"scheme":"HTTP"},"initialDelaySeconds":30,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":600}%
```

###### TODO
- Volume mounts
- Conditions leading to init containers?