# Flask with MongoDB

import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs"

{/* vale off */}
{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */}


[Flask](https://flask.palletsprojects.com/en/stable/) is a lightweight WSGI web application framework in Python, and [MongoDB](https://www.mongodb.com/) is a NoSQL database that stores data in JSON-like documents.
This example deploys three services on Unikraft Cloud: Nginx (reverse proxy), Flask (backend), and MongoDB (database).

**Credits**: This example is based on this [Awesome Compose example](https://github.com/docker/awesome-compose/tree/master/nginx-flask-mongo).

## Deployment

To run this example, follow these steps:

1. Install the CLI.
   Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install).
   You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/).
   Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start).

   :::note
   The unikraft CLI is the current standard, while kraft is the legacy version.
   Choose one of the CLIs below and only run the commands associated with it for the rest of this guide.
   :::

2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/nginx-flask-mongo` directory:

```bash
git clone https://github.com/unikraft-cloud/examples
cd examples/nginx-flask-mongo/
```

Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you.
This guide uses `fra` (Frankfurt, 🇩🇪):

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft login
```

```bash title="kraft"
# Set Unikraft Cloud access token
export UKC_TOKEN=token
# Set metro to Frankfurt, DE
export UKC_METRO=fra
```

</CodeTabs>

## Create the volume

