How to use Heroku.yml with private gem - ruby-on-rails

So I have a dockerized rails app. When building the docker image, i need to pass in some secret build args because
i need credentials to install sidekiq pro from contribsys
i need credentials to install private gem from github
i need to pass in the rails master key in order to do a rails assets:precompile
So when i build my image locally, my command looks like this:
docker build -f Dockerfile.web -t my-image:latest --build-arg BUNDLE_CONTRIBSYS=$SIDEKIQ_PRO_CREDS --build-arg BUNDLE_GITHUB=$MY_GITHUB_CREDS --build-arg RAILS_MASTER_KEY=$RAILS_MASTER_KEY .
I understand that when using buildpacks, heroku can use some of the apps config for the bundle credentials. But I have not found how to do that with a heroku.yml app.
Now i want to use heroku.yml, but i can't find a way to pass in those build args without writing them in plain text. How am i supposed to pass in the credentials used for fetching private gems?

Related

Creating my first docker image with a local zip

very new to Docker here. I am trying to use a maven 2.1.0 zip to create a docker image.
my
dockerfile.docker file is :
# syntax=docker/dockerfile:1
FROM scratch
LABEL maintainer="Myname"
LABEL maintainer="myemail"
RUN wget HTTP://archive.apache.org/dist/maven/binaries/apache-maven-2.1.0-bin.zip
RUN unzip
I am not exactly sure if I am doing this right
docker build -t apache-maven:2.1.0 .
Essentially I just wanted to create this image locally so I could then push it out to my targeted endpoint. Any help realizing what I did wrong would be appreciated. Whenever I run this build command it tells me it failed to read the dockerfile and that there's no such file or directory.
By default, it will try to find the file with the exact name Dockerfile.
If for any reason, you want to have a different file name like your scenario, you should use next:
docker build -f dockerfile.docker -t apache-maven:2.1.0 .
Detail refers to Specify a Dockerfile (-f)

Pass codecov variables to docker build

I would like to pass the coverage report to codecov during docker build phase. Like this:
ci_env=`bash <(curl -s https://codecov.io/env)`
docker build . --build-arg ci_env=$ci_env
This is currently not possible since ci_env is a list of environment variables.
In the documentation they describe how to achieve it with docker run but not with docker build.
Does anyone know how to do this?

How to share one Dockerfile for multiple version of my project?

I'd like to have one image for each version of my project. But how can I share one dockerfile for all these versions. The only difference is the version number. Thanks
You could pass a parameter to the docker build call.
E.g., consider the following Dockerfile (example for a Node.js project, but the same principals could apply to any type of application):
FROM node:10-alpine
# Install 3rd parties required for your application
# Define an argument for the project version
ARG PROJVER
# Use this argument when installing the project
RUN npm install myproject#{PROJVER}
Once you have a Dockerfile like this, you can build it for a certain version of your project, and of course push it to your registry with that tag:
$ export PROJVER=123
$ docker build --build-arg PROJCET_VERSION=${PROJVER} -t myproject:${PROJVER}
$ docker push myregistry:5000/myproject:${PROJVER}

Can i pass codeship env in docker build

Can I pass the code ship env ex.CI_BRANCH to docker build. I'm must be use it to run bulid backpack separate build for staging or production by CI_BRANCH
There is currently no way to utilize the Codeship environment variables during the image build time.
You can however pass along these environment variables during run time with a step command:
command: /bin/bash -c './script_dependent_on_timestamp.sh $CI_TIMESTAMP'

Create dynamic environment variables at build time in Docker

My specific use case is that I want to organize some data about the EC2 instance a container is running on and make i available as an environment variable. I'd like to do this when the container is built.
I was hoping to be able to do something like ENV VAR_NAME $(./script/that/gets/var) in my Dockerfile, but unsurprisingly that does not work (you just get the string $(./script...).
I should mention that I know the docker run --env... will do this, but I specifically want it to be built into the container.
Am I missing something obvious? Is this even possible?
Docker v1.9 or newer
If you are using Docker v1.9 or newer, this is possible via support for build time arguments. Arguments are declared in the Dockerfile by using the ARG statement.
ARG REQUIRED_ARGUMENT
ARG OPTIONAL_ARGUMENT=default_value
When you later actually build your image using docker build you can pass arguments via the flag --build-arg as described in the docker docs.
$ docker build --build-arg REQUIRED_ARGUMENT=this-is-required .
Please note that it is not recommended to use build-time variables for passwords or secrets such as keys or credentials.
Furthermore, build-time variables may have great impact on caching. Therefore the Dockerfile should be constructed with great care to be able to utilize caching as much as possible and therein speed up the building process.
Edit: the "docker newer than v1.9"-part was added after input from leedm777:s answer.
Docker before v1.9
If you are using a Docker-version before 1.9, the ARG/--build-arg approach was not possible. You couldn't resolve this kind of info during the build so you had to pass them as parameters to the docker run command.
Docker images are to be consistent over time whereas containers can be tweaked and considered as "throw away processes".
More info about ENV
A docker discussion about dynamic builds
The old solution to this problem was to use templating. This is not a neat solution but was one of very few viable options at the time. (Inspiration from this discussion).
save all your dynamic data in a json or yaml file
create a docker file "template" where the dynamic can later be expanded
write a script that creates a Dockerfile from the config data using some templating library that you are familiar with
Docker 1.9 has added support for build time arguments.
In your Dockerfile, you add an ARG statement, which has a similar syntax to ENV.
ARG FOO_REQUIRED
ARG BAR_OPTIONAL=something
At build time, you can pass pass a --build-arg argument to set the argument for that build. Any ARG that was not given a default value in the Dockerfile must be specified.
$ docker build --build-arg FOO_REQUIRED=best-foo-ever .
To build ENV VAR_NAME $(./script/that/gets/var) into the container, create a dynamic Dockerfile at build time:
$ docker build -t awesome -f Dockerfile .
$ # get VAR_NAME value:
$ VAR_VALUE=`docker run --rm awesome \
bash -c 'echo $(./script/that/gets/var)'`
$ # use dynamic Dockerfile:
$ {
echo "FROM awesome"
echo "ENV VAR_NAME $VAR_VALUE"
} | docker build -t awesome -
https://github.com/42ua/docker-autobuild/blob/master/emscripten-sdk/README.md#build-docker-image

Resources