I want to use custom docker image, e.g. cern/cc7-base, which is RedHat based in my GH Action workflow. There are several posts about how to use custom image which fits the same runs-on one, e.g. custom image is ubuntu based. But I can't find how to specify runs-on with my custom image, e.g. here is what I was expecting
jobs:
build:
container:
image: cern/cc7-base
runs-on: cc7-base
But apparently this does not work, it just hangs and waits forever. If I skip runs-on the GH Action complains about it, and I do not want to use ubuntu in runs-on as my base image is different. I want to use my base image as a runner. How I can do that?
Related
I have a custom docker image that run certain security checks on the Github repository and posts the results to a URL for review/analysis. I can see now that Github actions support custom Docker images. My question is will the runner environment variables and the clone repo be automatically mounted into the custom container or I need to pass them individually.
Also my custom container image is around 1G in size. Downloading and running it on every build will slow down the test and build. What is the best option in this case. Is there any way I can cache the image? If not are there any other workaround?
Thanks
My question is will the runner environment variables and the clone repo be automatically mounted into the custom container or I need to pass them individually.
Automatically mounted no, you have to tell him it should use your custom container:
container:
image: ghcr.io/owner/image
# ...
Refs: github docs
Is there any way I can cache the image? If not are there any other workaround?
I think you should check around cache action. I guess you should be able to download your image and cache the path where you download it or something like that.
I want to create an image A in one instance/server, but in that instance there is no internet connection.
So can I create an image B with all packages installed at my machine and then Push to x.x.x.x and use it in image A as the FROM tag?
It will look like :
FROM x.x.x.x/B:latest
RUN ***
ENTRYPOINT
Please suggest a correct solution for this problem.
Yes, you can.
First though, you say image A is on a server that has no internet connection. If that is true, then you can't access the built image B that you've pushed to x.x.x.x unless the x.x.x.x that you refer to is localhost.
To answer the question fully with the assumption that there's no internet:
Dockerfile B contains all the stuff you want in your base image. Build that. Then move the image to the internet-less server that you're building image A on. (To move the image, check out docker export or docker save commands and/or google 'moving a docker image from one host to another'. My initial search lead me here: https://blog.giantswarm.io/moving-docker-container-images-around/)
(note: for anyone that wants to do this and you have a internet connection, you would push image B to a repo and then pull the image straight from there in Dockerfile A which would skip the moving from host to host part.)
Then, just like you've written already, the Dockerfile for image A should have:
FROM imageB:latest
to pull from your first image. It's all pretty easy. Long story long, yes, you can build your own images and then build other images based off of that image.
Short answer - of course, you can. You can use any image, including your own, to build new images.
Long answer - consider Docker multistage build for you purpose. This allows reduce the amount of images and the space occupied by your docker registry.
You can read more on https://docs.docker.com/develop/develop-images/multistage-build/
In short - you create a single Dockerfile where you define several images, based on each other. In case you don't need your base image outside from derived, this is your case. Following example will illustrate:
Dockerfile
# First create base image
FROM foo:latest as mybase # note we tag it 'mybase'
RUN blahblah
FROM mybase # here we derive new image, note Dockerfile is same!
RUN blahblahblah
On machine A I have docker image FOO/BAR installed. How do I query the version of that image, and how do I install the same version to machine B?
Please note that on machine B I don't need the newest available version of FOO/BAR, but the same version as machine A. I don't want to keep local modifications to the image made on machine A.
Docker uses a tag or digest to distinguish between different versions of an image. When specifying neither a tag or a digest, all Docker commands assume that you want to use the default tag latest. But you can always be more specific.
Assuming the image comes from a registry FOO and is called BAR, there are two ways how you can pull the same version of the image: either by tag or by digest. You can only use the tag if you know that it is unique and not reused. This is often the case when using build numbers or Git hashes as tags, but if you want to be absolutely sure, use the digest.
On machine A, run docker images --digests. Look for FOO/BAR and its digest (starting with sha:).
On machine B, run the following command and replace {digest} with the digest from machine A:
docker pull FOO/BAR#{digest}
This is an example how it could look:
docker pull FOO/BAR#sha256:e4957dfd892f656ae672dfa03eb7a73f1c47bd24fc95f2231fc5ac91a76092a0
This will download the same version that is available on machine A to machine B. Since it comes from the registry, it's a fresh copy without any modifications.
Use a tag!
docker image supports tag, which is usually used as a version number. When building an image, you can specify a tag:
docker build -t myimage:v0.1 .
Then use the same image is easy:
docker run -d myimage:v0.1 entrypoint.sh
If you do not specify a tag, and everything works fine. Because docker uses default tag latest, which can be annoying when updating and keeping them sync.
latest image can change all the time(usually with CI/CD auto-build), so easy container can use different images. If there is not what you expected, use a tag always!
A generic selenium/node-firefox docker image available in docker repository. I need to make changes/append to the image so that it have our test environment host entries.
What would be the best approach to do this. Should I just take the source and make the changes and build my own image?
In terms of maintainability it is possible to do it such a way that it always gets the base image and my changes append to it to make a new image? If so how can this be done?
When you run a docker container, there is an add-host argument that lets you specify what host entries you need to make available to the container. This would be similar to if you updated the /etc/hosts file.
docker run --add-host myserver:192.168.0.100 the-image-name
You don't need to update the source image to accomplish this. If you need to perform customizations to a docker image beyond what the runtime arguments give you, you can always derive your own Dockerfile from the image (although you should research best practices around deriving image files and not making deeply nested image files).
Here is a reference page.
I want to create separated containers with a single service in each (more or less). I am using the php7-apache image which seems to use a base image of debian:jessie, php7 and apache. Since apache and php in this case are pretty intertwined I don't mind using this container.
I want to start adding other services to their own containers (git for example) and was considering using a tiny base image like busybox or alpinebox for these containers to keep image size down.
That said, I have read that using the same base image as other containers only gives you the 'penalty' of the one time image download of the base OS (debian jessie) which is then cached - while using tiny OSes in other containers will download those OSes on top of the base OS.
What is the best practice in this case? Should I use the same base image (debian jessie) for all the containers in this case?
You may want to create a base image from scratch. Create a base image from scratch.
From docker documentation
You can use Docker’s reserved, minimal image, scratch, as a starting point for building containers. Using the scratch “image” signals to the build process that you want the next command in the Dockerfile to be the first filesystem layer in your image.
While scratch appears in Docker’s repository on the hub, you can’t pull it, run it, or tag any image with the name scratch. Instead, you can refer to it in your Dockerfile. For example, to create a minimal container using scratch:
This example creates the hello-world image used in the tutorials. If you want to test it out, you can clone the image repo