In the Spring Cloud configuration service, I mentioned that I was messing around on the small Cloud, but the learning skills are not fine, and it is quite laborious to toss about. In order to make the toss easier, I launched the configuration service. In fact, in addition to fiddling with configuration parameters, code changes are inevitable (although often just adding or deleting a line of code). For example, cross-domain access to resources will be blocked by CSRF, so you have to add.csrf().disable() to verify the function. In order to further make my journey more leisurely, I began to look for a lightweight, free CI environment.

A few years ago, when Github was used as a repository, Travis CI was given resources for nothing. It was simple to add a.travis. Yml configuration file to the code (see this one). Then add the Github account public key in the Travis CI control panel. When code is submitted to the Master branch of Github repository, it is automatically compiled into jar packages, packaged into containers, and then automatically published to Docker Hub. The cloud only needs to update the container for deployment. In fact, Travis CI can call the cloud interface again for fully automatic deployment, but the juchang elastic server purchased at that time did not open the relevant interface. Note 2: There is also a way that Travis CI can push DockerHub and submit an issue to Github’s repository, using Github’s WebHook to initiate a POST request to the cloud to trigger a Docker update. .

For standard

Now the station master repository has been switched to Gitee, Travis CI does not support small Gitee, so we have no choice but to find a replacement, but fortunately it can be used as a calibration.

There are plenty of other products that offer similar functionality, but either charge for it or are too heavy, like Gitee Go or Jenkins. It’s not that they’re not good, they just don’t fit my scenario.

demand

  1. It can be started quickly at any time and not resident in the system after completion (after all, small cloud resources are limited).
  2. You can compile Spring Cloud projects and package them as Docker (you don’t need to publish them to DockerHub because they are already in the Cloud, you can run them directly).
  3. The host environment configuration is not affected and the host runs stably.

The selection

The good news is that SpringBoot now supports direct compilation to Docker (see “3 Ways to Build A Docker Image by SpringBoot”), but none of them meet the third requirement because they require at least a Maven environment on the host. So does the Maven environment affect host running? I think the chances are low, but if the host is running on an unusual system, it might take a lot of work to set up. Unfortunately, xiaoyun is just such a system — CoreOS, a system that has stopped updating and has been acquired. 🤣

To keep the host stable and not change the host environment, what is on my host right now? There’s Docker, git, nginx, and nothing else. It looks like you’ll have to use existing tools for code compilation and container packaging. Since the final output is docker image, it is necessary to find a breakthrough in Docker.

Docker multi-stage build

Docker 17.05 native support for multi-phase builds, what is multi-phase builds? Click here, please. In simple terms, docker build can be divided into multiple stages as required, and the input and output of each stage can be controlled. Then we can use compilation as the first phase of construction, and the final packaging of images as the second phase. So my Dockerfile could say:

FROM registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8 AS build-env
LABEL stage=tmp-build

ENV MY_HOME=/app
RUN mkdir -p $MY_HOME
WORKDIR $MY_HOME
ADD pom.xml $MY_HOME

RUN ["/usr/local/bin/mvn-entrypoint.sh"."mvn"."validate"."clean"."--fail-never"]
ADD . $MY_HOME

RUN ["/usr/local/bin/mvn-entrypoint.sh"."mvn"."verify"."-Dmaven.test.skip=true"]

FROM openjdk:8-jre-alpine
COPY --from=build-env /app/target/*.jar /app.jar
ADD run.sh run.sh
RUN chmod a+x run.sh
Copy the code

The first stage is called the build-env compilation stage, and its goal is to compile and export the final JAR package, so this stage does not care about the docker image size and hierarchy (it is all intermediate anyway). Even so, this stage is interesting. First, select the Maven image with the JDK, then add the POM file first, and pull the required library files based on the POM. Then add the source code project to compile. There should be room for further acceleration at this stage, but there you go.

The second stage is to output the final image, so a relatively small Alpine image is chosen. At the same time, in order to reduce the hierarchy and improve the readability, I encapsulated the container execution entry into the run.sh script (for debugging convenience, automatic execution was not added, the actual application of the docker-compose specified run.sh).

Once you have the Dockerfile ready, put it with the Spring Cloud project and update it with the code. To do this, run docker build -t

. Will do. Normally you should see something like this:

Effect of additional

Imagine when everyone gets together to celebrate the Spring Festival, you silently take out your mobile phone, click a few times seemingly at random and then gently put it on the table, turn around and chat with everyone about their parents. Finally, someone will ask you what you are doing. At this time, you must control your emotions and voice, and slowly say: “Oh, it’s the American’s small plane fell into the water, and I’m just free today, I’ll help the country to find it.” Did you pull off a perfect make-believe? The so-called invisible force is the most deadly.

legacy

Multi-stage build is really convenient, and reasonable use can well meet my small needs. However, the intermediate products generated by multi-stage build will not be deleted automatically. Docker images-a can see many images marked as None, but don’t panic, execute a shell command to delete them in batches:

docker rmi $(docker images -a | grep none | awk '{print $3}')

The last

Thanks to clouds, many things that could not be done before can now be done. Because of the cloud, resource utilization can be higher. Thanks to the cloud, the role and boundaries of portable devices have been expanded. Because of clouds, all kinds of imagination are gradually becoming reality.