diff --git a/examples/fastapi0.116.0-python3.12-base/.dockerignore b/examples/fastapi0.116.0-python3.12-base/.dockerignore new file mode 100644 index 00000000..fda68d74 --- /dev/null +++ b/examples/fastapi0.116.0-python3.12-base/.dockerignore @@ -0,0 +1,4 @@ +/.unikraft/ +/Kraftfile +/Dockerfile +/README.md diff --git a/examples/fastapi0.116.0-python3.12-base/.gitignore b/examples/fastapi0.116.0-python3.12-base/.gitignore new file mode 100644 index 00000000..1b8123b9 --- /dev/null +++ b/examples/fastapi0.116.0-python3.12-base/.gitignore @@ -0,0 +1 @@ +/.unikraft/ diff --git a/examples/fastapi0.116.0-python3.12-base/Dockerfile b/examples/fastapi0.116.0-python3.12-base/Dockerfile new file mode 100644 index 00000000..cfbd3bf9 --- /dev/null +++ b/examples/fastapi0.116.0-python3.12-base/Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.12 AS base + +WORKDIR /app + +COPY requirements.txt . + +RUN pip3 install --no-cache-dir -r requirements.txt + +FROM scratch + +# System libraries +COPY --from=base /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/ +COPY --from=base /lib/x86_64-linux-gnu/libpthread.so.0 /lib/x86_64-linux-gnu/ +COPY --from=base /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/ +COPY --from=base /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/ +COPY --from=base /lib/x86_64-linux-gnu/libz.so.1 /lib/x86_64-linux-gnu/ +COPY --from=base /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/ +COPY --from=base /lib64/ld-linux-x86-64.so.2 /lib64/ +COPY --from=base /lib/x86_64-linux-gnu/librt.so.1 /lib/x86_64-linux-gnu/librt.so.1 +COPY --from=base /usr/lib/x86_64-linux-gnu/libssl.so.3 /usr/lib/x86_64-linux-gnu/libssl.so.3 +COPY --from=base /usr/lib/x86_64-linux-gnu/libcrypto.so.3 /usr/lib/x86_64-linux-gnu/libcrypto.so.3 + +# Python +COPY --from=base /usr/local/lib/python3.12 /usr/local/lib/python3.12 +COPY --from=base /usr/local/bin/python3 /usr/local/bin/python3 +COPY --from=base /usr/local/lib/libpython3.12.so.1.0 /usr/local/lib/libpython3.12.so.1.0 + +# App +COPY ./server.py /app/server.py diff --git a/examples/fastapi0.116.0-python3.12-base/Kraftfile b/examples/fastapi0.116.0-python3.12-base/Kraftfile new file mode 100644 index 00000000..de89ec33 --- /dev/null +++ b/examples/fastapi0.116.0-python3.12-base/Kraftfile @@ -0,0 +1,9 @@ +spec: v0.6 + +name: fastapi0.116.0-python3.12-base + +runtime: base:latest + +rootfs: ./Dockerfile + +cmd: ["/usr/local/bin/python3", "/app/server.py"] diff --git a/examples/fastapi0.116.0-python3.12-base/README.md b/examples/fastapi0.116.0-python3.12-base/README.md new file mode 100644 index 00000000..085bdcd2 --- /dev/null +++ b/examples/fastapi0.116.0-python3.12-base/README.md @@ -0,0 +1,64 @@ +# Python FastAPI Web Server + +This directory contains a Python 3.12 [`FastAPI`](https://fastapi.tiangolo.com/) web server using ['Uvicorn'](https://www.uvicorn.org/) running on Unikraft. + +## Set Up + +To run this example, [install Unikraft's companion command-line toolchain `kraft`](https://unikraft.org/docs/cli), clone this repository and `cd` into this directory. + +## Run and Use + +Use `kraft` to run the image and start a Unikraft instance: + +```bash +kraft run --rm -p 8080:8080 --plat qemu --arch x86_64 -M 512M . +``` + +If the `--plat` argument is left out, it defaults to `qemu`. +If the `--arch` argument is left out, it defaults to your system's CPU architecture. + +Once executed, it will open port `8080` and wait for connections. +To test it, you can use `curl`: + +```bash +curl localhost:8080 +``` + +You should see a "Bye, World!" message. + +## Inspect and Close + +To list information about the Unikraft instance, use: + +```bash +kraft ps +``` + +```text +NAME KERNEL ARGS CREATED STATUS MEM PORTS PLAT +nifty_bubbles oci://unikraft.org/python:3.12 /usr/bin/python3 /app/server.py 11 seconds ago running 488M 0.0.0.0:8080->8080/tcp qemu/x86_64 +``` + +The instance name is `nifty_bubbles`. +To close the Unikraft instance, close the `kraft` process (e.g., via `Ctrl+c`) or run: + +```bash +kraft rm nifty_bubbles +``` + +Note that depending on how you modify this example your instance **may** need more memory to run. +To do so, use the `kraft run`'s `-M` flag, for example: + +```bash +kraft run --rm -p 8080:8080 --plat qemu --arch x86_64 -M 1024M . +``` + +## `kraft` and `sudo` + +Mixing invocations of `kraft` and `sudo` can lead to unexpected behavior. +Read more about how to start `kraft` without `sudo` at [https://unikraft.org/sudoless](https://unikraft.org/sudoless). + +## Learn More + +- [How to run unikernels locally](https://unikraft.org/docs/cli/running) +- [Building `Dockerfile` Images with `BuildKit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) diff --git a/examples/fastapi0.116.0-python3.12-base/requirements.txt b/examples/fastapi0.116.0-python3.12-base/requirements.txt new file mode 100644 index 00000000..550ebdce --- /dev/null +++ b/examples/fastapi0.116.0-python3.12-base/requirements.txt @@ -0,0 +1,2 @@ +fastapi==0.116.0 +uvicorn==0.23.2 diff --git a/examples/fastapi0.116.0-python3.12-base/server.py b/examples/fastapi0.116.0-python3.12-base/server.py new file mode 100644 index 00000000..f2467452 --- /dev/null +++ b/examples/fastapi0.116.0-python3.12-base/server.py @@ -0,0 +1,11 @@ +from fastapi import FastAPI +import uvicorn + +app = FastAPI() + +@app.get("/") +def hello(): + return "Bye, World!" + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8080)