Unable to use Arg values in commands in dockerfile - docker

I am trying to allow passing build args to a dockerfile during build process but I cannot figure out how to get it to work.
This is my dockerfile
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
RUN apt-get update && apt-get install openssh-server -y \
&& echo "root:Docker!" | chpasswd
COPY sshd_config /etc/ssh/
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 2222
ARG node_build=production
ENV node_build_env=$node_build
ARG net_build=Release
ENV net_build_env=$net_build
FROM node:12.18.3 AS node-build
RUN echo $build_command_env
WORKDIR /root
COPY ["MyProject/package.json", "."]
COPY ["MyProject/package-lock.json", "."]
RUN npm i --ignore-scripts
COPY ["MyProject/angular.json", "."]
COPY ["MyProject/tsconfig.json", "."]
COPY ["MyProject/tslint.json", "."]
COPY ["MyProject/src", "./src"]
RUN npx ng build -c $node_build_env
FROM microsoft/dotnet:2.2-sdk AS build
RUN echo $net_build_env
WORKDIR /src
COPY ["MyProject/MyProject.csproj", "MyProject/"]
COPY ["MyProject.ServiceModel/MyProject.ServiceModel.csproj", "MyProject.ServiceModel/"]
COPY ["MyProject.ServiceInterface/MyProject.ServiceInterface.csproj", "MyProject.ServiceInterface/"]
COPY ["NuGet.config", "NuGet.config"]
RUN dotnet restore "MyProject/MyProject.csproj"
COPY . .
WORKDIR "/src/MyProject"
RUN dotnet build "MyProject.csproj" -c $net_build_env -o /app
FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c $net_build_env -o /app
FROM base AS final
WORKDIR /app
COPY --chown=www-data:www-data --from=publish /app .
COPY --chown=www-data:www-data --from=node-build /root/wwwroot ./wwwroot
ENTRYPOINT service ssh start && dotnet MyProject.dll
I have tried many different ways. I tried just using ARG and declaring after every FROM but that didn't work. This version I try copying ARG to ENV but that also didn't work.
How do I do this?

Issue was that variable had to be in double quote:
RUN dotnet build "MyProject.csproj" -c "$net_build_env" -o /app

You have to add --build-arg <arg>=<value> in your docker build command in order to use ARG arguments in your containerfile.
There's no need for ENV if you're only going to use the args in container build process

Related

Even with a slight change in code, docker image build takes a lot of time

Here is a Dockerfile and I wonder why with a slight change in C# code rebuilding the image takes a lot of time compared to Python. I read all tips and still no chance. Is there a way to improve it?
Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
RUN apt-get update && apt-get install -y libldap-2.4-2
RUN apt-get install curl -y
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["test/testAdmin.csproj", "test/"]
COPY ["testDal/testDal.csproj", "testDal/"]
COPY ["testCore/testCore.csproj", "testCore/"]
RUN dotnet restore "test/testAdmin.csproj"
COPY . .
WORKDIR "/src/testAdmin"
RUN pwd
RUN ls
RUN mv appsettings.json appsettings.json
RUN dotnet build "testAdmin.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "testAdmin.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "testAdmin.dll"]
For production environment this is OK but for testing we need faster builds for every pull.

Getting Docker Dev Engine to work with VS Code

whenever I run the dev engine, I get the following error at the end of the install:
chown: invalid group: ‘root:docker’
WARNING: Could not change owner for docker socket in container : exit code 1
Docker socket permission set to allow in container docker
I am on macOS, so not sure if I need to create a docker group or not.
I have the following Dockerfile.devenv
FROM python:3.9-buster
COPY requirements.txt requirements.txt
COPY . .
RUN pip install -r requirements.txt
USER root
WORKDIR /src
EXPOSE 8000
RUN useradd -ms /bin/bash devenv
and no docker compose file.
Based on docker documentation when we are specifying Dockerfile, we need to make sure that we are using vscode user and included to docker group.
So i think your Dockerfile.devenv need to be updated. e.g:
FROM python:3.9-buster
WORKDIR /src
COPY requirements.txt requirements.txt
COPY . .
RUN pip install -r requirements.txt
# create vscode user then add to docker group
RUN useradd -s /bin/bash -m vscode \
&& groupadd docker \
&& usermod -aG docker vscode
USER vscode
EXPOSE 8000
According to the documentation: https://learn.microsoft.com/en-us/visualstudio/mac/docker-quickstart?view=vsmac-2019
It could be possible to run the service of Visual Studio by configurating the dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY DockerDemo/DockerDemo.csproj DockerDemo/
RUN dotnet restore "DockerDemo/DockerDemo.csproj"
COPY . .
WORKDIR "/src/DockerDemo"
RUN dotnet build "DockerDemo.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DockerDemo.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DockerDemo.dll"]
So it could be possible to run your python environment within the environment for visual studio to run over macOS:
FROM python:3.9-buster
COPY requirements.txt requirements.txt
COPY . .
RUN pip install -r requirements.txt
USER root
WORKDIR /src
EXPOSE 8000
RUN useradd -ms /bin/bash devenv
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /src
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY DockerDemo/DockerDemo.csproj DockerDemo/
RUN dotnet restore "DockerDemo/DockerDemo.csproj"
COPY . .
WORKDIR "/src/DockerDemo"
RUN dotnet build "DockerDemo.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DockerDemo.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /src
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DockerDemo.dll"]