Create a volume for MongoDB data persistence:

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft volume create --metro=fra --name=mongo-data --size=1G
```

```bash title="kraft"
kraft cloud volume create --name mongo-data --size 1Gi
```

</CodeTabs>

The output shows the volume details:

<CodeTabs syncKey="cli">

```text title="unikraft"
metro:        fra
name:         mongo-data
uuid:         9c7723f3-7e1f-4e06-afe6-c811240faf5a
state:        [92mavailable[0m
size:         1GiB
filesystem:   ext4
quota-policy: static
persistent:   true
timestamps:
  created:    just now
```

```ansi title="kraft"
[1mNAME[0m        [1mCREATED AT[0m  [1mSIZE[0m     [1mATTACHED TO[0m  [1mMOUNTED BY[0m  [1mSTATE[0m      [1mPERSISTENT[0m
mongo-data  now         1.0 GiB                           available  true
```

</CodeTabs>

## Deploy MongoDB

First, deploy the MongoDB instance.
MongoDB is an internal service (not publicly accessible), reached via the `mongo.internal` domain:

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft build ./mongo --output <my-org>/mongo:latest
unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -m 1024M --image <my-org>/mongo:latest --domain mongo.internal --volume mongo-data:/data/db
```

```bash title="kraft"
kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -M 1024Mi --domain mongo.internal --volume mongo-data:/data/db ./mongo
```

</CodeTabs>

The output shows the MongoDB instance details:

<CodeTabs syncKey="cli">

```text title="unikraft"
metro:           fra
name:            mongo-o3qhq
uuid:            90158c53-6654-4e73-bad1-1d6ab4452001
state:           [92mstarting[0m
image:           <my-org>/mongo
resources:
  memory:        1GiB
  vcpus:         1
service:
  name:          restless-glade-l8pu2mf0
  uuid:          77a04441-2479-433a-b468-32f23e475f58
  domains:
  - fqdn:        mongo.internal
volumes:
- name:          mongo-data
  uuid:          9c7723f3-7e1f-4e06-afe6-c811240faf5a
  at:            /data/db
networks:
- uuid:          4f891227-d381-42f4-88a4-25a97b95a9e3
  private-ip:    10.0.15.21
  mac:           12:b0:0a:00:0f:15
timestamps:
  created:       just now
scale-to-zero:
  enabled:       true
  policy:        idle
  stateful:      true
  cooldown-time: 1s
```

```ansi title="kraft"
[90m[[0m[92m●[0m[90m][0m Deployed successfully!
 [90m│[0m
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mname[0m: mongo-hwoaz
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90muuid[0m: 56d43696-af3e-4ccb-aa81-9ae872b7bf43
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mmetro[0m: https://api.fra.unikraft.cloud/v1
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mstate[0m: [92mstarting[0m
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mdomain[0m: mongo.internal
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mimage[0m: oci://unikraft.io/<my-org>/mongo@sha256:68894454735e0e5b07d61aad19b1c03355f415ec33c050daeaa419d931962657
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mmemory[0m: 1024 MiB
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mservice[0m: shy-field-y89vrq32
 [90m├[0m[90m─[0m [90mprivate fqdn[0m: mongo-hwoaz.internal
 [90m└[0m[90m─[0m[90m─[0m[90m─[0m [90mprivate ip[0m: 10.0.0.29
```

</CodeTabs>

## Deploy Flask

Next, deploy the Flask backend.
It connects to MongoDB using the `MONGO_SERVER_URL` environment variable and is reached internally via `backend.internal`:

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft build ./flask --output <my-org>/flask:latest
unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -m 1024M --image <my-org>/flask:latest --domain backend.internal --env FLASK_SERVER_PORT=9091 --env MONGO_SERVER_URL=mongo.internal:27017
```

```bash title="kraft"
kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -M 1024Mi --domain backend.internal --env FLASK_SERVER_PORT=9091 --env MONGO_SERVER_URL=mongo.internal:27017 ./flask
```

</CodeTabs>

The output shows the Flask instance details:

<CodeTabs syncKey="cli">

```text title="unikraft"
metro:                 fra
name:                  flask-9a68z
uuid:                  bb6d91f7-0714-45e5-b14a-ec82a5dac36e
state:                 [92mstarting[0m
image:                 <my-org>/flask
runtime:
  env:
    FLASK_SERVER_PORT: 9091
    MONGO_SERVER_URL:  mongo.internal:27017
resources:
  memory:              1GiB
  vcpus:               1
service:
  name:                broken-bird-8isa6q21
  uuid:                cd9fe757-784a-49d4-8936-1b6859b3a72d
  domains:
  - fqdn:              backend.internal
networks:
- uuid:                2da7f679-7067-4fb5-908b-853607d383f2
  private-ip:          10.0.17.97
  mac:                 12:b0:0a:00:11:61
timestamps:
  created:             just now
scale-to-zero:
  enabled:             true
  policy:              on
  cooldown-time:       1s
```

```ansi title="kraft"
[90m[[0m[92m●[0m[90m][0m Deployed successfully!
 [90m│[0m
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mname[0m: flask-1xnsj
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90muuid[0m: edc8e61d-ef6c-4c05-9de3-6983539a47d2
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mmetro[0m: https://api.fra.unikraft.cloud/v1
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mstate[0m: [92mstarting[0m
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mdomain[0m: backend.internal
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mimage[0m: oci://unikraft.io/<my-org>/flask@sha256:f23b3368cd777acae68ad8f35713a4cf55f901d6c266017bf6f0679ffc7a8172
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mmemory[0m: 1024 MiB
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mservice[0m: falling-mountain-pcx804jx
 [90m├[0m[90m─[0m [90mprivate fqdn[0m: flask-1xnsj.internal
 [90m└[0m[90m─[0m[90m─[0m[90m─[0m [90mprivate ip[0m: 10.0.0.17
```

</CodeTabs>

## Deploy Nginx

Finally, deploy Nginx as the public-facing reverse proxy.
It forwards requests to the Flask backend at `backend.internal:9091`:

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft build ./nginx --output <my-org>/nginx:latest
unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:80/tls+http -m 512M --image <my-org>/nginx:latest
```

```bash title="kraft"
kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:80/tls+http -M 512Mi ./nginx
```

</CodeTabs>

The output shows the Nginx instance details including its public FQDN:

<CodeTabs syncKey="cli">

```text title="unikraft"
metro:           fra
name:            nginx-jnpwi
uuid:            57f64e99-bd06-46fd-98f4-26b64751623e
state:           [92mstarting[0m
image:           <my-org>/nginx
resources:
  memory:        512MiB
  vcpus:         1
service:
  name:          snowy-river-gotjeojl
  uuid:          287ee3b8-43bc-47d1-a88e-4d6c72d2d682
  domains:
  - fqdn:        snowy-river-gotjeojl.fra.unikraft.app
networks:
- uuid:          107e4a03-e285-4d1d-84cb-24f86d7af875
  private-ip:    10.0.14.201
  mac:           12:b0:0a:00:0e:c9
timestamps:
  created:       just now
scale-to-zero:
  enabled:       true
  policy:        on
  cooldown-time: 1s
```

```ansi title="kraft"
[90m[[0m[92m●[0m[90m][0m Deployed successfully!
 [90m│[0m
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mname[0m: nginx-psndr
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90muuid[0m: 5ca29c9b-24de-4fa7-800e-a13175a909b1
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mmetro[0m: https://api.fra.unikraft.cloud/v1
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mstate[0m: [92mstarting[0m
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mdomain[0m: https://nameless-shadow-f7ywg1l4.fra.unikraft.app
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mimage[0m: oci://unikraft.io/<my-org>/nginx@sha256:8cff54392eeead80bafe33538866b04bfd076f2052d65cb3751a938a22368bc0
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mmemory[0m: 512 MiB
 [90m├[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m[90m─[0m [90mservice[0m: nameless-shadow-f7ywg1l4
 [90m├[0m[90m─[0m [90mprivate fqdn[0m: nginx-psndr.internal
 [90m└[0m[90m─[0m[90m─[0m[90m─[0m [90mprivate ip[0m: 10.0.0.1
```

</CodeTabs>

You can list all deployed instances with:

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft instances list
```

```text title="unikraft"
[1mMETRO[0m  [1mNAME[0m           [1mSTATE[0m    [1mIMAGE[0m            [1mMEMORY[0m  [1mVCPUS[0m  [1mFQDN[0m                                       [1mCREATED[0m
fra    nginx-jnpwi    [94mstandby[0m  <my-org>/nginx   512MiB  1      snowy-river-gotjeojl.fra.unikraft.app      11 minutes ago
fra    flask-9a68z    [94mstandby[0m  <my-org>/flask   1GiB    1      backend.internal                           12 minutes ago
fra    mongo-o3qhq    [94mstandby[0m  <my-org>/mongo   1GiB    1      mongo.internal                             14 minutes ago
```

```bash title="kraft"
kraft cloud instance list
```

```ansi title="kraft"
[1mNAME[0m         [1mFQDN[0m                                          [1mSTATE[0m    [1mSTATUS[0m       [1mIMAGE[0m                                        [1mMEMORY[0m   [1mVCPUS[0m  [1mARGS[0m  [1mBOOT TIME[0m
nginx-psndr  nameless-shadow-f7ywg1l4.fra.unikraft.app     [94mstandby[0m  standby      oci://unikraft.io/<my-org>/nginx@sha256:...   512 MiB  1            83.87 ms
flask-1xnsj  backend.internal                              [92mrunning[0m  since 2mins  oci://unikraft.io/<my-org>/flask@sha256:...   1.0 GiB  1            1916.54 ms
mongo-hwoaz  mongo.internal                                [92mrunning[0m  since 5mins  oci://unikraft.io/<my-org>/mongo@sha256:...   1.0 GiB  1            2776.86 ms
```

</CodeTabs>

## Test the deployment

The FQDN of the Nginx instance can be found in the `FQDN` column of the `unikraft instances list` output above.
Use `curl` to query it (replace with your actual FQDN):

```bash
curl https://<FQDN>
```

```text
Hello from the MongoDB client!
```

## Clean up

When done, remove the instances and volume:

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft instances delete mongo-o3qhq flask-9a68z nginx-jnpwi
unikraft volume delete mongo-data
```

```bash title="kraft"
kraft cloud instance remove mongo-hwoaz flask-1xnsj nginx-psndr
kraft cloud volume remove mongo-data
```

</CodeTabs>

## Learn more

Use the `--help` option for detailed information on using Unikraft Cloud:

<CodeTabs syncKey="cli">

```bash title="unikraft"
unikraft --help
```

```bash title="kraft"
kraft cloud --help
```

</CodeTabs>

Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview).

- [Flask Documentation](https://flask.palletsprojects.com/en/stable/)
- [MongoDB Documentation](https://www.mongodb.com/docs/)
- [Nginx Documentation](https://nginx.org/en/docs/)
- [Awesome Compose](https://github.com/docker/awesome-compose)
- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/)
- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit)
{/* vale on */}
