kamal icon indicating copy to clipboard operation
kamal copied to clipboard

Skip building an deploy some public docker image (listed at Docker Hub)

Open meglio opened this issue 2 years ago • 25 comments
trafficstars

I could not find where the documentation explains how to make Kamal skip the "build" step and just deploy some docker image found at the public Docker Hub.

image

meglio avatar Sep 25 '23 10:09 meglio

I think I found it in the Config section:

image

meglio avatar Sep 25 '23 10:09 meglio

Still, it is looking for some Dockerfile. Can it do without it and just use the public docker image?

image

meglio avatar Sep 25 '23 13:09 meglio

Try to use the --skip-push option, seems to be doing what you are searching for.

Edit: I've done some further testing today, it seems --skip-push only works for the deploy and redeploy commands. The setup ends calling the deploy command and it doesn't support that...

danthrue avatar Oct 11 '23 20:10 danthrue

This would be really helpful even when you already have a built private image (from the same ghcr.io registry that you use in deploy.yml).

I would image the deploy.yml having something like this as an option:

builder:
  disable: true

akoskovacs avatar Dec 19 '23 03:12 akoskovacs

I'm in the same boat and also need to skip the builder step. As my workflow requires to run rails tests and linters successfully before pushing it to ghcr registry. With the current solution I would build the image twice.

on:
  push:
    branches: [ main ]

jobs:
  build-test-push:
    runs-on: ubuntu-latest

    permissions:
      contents: read
      packages: write

    steps:
      - name: check out repository
        uses: actions/checkout@v4

      - name: set up docker buildx
        uses: docker/setup-buildx-action@v3

      - name: build & cache Docker image
        uses: docker/build-push-action@v5
        with:
          load: true
          tags: ${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: run Rails tests & linter
        run: docker-compose -f docker-compose.ci.yml up --abort-on-container-exit

      - name: log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ github.token }}

      - name: push Docker image to GitHub Container Registry
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}

  #__DEPLOY

bitsmyth avatar Dec 27 '23 16:12 bitsmyth

I'm also trying to deploy a public image with kamal and encounter some of the same issues.

Even with kamal deploy -P, kamal will try to get an image that has been tagged with the current commit sha. Even with kamal deploy -P --version=v0.48.1, kamal will fail because the image does not have the service label

I think I'll have to create a one-line Dockerfile that is just a FROM some/publicimage to bypass this but it would be so so great to be able to easily release any public docker image with kamal

Intrepidd avatar Jan 02 '24 11:01 Intrepidd

I am evaluating kamal for my use-case but I'm having the same problem. My build process generates an image already, I just want to release it. Making the build process optional for the entire workflow would be great.

flozano avatar Jan 07 '24 17:01 flozano

Same issue for me. Not having the ability to skip build step makes Kamal nearly useless for public images

spryffee avatar Jan 12 '24 21:01 spryffee

This is a feature Kamal is desperately missing.

I have made an open source rails app and have been trying to figure out how to best simplify deployment for other people. At present using DockerHub + Kamal would require sharing my password with the entire world.

Please add a no-login option.

RyanMcCoskrie avatar Jan 28 '24 20:01 RyanMcCoskrie

What I'm doing currently is creating a dummy busybox container for a placeholder in the service so I can deploy public docker images as an accessory.

Dockerfile example:

FROM busybox:1.36.1

CMD ["tail", "-f", "/dev/null"]

kamal-config example:

# Name of your application. Used to uniquely configure containers.
service: kamal-test

# Name of the container image.
image: <registry-username>/kamal-test

servers:
  - 1.1.1.1

registry:
  username: <registry-username>
  password:
    - KAMAL_REGISTRY_PASSWORD

ssh:
  user: <ssh-user>

accessories:
  app:
    image: nginx:1.24.0
    host: 1.1.1.1
    port: 127.0.0.1:8080:80
    files:
      - nginx.conf:/etc/nginx/nginx.conf

# Since the dummy service is not serving anything, healthcheck is set to true.
# probably there are other ways to optimize this to get true healthcheck (proxying healthcheck to "app" accessory)
healthcheck:
  cmd: /bin/true

sulo1337 avatar Feb 11 '24 19:02 sulo1337

Kamal is a wonderful tool, too bad it does not provide this capacity yet

While using --skip-push, a very minimal change here would make it all work.

It could just accepts something from the cli (like --tagged-image xyz:latest) and skip the build

benbonnet avatar Mar 03 '24 17:03 benbonnet

Kamal is a wonderful tool, too bad it does not provide this capacity yet

While using --skip-push, a very minimal change here would make it all work.

It could just accepts something from the cli (like --tagged-image xyz:latest) and skip the build

please make a pull request!

acidtib avatar Mar 04 '24 05:03 acidtib

