microsoft / DockerTools

Tools For Docker, including Visual Studio Provisioning and Publishing
Other
173 stars 26 forks source link

Publish single project when docker compose is enabled #349

Closed adeliab closed 1 year ago

adeliab commented 1 year ago

I have a solution containing multiple projects and I've enabled the docker support and docker compose for the solution. I'm deploying this applications as multiple container apps.

Before the docker compose was enabled, I can use the Publish functionality in VS to publish the image of a project to ACR.

After I've enabled docker compose, when I try to publish a single project to ACR, the publish failed.

image

As you see here I've set the image tag manually.

Looking at the build logs, it seems that the docker compose is used for this publish - because I see that it built the other projects in the docker compose as well.

And the publish error shows: Publish has encountered an error. Running the docker.exe tag command failed. Error response from daemon: No such image: xxxxxxxxxx:latest

Why does it try to find an image with tag latest and doesn't use the custom tag I've specified? How can I fix this?

And another question, when running the Debugger locally with docker-compose project, does it still target the base stage in each dockerfile build? Or does it build the full dockerfile?

adeliab commented 1 year ago

I managed to publish by commenting the DockerComposeProjectPath property in the project. But there should be another way, it's a hassle to do this everytime for each project

I also saw there's a publish target Container Apps in the publish profile but it's not possible for me to set custom image tag with this. Will this be added in the future?

ravipal commented 1 year ago

@adeliab, Due to historical reason, the publish to Container Registry uses Docker Compose build to generate the image which will generate the imagename:latest, then it will be tagged to custom tag specified in the publish dialog and pushed to Container Registry. To not use the compose build the current best option is to not define DockerComposeProjectPath in the web project, we will look into providing better options.

Looks like somehow the docker compose build is not generating the image name with latest tag and results into publish failure or the image itself is not created. Can you please share your complete build output, that would help us identify the issue?

And another question, when running the Debugger locally with docker-compose project, does it still target the base stage in each dockerfile build? Or does it build the full dockerfile?

When the build configuration is set to Debug (which is the default), the debugger will use base stage in dockerfile.

adeliab commented 1 year ago

@ravipal , when I want to publish 1 project I expect the docker compose only build that specific service and services it depends on though. But currently it builds all the services in the file

Attached is my build output: Build Output.txt

The project I want to publish is FaPoc.Alarm.Api But in the Build output I see it's also building FaPoc.Variable.Api and FaPoc.Public.Api

ravipal commented 1 year ago

Agree that it is a wired behavior that publishing a project uses docker-compose build, but that was the behavior from the start. Changing this may break existing scenarios/customers and I will look into updating this behavior. But this is not causing your publish failure.

Looks like you customized the docker-compose.yml to produce the image name to include docker compose project name like image: ${DOCKER_REGISTRY-}${COMPOSE_PROJECT_NAME-}_fapoc.api.alarm From the output I see the image with name docker.io/library/dockercompose9274409384541891387_fapoc.api.alarm:latest is generated. But not sure why your publish fails with message "No such image: xxxxxxxxxx:latest". Did the masked xxxxxxxxx match dockercompose9274409384541891387_fapoc.api.alarm? I tried a sample project similar to yours and with customization to image and I was able to publish to ACR successfully.

27 exporting layers done

27 writing image sha256:3f3aa33b6f6b14caf10d508e15d46748fdce36f7952fba00d8273934deedb75d done

27 naming to docker.io/library/dockercompose10467757167737078900_api.webapplication21 done

27 DONE 0.1s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== ========== Publish: 1 succeeded, 0 failed, 0 skipped ========== The push refers to repository [xxxxx.azurecr.io:443/dockercompose10467757167737078900_api.webapplication21] 840dba1a9e21: Preparing ... 531af3c69d62: Mounted from dockercompose10467757167737078900webapplication21 1.7.1: digest: sha256:df54614391e6292baa7fc71e7a75f3e572efcf43dcb3b8d31f9fff2d34f11c73 size: 1995 Successfully pushed docker image with tag '1.7.1'

Can you please share a sample repro project?

adeliab commented 1 year ago

it's not a problem to use docker-compose i think but would be nice if only the service being published is the only one being built so we don't have to wait for other services to be built which can take a while. maybe if we have a project property in the project and do docker-compose build service-name during publish instead of the whole file

About the image name, I removed the image name from the docker-compose file. A video I was watching about docker support for VS and VS code recommends to remove it so both VS and VS code can use the same docker-compose file. "They (VS and VS Code) name the images differently so you not be running the image you think you're running."

ravipal commented 1 year ago

Got the problem. If the image element is removed from docker-compose.yml then the docker-compose up command uses the default name which is the "compose project name_servicename:latest", but the publish expects the image name as "servicename:latest" and results into this publish failure.

Workaround is to specify the image in docker-compose.yml like image: ${DOCKER_REGISTRY-}webapplication1.

Meanwhile we will look into a way to not use docker-compose to publish a single image.

ravipal commented 1 year ago

@adeliab, Can you please share the video that suggested to remove the image from the docker compose document?

adeliab commented 1 year ago

@ravipal , it's actually a course in pluralsight called "Developing .NET Core 5 Apps with Docker" by Erik Dahl. If you have access to it, it's in the module "Simplify Complex Solutions with Docker Compose" and in lesson "Demo: Adding an ASP.NET MVC Project (UI) to Docker Compose (Visual Studio)", at time 00:20 he mentioned it.

image: ${DOCKER_REGISTRY-}webapplication1 I think this format was the autogenerated format from VS that I removed before. will it work in VS code & Rider as well? I want to work with a docker-compose that is IDE independent because our team members uses VS, VS code and Rider

ravipal commented 1 year ago

Thanks for sharing the video information.

image: ${DOCKER_REGISTRY-}webapplication1 allows you to specify the registry name through env variable. It will work in both VS and VS Code; I assume it will work in Rider as well. See https://docs.docker.com/compose/compose-file/#interpolation for more information. You could also simplify it as image: webapplication1.

adeliab commented 1 year ago

thanks @ravipal