#Have problems to build using Poetry?

1 messages Β· Page 1 of 1 (latest)

red wigeon
#

I'm very new for Dagger and trying to play around with it, the problem i hit are i'm trying to install my packages using Poetry but the problem are Poetry are not installed into my image i use, i can't install it its look like its a little different from Dagger to the normal way i do in Dockerfile.

Hope someone mabey can help me so i can coming out of me "start rabbiet hole" πŸ™‚

cedar zealot
red wigeon
#

yeah ofc, πŸ™‚ and good to see you here @cedar zealot thank for catch up on KubeCon πŸ˜„ i will share a sec, πŸ™‚

#

Its my demo code,

    @function
    def build_env(self, source: dagger.Directory) -> dagger.Container:
        """Build a ready-to-use development environment"""
        python_cache = dag.cache_volume("python")

        return (
            dag.container()
            .from_("python:3.12")
            .with_workdir("/app")
            .with_directory("/app/", source)
            # .with_mounted_cache("/root/.venv", python_cache)
            .with_exec(["poetry", "install"])
            .with_exec(["ls", "-la"])
        )
#

my folder structure is

service/src/service

and my poetry files are inside the first "service" folder

brittle cloud
#

I just added .with_exec(["pip", "install", "poetry"]) and it works for me πŸ™‚

red wigeon
#

Thanks, donno why i haven't tryed that XD mabey to tired in my head after KubeCon! πŸ˜„ thanks for both of you D:

red wigeon
#

I think its the first "dagger run" there shoud be the hardstes, now i fight with my build process, where i want to startup my fastapi services as a entrypoint and using the folder from build-env, πŸ™‚ i will add a comment inside here if i still fight with it later today πŸ˜„

red wigeon
#

a update, i can't get my fastapi services to run probley with Dagger my error is

Error: response from query: input: container.from.withDirectory.withMountedCache.withWorkdir.withExec.withExposedPort.withEntrypoint.asService.up resolve: failed to start host service: start upstream: service exited before healthcheck

and my build setps are

    @function
    def build(
        self, source: dagger.Directory, directory: str
    ) -> dagger.Container:  # dagger.Container
        python_cache = dag.cache_volume("python")

        """Build the application container"""
        build = self.build_env(source).directory(f"./{directory}")

        return (
            dag.container()
            .from_("python:3.12-slim")
            .with_directory("/app", build.directory(f"src/{directory}"))
            .with_mounted_cache("/root/.venv", python_cache)
            .with_workdir("/app")
            .with_exec(["ls", "-la"])
            .with_exposed_port(8000)
            .with_entrypoint(
                [
                    "uvicorn",
                    "--log-level",
                    "info",
                    "main:app",
                    "--host",
                    "0.0.0.0",
                ]
            )
        )

when i run the uvicorn inside local direclty into the terminal, everything runs good, its a demo fastapi script with this code so nothing spiceal.

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}
halcyon patio
#

Hi πŸ‘‹ You want with_default_args and as_service:

    @function
    def build(
        self,
        source: dagger.Directory, 
        directory: str,
    ) -> dagger.Service:
        python_cache = dag.cache_volume("python")

        """Build the application container"""
        build = self.build_env(source).directory(f"./{directory}")

        return (
            dag.container()
            .from_("python:3.12-slim")
            .with_directory("/app", build.directory(f"src/{directory}"))
            .with_mounted_cache("/root/.venv", python_cache)
            .with_workdir("/app")
            .with_exposed_port(8000)
            .with_default_args(
                [
                    "uvicorn",
                    "--log-level",
                    "info",
                    "main:app",
                    "--host",
                    "0.0.0.0",
                ]
            )
            .as_service()
        )

Note that if you add a with_exec before as_service, you'll have to add a with_exec([]) after. This is temporary, until https://github.com/dagger/dagger/issues/8140 is resolved.

GitHub

