Recent time due to the pandemic provided a lot of free time. I had previously done some learning about Docker, but kept running various commands without much progress. Recently, I revisited the topic and want to share some issues encountered along the way. Ubuntu is installed on a desktop machine, and I found virtual machines too cumbersome. I disconnected the mechanical hard drive power cable and installed the system on a 120GB SSD. It's a bit of a contribution when idle, and there are some small games on Ubuntu that are quite fun. That's aside.
The setup environment is not discussed here. The overall idea is to push code to Gitee, have Jenkins download the latest code, execute the Dockerfile, and run the container. Initially, I set up automatic triggers between Jenkins and Gitee, which was brief mentioned in a previous article, mainly involving Jenkins permissions and Gitee API calls.
http://username:user_token@jenkins_external_domain:port/job/project_name/build?token=webhook_password
The Dockerfile needs to be placed in the project root driectory, involving copying and compiling project files, like this:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN apt-get clean
RUN apt-get update
RUN apt-get install -y --no-install-recommends libgdiplus libc6-dev
RUN apt-get -y install fonts-wqy-zenhei && apt-get clean && fc-cache -fv
WORKDIR /app
EXPOSE 8238
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ./ /src
RUN dotnet restore "./FruitsCMS.Mvc/FruitsCMS.Mvc.csproj"
COPY . .
WORKDIR "/src/FruitsCMS.Mvc/"
RUN dotnet build "FruitsCMS.Mvc.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "FruitsCMS.Mvc.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FruitsCMS.Mvc.dll"]
An issue was encountered where the container ran easily but could not be accessed. The reason was that localhost could only be accessed within the container, so the hosting.json needed to be written as follows:
{
"urls": "http://*:8238;"
}
Here is the Jenkins build script:
# Switch to the source code directory, corresponding to the workspace under jenkins-home
cd ~/workspace/FruitsCMS;
image_version=`date +%Y%m%d%H%M`;
echo $image_version;
# Stop the previous docker container
docker stop fruits_cms;
# Remove this container
docker rm fruits_cms;
# Build the image and tag it
docker build -t fruits_cms:$image_version .;
docker images;
# Run the just built image
docker run -p 8082:8238 -v fruitscms-log-vol:/app/LogFiles -v fruitscms-resource-vol:/app/wwwroot/Resource/ -e TZ=Asia/Shanghai --restart=always --name fruits_cms -d fruits_cms:$image_version;
docker logs fruits_cms;
This part involves mapping the resource folder to the host directory. After checking, it turned out that using volumes was the right approach. Refer to the link: https://www.cnblogs.com/edisonchou/p/docker_volumes_introduction.html. During the initial installlation, Jenkins might not have permission to run Docker commands. The following script should be executed:
sudo groupadd docker # Add docker user group
sudo gpasswd -a $USER docker # Add the login user to the docker user group
sudo gpasswd -a jenkins docker
sudo service jenkins restart
newgrp docker # Update user group
docker ps # Test if Docker commands can be used with sudo
Alternatively, edit the group file and insert the jenkins user after the docker group, separated by commas in English:
vi /etc/group
newgrp docker # Update user group
service jenkins restart # Restart Jenkins