Software Bill of materials for docker image - node.js

I have node 12.14 docker image which I am using for my applications. But today I was asked to provide Software Bill of materials (SBOM) for this docker image. I am not sure how to get that.
Any inputs that you provide to help me get Software Bill of materials will be greatly appreciated.

I've personally not been tasked with something like this before, but I'd take a guess that looking at the history might be a good start:
# You may need to first run "docker pull node:12.14"
docker history --format '{{.CreatedBy}}' --no-trunc --human node:12.14
This will output the list of commands used to build the image and you'll have to decide what's appropriate for the team requesting the bill of materials from you.
Otherwise, you can look at the source for the Dockerfile directly at GitHub. This point in the history appears to be the latest commit that builds the 12.14 release (I could be wrong so please feel free to dig around that repository and its history yourself as well).

Docker just announced (Apr. 7th, 2022)
Introducing 'docker sbom' — the CLI command developed alongside #anchore (using their Syft project) that displays the SBOM of any Docker image.
CTO #justincormack explains how this functionality will help improve trust in the software supply chain by providing more visibility:
Announcing Docker SBOM: A step towards more visibility into Docker images
This command is just a first step that Docker is taking to make container images more self descriptive. We believe that the best time to determine and record what is in a container image is when you are putting the image together with docker build. To enable this, we are working on making it easy for partners and the community to add SBOM functionality to docker build using BuildKit’s extensibility.
As this information is generated at build time, we believe that it should be included as part of the image artifact. This means that if you move images between registries (or even into air gapped environments), you should still be able to read the SBOM and other image build metadata off of the image.
Example:
docker sbom neo4j:4.4.5
Result:
Syft v0.42.2
✔ Loaded image
✔ Parsed image
✔ Cataloged packages [385 packages]
NAME VERSION TYPE
...
bsdutils 1:2.36.1-8+deb11u1 deb
ca-certificates 20210119 deb
...
log4j-api 2.17.1 java-archive
log4j-core 2.17.1 java-archive
...
Note that the output includes not only the Debian packages that have been installed inside the image but also the Java libraries used by the application.
Getting this information reliably and with minimal effort allows you to promptly respond and reduce the chance that you will be breached.
In the above example, we can see that Neo4j uses version 2.17.1 of the log4j-core library which means that it is not affected by log4shell.
Engin Diri adds (tweet)
The new #Docker sbom command is great in terms of UX.
Plenty of choices for the output format (#CycloneDX_Spec, #SyftProject, SPDX or even #github JSON!) Great collab with #anchore.
BTW: You can pipe docker sbom output via "--format syft-json | grype" into #GrypeProject to get the vulnerabilities displayed!

Related

/usr/local/ reset for custom centos7 image on azure scale set

We're using Packer to construct a custom centos7 image for an Azure scale set. Part of this includes a custom rpm that we have created that builds git from source (can't use community repos so we make our own) and installs it to the /usr/local/bin directory. In normal practice, the package works perfectly. Everything gets installed appropriately to the right places and we can use our new version of git.
When we run things through Packer, we install it via ansible, and then finally Packer does the deprovisioning step, captures the image and puts it in an azure shared image gallery, which we then pick up for use in our azure scale set.
Scale set uses the image to make a few instances, and we're up and running. Problem is, suddenly, the /usr/local/ directory seems to be as if it has been reset to default. There's nothing in /usr/local/bin anymore, and furthermore, some (not all) of the packages that we install as dependencies to build git (like gcc for example), also just disappear. Our git rpm is still listed as installed, but gcc is not.
/usr/bin/ seems fine (aside from the missing gcc, and though we don't need it at this point anyway, it still seems concerning), so we can probably just install it there, but I'd still like to know if something crazy is happening, and should I look out for it in the future seeing as /usr/local/ seemed a logical spot to install it.
TL;DR:
packer gets base centos7 image
add our custom git package
git installs to /usr/local/bin (it works! git is available)
deprovision with waagent and generalized
packer captures image and uploads it
azure scale set uses image to make new instances
/usr/local/ is back to original state? (thus git is missing?)
???
packer azure arm docs
waagent deprovisioning tool docs
Figured this out.
Turns out (at least with version 1.7.2) Packer does not necessarily do idempotent operations with the azure arm in relation to Shared Image Gallery versions, even with the --force flag.
We had created the SIG image version before we had gotten our git package fully working and installed properly, so it was created on a base image that did not have /usr/local/bin/ modified.
When we ran the Packer build with the force flag, it deletes and recreates the base image, but it runs a PUT call with the configuration information for the SIG image version, which is to say it will "Create or Update" if it's following convention (you can't see this unless you set some packer logging vars and output the verbose logs to a file or something).
So while the base image was updated to one that had git properly set up, the SIG version thought it was using the same base image as before (the name was the same, no unique identifier), so as far as it was concerned the configuration hadn't changed and nothing needed to happen. After we deleted the old version or made a new version, it properly spun up a VM based on the base image we had made and everything was where it was supposed to be.
I am definitely of the opinion that a --force should be an idempotent operation from start to finish, I'm not sure if this is fixed in future versions (at the time of writing this they're on 1.7.6) but maybe I'll update once I've checked it out.