Summary I propose that asService always executes the entrypoint and default arguments, instead of only as a fallback. Background When we were close to releasing v0.12.0, we rushed to revert the &qu...

#

Btw @red wigeon, you're also missing the installation step in there for your app's dependencies, including uvicorn.

#

If you can share your Dockerfile, or parts of it that you may have trouble with, we can help with the equivalent code in Dagger.

red wigeon
#

My normal Dockerfile look like this, and its only thing i need now its to run its as service, but that part did not look like its working yet for me! πŸ˜„

normal i build a docker images and run it local after for testing, but this with Dagger looks much more nice and easier! πŸ˜„

FROM python:3.12 as builder

RUN pip install poetry

ENV POETRY_NO_INTERACTION=1 \
    POETRY_VIRTUALENVS_IN_PROJECT=1 \
    POETRY_VIRTUALENVS_CREATE=1 \
    POETRY_CACHE_DIR=/tmp/poetry_cache

ARG CODEARTIFACT_TOKEN

ENV CODEARTIFACT_TOKEN $CODEARTIFACT_TOKEN

WORKDIR /app

COPY pyproject.toml poetry.lock ./service/
RUN touch README.md
COPY --from=common ./ ./common

WORKDIR /app/service

RUN poetry config http-basic.aws aws $CODEARTIFACT_TOKEN
RUN --mount=type=cache,target=$POETRY_CACHE_DIR poetry install --no-dev

# Cleanup the images for production
FROM python:3.12-slim as runtime

ENV VIRTUAL_ENV=/app/service/.venv \
    PATH="/app/service/.venv/bin:$PATH"

COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
COPY src/service ./service

CMD [ "uvicorn", "--log-level", "warning", "--app-dir", "service", "main:app" ,"--host", "0.0.0.0" ]
brittle cloud
#

yep, something like...

from typing import Annotated

import dagger
from dagger import dag, DefaultPath, function, object_type

@object_type
class Tuna:
    @function
    def build(
        self,
        source: Annotated[dagger.Directory, DefaultPath("/")],
        #codeartifact_token: dagger.Secret,
    ) -> dagger.Container:
        """Build the application container"""
        builder = (
            dag.container()
            .from_("python:3")
            .with_exec(["pip", "install", "poetry"])
            .with_env_variable("POETRY_NO_INTERACTION", "1")
            .with_env_variable("POETRY_VIRTUALENVS_IN_PROJECT", "1")
            .with_env_variable("POETRY_VIRTUALENVS_CREATE", "1")
            .with_env_variable("POETRY_CACHE_DIR", "/tmp/poetry_cache")
            #.with_secret_variable("CODEARTIFACT_TOKEN", codeartifact_token)
            .with_directory("/app", source)
            .with_workdir("/app")
            #.with_directory("/app/service", source.directory("service"))
            #.with_directory("/app/common", source.directory("common"))
            #.with_workdir("/app/service")
            #.with_exec(["poetry", "config", "http-basic.aws", "aws", "$CODEARTIFACT_TOKEN"])
            .with_exec(["poetry", "install", "--no-dev"])
        )

        return (
            dag.container()
            .from_("python:3-slim")
            #.with_env_variable("VIRTUAL_ENV", "/app/service/.venv")
            .with_env_variable("VIRTUAL_ENV", "/app/.venv")
            #.with_env_variable("PATH", "/app/service/.venv/bin:$PATH")
            .with_env_variable("PATH", "/app/.venv/bin:$PATH")
            #.with_directory("/app/service/.venv", builder.directory("/app/service/.venv"))
            .with_directory("/app", builder.directory("/app"))
            .with_directory("/app/.venv", builder.directory("/app/.venv"))
            #.with_directory("/service", source.directory("src/service"))
        )

    @function
    def service(
        self,
        source: Annotated[dagger.Directory, DefaultPath("/")],
    ) -> dagger.Container:
        """Create a service from the built container"""
        return (
            self.build(source)
            .with_exposed_port(8000)
            .with_default_args([
                "uvicorn",
                "--log-level", "warning",
                "--app-dir", "/app",
                "main:app",
                "--host", "0.0.0.0"
            ])
        )