docker build not setting up environment variables using ENV

Trying to build a docker image with golang and react code. The environment variable JWT_SECRET_KEY is not being set.
# Build the Go API
FROM golang:latest AS builder
ADD . /app
WORKDIR /app/server
ENV JWT_SECRET_KEY=DefaultKey
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-w" -a -o /main .
# Build the React application
FROM node:alpine AS node_builder
COPY --from=builder /app/client ./
RUN npm install
RUN npm run build
# Final stage build, this will be the container
# that we will deploy to production
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /main ./
COPY --from=node_builder /build ./web
RUN chmod +x ./main
EXPOSE 8080
CMD ./main
To build this i ran the command
docker build -t webapp .
If you want JWT_SECRET_KEY to be set in the production stage you need to move it to that stage. Or if you need it in both copy it. So change your docker file to
# Build the Go API
FROM golang:latest AS builder
ADD . /app
WORKDIR /app/server
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-w" -a -o /main .
# Build the React application
FROM node:alpine AS node_builder
COPY --from=builder /app/client ./
RUN npm install
RUN npm run build
# Final stage build, this will be the container
# that we will deploy to production
FROM alpine:latest
RUN apk --no-cache add ca-certificates
ENV JWT_SECRET_KEY=DefaultKey
COPY --from=builder /main ./
COPY --from=node_builder /build ./web
RUN chmod +x ./main
EXPOSE 8080
CMD ./main

docker file arg variable not passed for asp.net core on linux

I have an Asp.Net core 3.1 app which is dockerized for linux like this
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
ARG BUILD_CONFIGURATION=Release
ENV ASPNETCORE_ENVIRONMENT=Production
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY . .
RUN dotnet restore "Api/Authentication/Authentication.csproj"
COPY . .
WORKDIR "/src/Api/Authentication"
RUN dotnet build "Authentication.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
RUN dotnet publish "Authentication.csproj" -c $BUILD_CONFIGURATION -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Authentication.dll"]
In the Azure Devops pipeline the build tempelate looks like this.
But the build fails with the following message
##[error]The command '/bin/sh -c dotnet build "Authentication.csproj" -c $BUILD_CONFIGURATION -o /app/build' returned a non-zero code: 1
The Arg BUILD_CONFIGURATION seems is not accepting the value from the devops piplline
An ARG instruction goes out of scope at the end of the build stage where it was defined. To use an arg in multiple stages, each stage must include the ARG instruction. More information, you can refer to ARG scope
So, you need to define ARG BUILD_CONFIGURATION=Release in build and publish stage.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
ARG BUILD_CONFIGURATION=Release
ENV ASPNETCORE_ENVIRONMENT=Production
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY . .
RUN dotnet restore "Api/Authentication/Authentication.csproj"
COPY . .
WORKDIR "/src/Api/Authentication"
RUN dotnet build "Authentication.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "Authentication.csproj" -c $BUILD_CONFIGURATION -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Authentication.dll"]

Kubernetes not take dockerfile timezone

I have the next docker file where I have defined timeZone to America/Bogota, then where The Azure pipeline build the image I can see in the log date is correct from dockerfile, but when I exec the pod in azure Kubernetes the timezone is different. Why the kubernetes pod don't take timezone America/Bogota?
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY NuGet.Config ./
COPY NugetPackage/travelExpensesRestClient.1.0.0.nupkg NugetPackage/
RUN dir /src/NugetPackage
COPY microservicioX/microservicioX.csproj microservicioX/
COPY travelExpenses.Viajes.Proxy/travelExpenses.Viajes.Proxy.csproj travelExpenses.Viajes.Proxy/
RUN dotnet restore -nowarn:msb3202,nu1503 microservicioX/microservicioX.csproj #--verbosity diag
COPY . .
WORKDIR /src/microservicioX
RUN dotnet build -c Release -o /app
FROM build AS publish
RUN dotnet publish microservicioX.csproj -c Release -o /app
WORKDIR /
ENV TZ=America/Bogota
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN date
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "microservicioX.dll"]
For more Details: in the azure pipeline I can see the correct timezone
https://i.ibb.co/wgSzHS9/Time-Zone-build-Image.png
Time Zone in the azure kubernetes pod
https://i.ibb.co/hm25Xkc/Time-Zone-in-Pod.png
I think you might be defining the TZ in a different image
This is the publish image:
FROM build AS publish
RUN dotnet publish microservicioX.csproj -c Release -o /app
WORKDIR /
ENV TZ=America/Bogota
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN date
And that's where you set the TZ. This is the final image where the application runs:
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "microservicioX.dll"]
You are not setting TZ here. Adding the TZ here just like you did in the publish image should be sufficient, I think.

Resources