IBM Cloud Code Engine: How can I deploy an app from GitLab source without CLI

I create a project and saved it in GitLab.
I tried to download the IBM Cloud CLI to my Windows 10 system and I failed, I try to do it Run as administrator as mention in the CLI docs.
Now, I want to deploy this code project without CLI from source code. I could not find any docs about it.
I read about Dockerfile I should insert into my project but I know nothing about it.
Please help me in 2 ways:
Deploy my project with source code (Gitlab connect to IBM Cloud Code Engine).
Deploy my project using CLI in the windows 10 system.
I just did the same thing as part 1 of your question yesterday. As a prerequisite, you will need a container registry to put things into, such as a free account on Docker Hub.
Start on the Code Engine console.
Choose Start with Source Code, and paste in your on Gitlab URL. (The default is a sample repo which may be useful, especially https://github.com/IBM/hello.
On the next page, you can accept most of the defaults but you will need to create a project. That's free, but it needs a credit card so you can use a Pay As You Go account.
You'll also need to Specify Build Details
Here you tell it about your source repo, and where your Dockerfile lives. If you don't have a Dockerfile, you can probably find a sample one for your chosen runtime (C#? Node.js? Java?), or you can try using the Cloud Native buildpack. The build pack will try and work out how to run your code by inspecting what files you have.
Finally, on the last page of the build details, you will need to tell it where your container registry lives. This is a repository used to store the built images. If you set up a personal account on docker hub, you can just enter the credentials.
Once you've done that, you can choose Done in the sidebar:
and then Create
You should get a page which shows your image is building
and then once the build is done, in the top right you'll get a link to take you to your app's web page:
If you get stuck, there's a good set of documentation.

What is the purpose of Docker?

So in my head, Docker is a container management system that allows you to build an application in a unified way so you don't need to worry about version control, client environment configuration and so on.
However, there is some concept that I am clearly missing:
In my head, Docker basically wraps your whole program in a container to be shipped easily to clients and anybody who wants to use your product. And from there I can just tell clients to install so-and-so to set up the whole system in their own system. However, digging into Docker, I don't understand how pulling and pushing images into DockerHub helps that use case as well as not providing an executable to execute DockerImage in a click.
DockerHub images take so many steps to unpack and edit. I was assuming that those templates on DockerHub exists for us to pull and edit the template for our own use cases, but that does not seem to be the case because the steps to unpack an image is much more than I imagined, and the use case seems to be more of "Download and use image, not for editing".
Surely I am missing something about Docker. What is the purpose of pushing and pulling images on DockerHub? How does that fit into the use case of containerizing my software to be executed by clients? Is the function of DockerHub images just to be pulled to be ran and not edited?
It's so hard for me to wrap my head around this because I'm assuming Docker is for containerizing my application to be easily executable by clients who wants to install my system.
To further explain this answer I would even say that docker allows you to have a development environment tied to your application that is the same for all your developers.
You would have your git repo with your app code, and a docker container with all that is needed to run the application.
This way, all your developers are using the same version of software and that docker container(s) should replicate the production environment (you can even deploy with it, that's another use for it) but with this there's no more the "it works on my machine" problem. Because everyone is working on the same environment.
In my case all our projects have a docker-compose structure associated with them so that each project always have their server requirements. And if one developer needs to add a new extension, he can just add it to the docker config files and all developer will receive the same extension once they update to the latest release.
I would say there are two uses to having images on DockerHub.
The first is that some images are extremely useful as-is. Pulling a redis/mariadb image saves you the trouble of setting it and configuring it yourself.
The second is that you can think of a docker image as a layered item: assume your application is a PHP server. You can (and will have to) create an image for your app source code. BUT the container will need PHP to run your source code!
This is why you have a FROM keyword in a Dockerfile, so that you can define a "starting layer". In the case of a PHP server you'd write FROM php:latest, and docker would pull a PHP image for your server to use from DockerHub.
Without using Dockerhub, you'd have make your image from scratch, and therefore to bundle everything in your image, some operating system information, PHP, your code, etc. Having ready-to-use images to start from makes the image you're building much lighter.

How to specify image platform in gitlab-ci.yml

I am trying to build CI pipeline which does build for particular image. In the CI file however, I could not find a way to specify image platform.
stages:
- build
- deploy
build_j:
image: customServer/debian/jessy
I checked Docker Images doc and this but could not find any example. Alternative way perhaps is to pull image explicitly and run commands using script.
docker pull debian:jessy -platform i386
Since multi architecture/platform tags of a Docker image have different digests, You can pull a Docker image using its digest (instead of using tags) to pull the desired architecture/platform.
Here is an example of multi architecture/platform tag of a Docker image (Ubuntu) in Docker Hub:
As you can see, 20.04 is a multi architecture tag and there are different digests for each of architectures in the tag.
If you run command docker pull ubuntu:20.04
it will pull all architectures.
But command
docker pull ubuntu#sha256:55e5613c8c7bcd8044aaf09d64d20518964a0d7a6e41af129f95b731301c2659
will pull just linux/arm/v7.
As I tried, it is possible to use digest in .gitlab-ci.yml:
job_1:
image: ubuntu#sha256:55e5613c8c7bcd8044aaf09d64d20518964a0d7a6e41af129f95b731301c2659
script:
- ...
job_2:
image: alpine#sha256:71465c7d45a086a2181ce33bb47f7eaef5c233eace65704da0c5e5454a79cee5
script:
- ...
Speaking of image digest, GitLab 13.5 (October 2020) proposes:
Create release with image digest on new tag
Docker supports immutable image identifiers and we have adopted this best practice to update our cloud-deploy images.
When a new image is tagged, we also programmatically retrieve the image digest upon its build, and create a release note to effectively communicate this digest to users.
This guarantees that every instance of the service runs exactly the same code.
You can roll back to an earlier version of the image, even if that version wasn’t tagged (or is no longer tagged). This can even prevent race conditions if a new image is pushed while a deploy is in progress.
See Documentation and Issue.

Gitlab markdown links to artifacts

Is it possible in Gitlab to have source controlled markdown that contains a link to an artifact?
My runner generates metrics that are saved to a file. This output, of course, does not belong in version control. If it was in version control, I could just link to it, no problem. Instead, I mark the output as an artifact so that it is saved after the build is complete.
Currently, our devs can click the [passed] icon for the build that generates the metrics, then click 'Build Artifacts'|'Browse'|dir1|... down to the generated output metric. This is complicated, and you have to know exactly where to look.
It would be way more convenient to have a link to the artifact in the README.md.
These docs say that I can choose to store my artifacts in a different location, but that seems like a heavy solution, and it does not generalize to artifacts from different projects.
These docs say that I can embed build numbers in the artifact filename, but that's not really what I'm after. I just want the artifacts from the most recent build.
What I want is a persistent URL for the artifact, but I am unable to find anything of this nature.
Update February 2018:
Since Gitlab 8.12, the link is https://gitlabInstance/myNamespace/repository/master/archive.zip. (e.g: https://gitlab.com/rpadovani/my-gitlab-ci/repository/master/archive.zip).
There are also other formats.
You can see all the formats clicking on the little cloud in the top right of the homepage of your project.
ORIGINAL ANSWER
They are working on it right now.
Since GitLab 8.10, there is an API to do that:
curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/1/builds/artifacts/master/download?job=test"
Unfortunately you still cannot use the web interface, but there is already a MR to implement it (and a related bug with discussion).
After that MR you can link the build in your README

Resources