#

I just let the service function return a Container because you can still run up on it on the command line (sugar for as_service().up(), plus you can run terminal on it to check it out.

#

(I was experimenting with an AI model trained on our docs and daggerverse to see how it would do on your Dockerfile. Did pretty good, then I was trying to make it fit a simpler general case to test it. Here's the original (with a tiny tweak) in case it's more helpful:

import dagger
from dagger import dag, function, object_type

@object_type
class Tuna:
    @function
    def build(self, source: dagger.Directory, codeartifact_token: dagger.Secret) -> dagger.Container:
        """Build the application container"""
        builder = (
            dag.container()
            .from_("python:3.12")
            .with_exec(["pip", "install", "poetry"])
            .with_env_variable("POETRY_NO_INTERACTION", "1")
            .with_env_variable("POETRY_VIRTUALENVS_IN_PROJECT", "1")
            .with_env_variable("POETRY_VIRTUALENVS_CREATE", "1")
            .with_env_variable("POETRY_CACHE_DIR", "/tmp/poetry_cache")
            .with_secret_variable("CODEARTIFACT_TOKEN", codeartifact_token)
            .with_workdir("/app")
            .with_directory("/app/service", source.directory("service"))
            .with_directory("/app/common", source.directory("common"))
            .with_workdir("/app/service")
            .with_exec(["poetry", "config", "http-basic.aws", "aws", "$CODEARTIFACT_TOKEN"])
            .with_exec(["poetry", "install", "--no-dev"])
        )

        return (
            dag.container()
            .from_("python:3.12-slim")
            .with_env_variable("VIRTUAL_ENV", "/app/service/.venv")
            .with_env_variable("PATH", "/app/service/.venv/bin:$PATH")
            .with_directory("/app/service/.venv", builder.directory("/app/service/.venv"))
            .with_directory("/service", source.directory("src/service"))
        )

    @function
    def service(self, source: dagger.Directory) -> dagger.Service:
        """Create a service from the built container"""
        return (
            self.build(source)
            .with_exposed_port(8000)
            .with_default_args([
                "uvicorn",
                "--log-level", "warning",
                "--app-dir", "service",
                "main:app",
                "--host", "0.0.0.0"
            ]).as_service()
        )
red wigeon
#

It's still not working, and AI are not the way to try to convert a very simple sample based on my "orginal" Dockerfile, the code are more confuse then helping at the point.

i'm trying to get a very very simple fastapi up and running, and its a litte sad its so complicated to get up and running as so very simple example i have here

#

i hit the error all the time

βœ” DaggerTest.service(
    directory: "service"
    source: βœ” ModuleSource.resolveDirectoryFromCaller(path: "."): Directory! 0.0s
  ): Service! 10.6s
✘ Service.up(ports: [{frontend: null, backend: 8000, protocol: TCP}]): Void 0.7s
! failed to start host service: start upstream: exited: exit code: 2
#

so i think i do some thing wrong, but the error outout are very very bad, here is somethiung Dagger shoud optimize, becures i have no idea of why its give me a error, just a error, if its a build "startup failed" docker will give me this normal, and if its a build failed (i don't think so) i got this in docker build part, so i really need some help here to undertanding the log output becures now i have no idea of what happening,

#

i can buld the images success, but i don't see it in my docker desktop images, so its not visable and thats way i can't look into it to see whats going one πŸ˜’ so i'm very stuck right now and i just trying a very simple sample out here

halcyon patio
odd pasture
#

@red wigeon if you could connect to Dagger Cloud as Helder is suggesting via dagger login in the CLI or add -vvv to your dagger call command, that will give us more information to help you better troubleshoot this issue πŸ™

red wigeon