@acidtib I did a very simple hack in a fork here. Passing a new arg would require awkward changes, so either ENV["TAGGED_IMAGE"] or static tagged_image key at the top level. Still coupled with --skip-push

To be honest, by looking at the code, the "deploy local code only" is deeply rooted. Coupled with the fact that each elements in the servers: block use the same image

IMHO a good refactor would be to prioritize the requirement discussed in this issue (which would make the concept of accessories pointless somehow), and falling back to the current existing behaviour (local code build/push)

A possibility would be to allow primary_role to accept an accessory, but then servers could be empty.

Anyways, those are personal thought; there might be other ways. But overall it feels like things were heavily focused on building your current code, nothing else

benbonnet avatar Mar 04 '24 10:03 benbonnet

Seems like you can achieve this with the VERSION env var combined with -P. This is the command I use to deploy the latest image (already built for staging) to production:

VERSION=latest kamal deploy -P -d production

joelcogen avatar Apr 15 '24 06:04 joelcogen

Kamal requires that images are labeled with the service, so that it can identify them when pruning.

So right now you can't deploy arbitrary public images. If you have an external image that you've built yourself with the service label, then you can either also tag it with the appropriate git SHA or use @joelcogen's suggestion to override the version.

djmb avatar May 02 '24 11:05 djmb

Seems like you can achieve this with the VERSION env var combined with -P. This is the command I use to deploy the latest image (already built for staging) to production:

VERSION=latest kamal deploy -P -d production

Did you get this to work to deploy the latest image.

I am doing:

./gradlew bootBuildImage && VERSION=latest; kamal deploy -P

but getting:

docker stderr: Error response from daemon: manifest for XX/YY:a4da0e855e22e06611c6b4a1ea5f76ebdec20411_uncommitted_419e2abc190b3302 not found: manifest unknown: manifest unknown

The docker image built with bootBuildImage pushed to docker hub is 191 MB Vs. 291 MB that Kamal builds with Docker "out of the box", so it would be good to be able to simply deploy the latest image.

gregjotau avatar Jun 19 '24 13:06 gregjotau

@gregjotau - does it work if you remove the ; after VERSION=latest?

djmb avatar Jun 19 '24 13:06 djmb

@gregjotau - does it work if you remove the ; after VERSION=latest?

Thanks for the quick response!

Then I get: docker stdout: Image XX/YY:latest is missing the 'service' label docker stderr: Nothing written

gregjotau avatar Jun 19 '24 13:06 gregjotau

That's a requirement of Kamal, you'll need to add a label called "service" to your image. The value should be the same as the service in your Kamal configuration.

djmb avatar Jun 19 '24 14:06 djmb

That's a requirement of Kamal, you'll need to add a label called "service" to your image. The value should be the same as the service in your Kamal configuration.

Yep, figured it out and worked when adding: environment.set(mapOf("BP_IMAGE_LABELS" to "service="XX"")) in config

Thanks!

gregjotau avatar Jun 19 '24 14:06 gregjotau

Was anybody able to make this work with kamal2? Tried adding the label, and deploying with kamal deploy -P.

Part of my deploy.yml:

service: gotenberg

image: gotenberg/gotenberg:8

labels:
  service: gotenberg

Kamal still tries to log in to the registry every time.

JUVOJustin avatar Oct 10 '24 20:10 JUVOJustin

This still hasn’t been fixed after a year? I build an image using GitHub Actions and then push it to GitHub’s registry. I don’t want Kamal to build anything. It’s strange that I can’t skip this step.

denisorehovsky avatar Oct 16 '24 03:10 denisorehovsky

Seems like you can achieve this with the VERSION env var combined with -P. This is the command I use to deploy the latest image (already built for staging) to production:

VERSION=latest kamal deploy -P -d production

@joelcogen Thanks, this was useful. I've been trying for ages to build an image in Github Actions and then deploy it from my Macbook without having to rebuild it locally. I ended up with VERSION=$(git rev-parse HEAD) kamal deploy -P.

jdelStrother avatar Oct 18 '24 16:10 jdelStrother

Proving impossible to deploy pihole/pihole image to a local Pi using kamal2. From reading these posts it seems that I need to build my own image of pihole, label it to match the service, push it back to dockerhub and then deploy. But the issue then is that the sha1 from my local git repository (which I had to create as kamal2 insists on using git to determine the latest version) doesn't match the tag on dockerhub.

Am I going down the completely wrong rabbit hole with this? It doesn't feel natural.

isteel avatar Oct 19 '24 12:10 isteel

It's a hard requirement of Kamal right now that images have the service label, so we can identify them when pruning.

We could switch that to filtering by reference instead and drop the requirement, then we could deploy any image which would definitely be nice to be able to do.

Not completely straightforward though. If someone is deploying multiple apps to a server using the same image, we'd need to make sure app A doesn't try to prune images used by app B.

djmb avatar Oct 22 '24 11:10 djmb