This scenario might be useful to anyone who is willing to write some browser automation or run integration tests with Selenium in .NET Core application in a headless mode in docker.
Simple .NET Application with Selenium, Firefox and GeckoDriver
Let's start with a simple .NET Core application. I am using .NET 5.0 but this should work with any "core" version of the .NET Framework.
using var browser = new FirefoxDriver();
browser.Go("https://youtube.com/");
// some other browser related logic here
browser.Quit();
You also have to add Selenium.WebDriver.GeckoDriver
and Selenium.WebDriver
nuget packages to the project.
Also you have to let the project know that it should copy geckodriver
to the publish folder. Add this to the csproj
file:
<ItemGroup>
<Content Include="$(TargetDir)\geckodriver" CopyToPublishDirectory="Always">
<Link>geckodriver</Link>
</Content>
</ItemGroup>
Now you can run it locally and see that everything is working as expected.
Add Docker Support to .NET Application
Now you have to create Dockerfile
in the project folder with the following content (remember to replace project name):
FROM mcr.microsoft.com/dotnet/runtime:5.0 AS base
RUN apt-get update
RUN apt-get install -y xvfb
RUN echo "deb http://deb.debian.org/debian/ unstable main contrib non-free" >> /etc/apt/sources.list.d/debian.list
RUN apt-get update
RUN apt-get install -y libcrypt1
RUN apt-get install -y firefox
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Folder/Project.csproj", "Folder/"]
RUN dotnet restore "Folder/Project.csproj"
COPY . .
WORKDIR "/src/Folder"
RUN dotnet build "Project.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Project.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/xvfb-run -a $@", ""]
CMD ["dotnet", "Project.dll"]
This is a slightly modified version of the standard Dockerfile generated by Visual Studio.
Let's see what is the difference.
Install xvfb and Firefox in dotnet/runtime docker image
To install xvfb (here you can see what this is) you first have to run `apt-get update` and the install the package:
RUN apt-get update
RUN apt-get install -y xvfb
Next, you have to add unstable package repo, since Debian (Microsoft uses Debian bustre-slim as a base image for `dotnet/runtime` image and it only contains firefox-esr but it is really unstable with the latest Firefox versions and I couldn't run my automation with it. So here is how you install firefox in yur docker image:
RUN echo "deb http://deb.debian.org/debian/ unstable main contrib non-free" >> /etc/apt/sources.list.d/debian.list
RUN apt-get update
RUN apt-get install -y libcrypt1
RUN apt-get install -y firefox
The other tricky part is how to run xvfb-run
command in a docker container. By default it will not work and will block executon of your code so you have to use this combination of ENTRYPOINT
and CMD
:
ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/xvfb-run -a $@", ""]
CMD ["dotnet", "Project.dll"]
Run xvfb with Firefox in Docker
Time to build your image:
docker build -t name -f .\Dockerfile .
and run it:
docker run -it --rm name
I hope it worked and now you can run your selenium tests or automation in a headless mode in docker.