英文:
Platform-specific RUN statements in Dockerfile
问题
Here's the translated Dockerfile section with the conditional RUN
statement:
ARG BASE_IMAGE=mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim-arm64v8
FROM ${BASE_IMAGE} AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["src/ScreenshotCreator.Api/ScreenshotCreator.Api.csproj", "src/ScreenshotCreator.Api/"]
COPY ["src/ScreenshotCreator.Logic/ScreenshotCreator.Logic.csproj", "src/ScreenshotCreator.Logic/"]
RUN dotnet restore "src/ScreenshotCreator.Api/ScreenshotCreator.Api.csproj"
COPY . .
WORKDIR "/src/src/ScreenshotCreator.Api"
RUN dotnet build "ScreenshotCreator.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ScreenshotCreator.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# Conditional RUN statement
RUN if [ "${PLATFORM}" = "arm" ]; then \
apt-get update \
&& apt-get install -y wget libssl1.1 libunwind8 \
&& mkdir -p /opt/microsoft/powershell/7 \
&& wget -O /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.2.6/powershell-7.2.6-linux-arm64.tar.gz \
&& tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 \
&& chmod +x /opt/microsoft/powershell/7/pwsh \
&& ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh \
&& rm /tmp/powershell.tar.gz \
&& pwsh playwright.ps1 install chromium \
&& pwsh playwright.ps1 install-deps chromium; \
else \
apt-get update \
&& apt-get install -y wget apt-transport-https software-properties-common \
&& wget -q https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb \
&& dpkg -i packages-microsoft-prod.deb \
&& rm packages-microsoft-prod.deb \
&& apt-get update \
&& apt-get install -y powershell \
&& pwsh playwright.ps1 install chromium \
&& pwsh playwright.ps1 install-deps chromium; \
fi
ENTRYPOINT ["dotnet", "ScreenshotCreator.Api.dll"]
Please note that I've adjusted the conditional RUN
statement to use the correct syntax in a Dockerfile. If the ${PLATFORM}
environment variable is set to "arm", it will execute the first set of commands; otherwise, it will execute the second set of commands.
英文:
I have an ASP.NET Core application running in Docker on my Raspberry Pi (arm64
). This is the Dockerfile
:
ARG BASE_IMAGE=mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim-arm64v8
FROM ${BASE_IMAGE} AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["src/ScreenshotCreator.Api/ScreenshotCreator.Api.csproj", "src/ScreenshotCreator.Api/"]
COPY ["src/ScreenshotCreator.Logic/ScreenshotCreator.Logic.csproj", "src/ScreenshotCreator.Logic/"]
RUN dotnet restore "src/ScreenshotCreator.Api/ScreenshotCreator.Api.csproj"
COPY . .
WORKDIR "/src/src/ScreenshotCreator.Api"
RUN dotnet build "ScreenshotCreator.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ScreenshotCreator.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN apt-get update
RUN apt-get install -y wget libssl1.1 libunwind8
RUN mkdir -p /opt/microsoft/powershell/7
RUN wget -O /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.2.6/powershell-7.2.6-linux-arm64.tar.gz
RUN tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7
RUN chmod +x /opt/microsoft/powershell/7/pwsh
RUN ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh
RUN rm /tmp/powershell.tar.gz
RUN ["pwsh", "playwright.ps1", "install", "chromium"]
RUN ["pwsh", "playwright.ps1", "install-deps", "chromium"]
ENTRYPOINT ["dotnet", "ScreenshotCreator.Api.dll"]
When trying to build and run this Docker container on my Windows machine (amd64
, Docker via WSL2 (Ubuntu)), it fails because a) the base image is not correct and b) the bunch of RUN
statements for installing PowerShell at the end have to look different depending on the platform:
# Install PWSH on Raspberry
# https://learn.microsoft.com/en-us/powershell/scripting/install/install-raspbian?view=powershell-7.3#install-on-raspberry-pi-os
sudo apt-get update
sudo apt-get install '^libssl1.0.[0-9]$' libunwind8 -y
wget https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/powershell-7.3.4-linux-arm64.tar.gz
mkdir ~/powershell
tar -xvf ./powershell-7.3.4-linux-arm32.tar.gz -C ~/powershell
~/powershell/pwsh
# Install PWSH on Ubuntu (WSL2/Docker)
# https://learn.microsoft.com/en-us/powershell/scripting/install/install-ubuntu?view=powershell-7.3#installation-via-package-repository
sudo apt-get update
sudo apt-get install -y wget apt-transport-https software-properties-common
wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb"
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y powershell
pwsh
I solved problem a with the variable BASE_IMAGE
that I set override locally, but I'm not sure how to handle b. What's the recommended pattern for this using Docker?
- Maintain two different
Dockerfile
s (arm64
/Raspi andamd64
/Ubuntu/WSL) and swallow the bitter pill of duplicating the first half of theDockerfile
. - Using some sort of conditional
RUN
statement so that there is only onlyDockerfile
, looking like this:
ARG BASE_IMAGE=mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim-arm64v8
FROM ${BASE_IMAGE} AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["src/ScreenshotCreator.Api/ScreenshotCreator.Api.csproj", "src/ScreenshotCreator.Api/"]
COPY ["src/ScreenshotCreator.Logic/ScreenshotCreator.Logic.csproj", "src/ScreenshotCreator.Logic/"]
RUN dotnet restore "src/ScreenshotCreator.Api/ScreenshotCreator.Api.csproj"
COPY . .
WORKDIR "/src/src/ScreenshotCreator.Api"
RUN dotnet build "ScreenshotCreator.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ScreenshotCreator.Api.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
if ${PLATFORM}=="arm":
RUN apt-get update
RUN apt-get install -y wget libssl1.1 libunwind8
RUN mkdir -p /opt/microsoft/powershell/7
RUN wget -O /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.2.6/powershell-7.2.6-linux-arm64.tar.gz
RUN tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7
RUN chmod +x /opt/microsoft/powershell/7/pwsh
RUN ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh
RUN rm /tmp/powershell.tar.gz
RUN ["pwsh", "playwright.ps1", "install", "chromium"]
RUN ["pwsh", "playwright.ps1", "install-deps", "chromium"]
else
RUN apt-get update
RUN apt-get install -y wget apt-transport-https software-properties-common
RUN wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb
RUN dpkg -i packages-microsoft-prod.deb
RUN apt-get update
RUN apt-get install -y powershell
RUN ["pwsh", "playwright.ps1" ,"install", "chromium"]
RUN ["pwsh", "playwright.ps1" ,"install-deps", "chromium"]
ENTRYPOINT ["dotnet", "ScreenshotCreator.Api.dll"]
答案1
得分: 0
以下是已翻译的内容:
有人在Docker论坛给了我这个答案,非常有效。
基本上,现在每个架构都有一个PowerShell安装脚本(install-powershell-arm64.sh
和install-powershell-amd64.sh
),在Dockerfile
中使用如下方式调用:
ARG TARGETARCH
COPY src/ScreenshotCreator.Api/install-powershell-$TARGETARCH.sh /scripts/install-powershell-$TARGETARCH.sh
RUN chmod +x /scripts/install-powershell-$TARGETARCH.sh
英文:
Someone in the Docker forum gave me this answer which works like a charm.
Basically there is now a PowerShell installation script for each architecture (install-powershell-arm64.sh
and install-powershell-amd64.sh
) and within the Dockerfile
, it is called like this:
ARG TARGETARCH
COPY src/ScreenshotCreator.Api/install-powershell-$TARGETARCH.sh /scripts/install-powershell-$TARGETARCH.sh
RUN chmod +x /scripts/install-powershell-$TARGETARCH.sh
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论