How do I build with docker?
Using Docker makes it possible to deploy your application as a docker container or release an image on docker hub. This recipe walks you through creating a
Dockerfile and automating the build and test process with Docker Hub.
1. Create a .dockerignore file
.dockerignore file with the same contents as
cp .gitignore .dockerignore
copy .gitignore .dockerignore
Now, add the following lines to the
2. Create the dockerfile
Dockerfile with the following contents:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as build # Install node RUN curl -sL https://deb.nodesource.com/setup_14.x | bash RUN apt-get update && apt-get install -y nodejs WORKDIR /workspace COPY . . RUN dotnet tool restore RUN dotnet fake build -t Bundle FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine COPY --from=build /workspace/deploy /app WORKDIR /app EXPOSE 8085 ENTRYPOINT [ "dotnet", "Server.dll" ]
This uses multistage builds to keep the final image small.
Using the minimal template?
If you created your SAFE app using the minimal option, a FAKE script is not included by default so you need to bundle up the client and server separately.
Replace the line
RUN dotnet fake build -t Bundle
RUN npm run build RUN cd src/Server && dotnet publish -c release -o ../../deploy
3. Building and running with docker locally
- Build the image
docker build -t my-safe-app .
- Run the container
docker run -it -p 8085:8085 my-safe-app
Because the build is done entirely in docker, Docker Hub automated builds can be setup to automatically build and push the docker image.
4. Testing the server
docker-compose.server.test.yml file with the following contents:
sut: build: context: . target: build command: cd tests/Server && dotnet run
If you added tests to the minimal template according to the testing the server recipe, change the command to
cd src/Server.Tests && dotnet run
Docker Hub can also run automated tests for you.
The template is not currently setup for automating the client tests.
Follow the instructions to enable Autotest on docker hub.
5. Making the docker build faster
Not recommended for most applications
If you often build with docker locally, you may wish to make the build faster by optimising the Dockerfile for caching. For example, it is not necessary to download all paket and npm dependencies on every build unless there have been changes to the dependencies.
Furthermore, the client and server can be built in separate build stages so that they are cached independently. Enable Docker BuildKit to build them concurrently.
This comes at the expense of making the dockerfile more complex; if any changes are made to the build such as adding new projects or migrating package managers, the dockerfile must be updated accordingly.
The following should be a good starting point but is not guarenteed to work.
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as build # Install node RUN curl -sL https://deb.nodesource.com/setup_14.x | bash RUN apt-get update && apt-get install -y nodejs WORKDIR /workspace COPY .config .config RUN dotnet tool restore COPY .paket .paket COPY paket.dependencies paket.lock ./ RUN dotnet paket restore FROM build as server-build COPY src/Shared src/Shared COPY src/Server src/Server RUN cd src/Server && dotnet publish -c release -o ../../deploy FROM build as client-build COPY package.json package-lock.json ./ RUN npm install COPY webpack.config.js ./ COPY src/Shared src/Shared COPY src/Client src/Client RUN npm run build FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine COPY --from=server-build /workspace/deploy /app COPY --from=client-build /workspace/deploy /app WORKDIR /app EXPOSE 8085 ENTRYPOINT [ "dotnet", "Server.dll" ]