Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: Build local docker image #1175

Open
3 tasks done
silverwind opened this issue Sep 7, 2022 · 15 comments
Open
3 tasks done

Idea: Build local docker image #1175

silverwind opened this issue Sep 7, 2022 · 15 comments
Labels
cache proposals ideas for make caching work seamles

Comments

@silverwind
Copy link
Contributor

silverwind commented Sep 7, 2022

Clear and concise description of the problem

Docker-based CI systems have an inherent flaw that it's not possible to pre-define an environment for steps/pipelines, so system-wide tools/languages have to be installed again and again into individual steps/pipelines which is a waste of resources and time.

Suggested solution

The CI could provide the ability to build docker images that are only available locally on the system, keyed and cached on the resulting image name. Build should be skipped if an image with the name already exists on the system.

In a file outside of pipelines:

build-images:
  - name: ci.local/golang-1.19-node-18:1
    image: golang:1.19
    commands:
      - curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get -qqy install nodejs

Pipeline using the built image:

pipeline:
  deps:
    image: ci.local/golang-1.19-node-18:1
    commands:
      npm install
      go mod download

Alternative

The alternative is to create and publish these images to a docker registry, but this brings a lot of extra burden in keeping these images up-to-date which many are not willing to do.

Validations

@6543 6543 added the cache proposals ideas for make caching work seamles label Sep 7, 2022
@silverwind
Copy link
Contributor Author

silverwind commented Sep 7, 2022

Actually, thinking about it again, this should be possible with the docker plugin and a Dockerfile in the repo. Certainly not as convenient to configure as above but I think it'd probably be a lot of work to support this in woodpecker as it has no registry, for example.

@6543 6543 reopened this Sep 7, 2022
@6543
Copy link
Member

6543 commented Sep 7, 2022

let's collect cache proposals and then decide ... but that will not be in next release ...

@reivilibre
Copy link

This would be an absolute 'killer' feature and I would love to have it.

My current workaround is to have a separate repo of dockerfiles and have CI which publishes those to a private registry, but it's so clunky and it means that my project repos aren't self-contained.

CI performance would be much much faster if I could define an image within the Woodpecker YAML that would be built as needed and cached otherwise, precisely for installing packages or compiling build tools... :)

@lafriks
Copy link
Contributor

lafriks commented Sep 24, 2022

Maybe woodpecker server could provide temporary docker registry for docker build images? This would also allow testing built images in separate pipeline and starting them as services.

There could be option on how long images in that registry should be kept either only as long as pipeline is running (temporary) or deleted when not used anymore for some period of time

@silverwind
Copy link
Contributor Author

Yeah, I guess an option like LOCAL_IMAGE_RETENTION_TIME could be used, default it to something like 2 months, and if a local image is unused for such a period, delete it and rebuild it on-demand.

@lafriks
Copy link
Contributor

lafriks commented Sep 25, 2022

Yes but would be nice if that could be specified somehow also in pipeline (with having setting for default value if not specified)

@6543
Copy link
Member

6543 commented Oct 14, 2022

well docker does allow to create a "snapshot" of a running container ... so we could just snapshot a step after exec before stop it and store that, and on next run check if there is already a snapshot.

TODO: are there similar concepts for the kubernetes and podmak backend(s)?

@silverwind
Copy link
Contributor Author

Updated syntax suggestion in OP slightly to allow multiple images to be built.

@gmuellerinform
Copy link

This feature would be really useful. Why not use the docker compose syntax:

pipeline:
  deps:
    build:
      context: ./docker/build
      dockerfile: Dockerfile
      target: wp
    commands:
      npm install
      go mod download

@silverwind

This comment was marked as off-topic.

@lafriks
Copy link
Contributor

lafriks commented May 11, 2023

Something like this could potentially be useful for building docker image for services

@Timshel
Copy link
Contributor

Timshel commented Oct 3, 2023

The documentation hinted it might be possible : https://woodpecker-ci.org/docs/usage/volumes

A working example :

steps:
  build-image:
    image: docker
    commands:
      - docker build --rm -t local/project-image .
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  build-project:
    image: local/project-image
    commands:
      - ./build.sh

Timshel added a commit to Timshel/woodpecker that referenced this issue Oct 3, 2023
Timshel added a commit to Timshel/woodpecker that referenced this issue Oct 4, 2023
@gmuellerinform
Copy link

This is just a workaround, not a solution:

Volumes are only available to trusted repositories and for security reasons should only be used
in private environments. See [project settings] to enable trusted mode.

@Timshel
Copy link
Contributor

Timshel commented Oct 4, 2023

Yep but depending on your setup this might be an acceptable workaround so I thought it was worth mentioning.

qwerty287 pushed a commit that referenced this issue Oct 8, 2023
Add some documentation on how to build then use a local `Docker` image.
It's hinted in the
[Volumes](https://woodpecker-ci.org/docs/usage/volumes) doc, but I think
it's worth to make it more visible.

Relates to #1175.
@airtower-luna
Copy link

I came here looking for something similar to the dockerfile agent in Jenkins. Basically I'd like to be able to do something like this:

steps:
  - name: build
    dockerfile: Dockerfile.ci
    commands:
      - meson # ...

Where the container image would then be built and used to run the commands. With the build cache it's highly efficient when running pipelines repeatedly on the same host, and still pretty good with only a few (when spreading over many hosts an internal registry might indeed be better).

I personally don't see a need to have a context other than an empty directory (anything from the repository should be available from the workspace during commands execution anyway), and while an image tag would be useful to reuse the image in later steps on the same host there'd be the risk of collisions (imagine two builds with different version of the Dockerfile building in parallel, could be alleviated with variables though).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cache proposals ideas for make caching work seamles
Projects
None yet
Development

No branches or pull requests

7 participants