On the front end of development process, we need to solve not only the style of the page, browser compatibility, and user’s experience, of course, these are very important part, but some, although we do not need to pay special attention to, but it exists, is of the repair in time with some of our project timeliness, play a crucial role.

Be prepared before you look at it, maybe someone can do it, but I didn’t do it before, if you can don’t spray me, if you can’t ask me

The purpose of doing this

Actually, it is always before I personally also didn’t notice a problem, eyes rest early do page, how to write better, how to render faster, how the user experience, best for project deployment this hasn’t been keen studied, because did not understand this piece of knowledge, I always thought this time it is so long, There’s no way to optimize.

Later, as the project needed to make local version requirements, the mirror image was too large, and both the front and back ends needed to be optimized to a large extent. At that time, MY eyes focused on this piece of content.

course

The way it was implemented before

Before optimization, the implementation method is actually very simple: pull the current branch content through Git in the deployment platform, install all dependencies according to package.json, package the build, and build the image in the deployment platform. After construction, release the image to the container through the platform.

Advantage: save worry, on the point once finished

Disadvantages: Large image, slow release, slow build, once the network or platform problems, image has the risk of build failure, and the cost of emergency repair is very high

Most online implementations

I have checked some methods on the Internet before, and now I have found some implementation methods, which are through CI, and then select the corresponding branch to build docker image, and finally publish it to the corresponding container.

Advantages: Easy to build a mirror. You can set the cache and reduce the mirror volume

Disadvantages: Poor controllability. When Github projects use GitLab CI, there is frequent push and a commit update delay, so the project cannot be built in the first time. Different branches have different NPM packages to do cache processing, and the maintenance cost is high

Thinking process

Local simulation

Before I do optimization, I have to think about, where is the range of optimizations, is it the size of the code? In fact, it is not realistic to optimize the code a few meters, because the total package code is not large, here is not an important point I need to optimize, so I plan to build the image locally in accordance with the platform to build the image.

Part of docker knowledge is required here, but it is not much and not difficult. I will not talk about the installation method of Docker, so we can search for it by ourselves

Execute docker command locally:

docker build -t local-test:2150PATH(your current project directory)Copy the code

This is what the command line looks like, it’s a mess to install, because as I said, the image is built on the platform, so the platform has to install a lot of packages, a lot of content, and finally the image is built properly.

View mirror information locally

After the normal image construction is complete, we can check the current image construction locally:

docker images
Copy the code

Then we find the currently built local image, and we can see the size of our current image:

Now we can see that the mirror image is very large, 1.65 grams, which is a very scary size, and then we can go on to dissect what is taking up so much of it.

Start the Docker container locally

Enter the container:

docker run -it local-test:2150 /bin/bash
Copy the code

View all file sizes of the current mirror:

cd /
du -d1 -h
Copy the code

This way we can see the size of all directories, and now we can see exactly what is occupying the mirror size:

Look at the code:

A node_modules module is completely useless and can be destroyed.

There is also a./usr folder, which takes up 1.2GB, which is a similar situation, but doesn’t take up any content here.

In fact, the main thing about mirroring is that nginx and the dist folder after build, most of the other stuff is useless and can be removed, and we can probably see where the problem is.

If you can find the essence of the problem, it is not a problem, it is experience - enthusiastic Uncle LiuCopy the code

Solving steps

Optimize dockerfile

Let’s look at the dockerfile before I optimized it:

FROM debian:9

RUN echo\ deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ stretch  main non-free contrib\ deb http://mirrors.aliyun.com/debian-security stretch/updates main\ deb-src http://mirrors.aliyun.com/debian-security stretch/updates main\ deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib\ deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib\ deb-src http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib\ > /etc/apt/sources.list

RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y git-core curl build-essential
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
RUN npm config set registry https://registry.npm.taobao.org

RUN mkdir /code
ADD . /code
WORKDIR /code

RUN npm install
RUN npm run build:test

RUN cp -fr /code/dist/ /usr/share/nginx/html/
COPY nginx/prod.conf /etc/nginx/nginx.conf

EXPOSE 80

STOPSIGNAL SIGTERM

CMD ["nginx"."-g"."daemon off;"]

Copy the code

/usr/share/nginx/ HTML /nginx configuration /etc/nginx/nginx.conf /nginx/nginx.conf /nginx.conf /nginx.conf /nginx.conf /nginx.conf /nginx.conf /nginx.conf /nginx.conf /nginx.conf Start the nginx.

Streamline dockerfile

After deleting the above things, I found that I still needed a build. At this time, I came up with a way to overtake: local build

FROM debian:9

ADD ./dist/ /usr/share/nginx/html/dist/
COPY nginx/prod.conf /etc/nginx/nginx.conf

EXPOSE 80

STOPSIGNAL SIGTERM

CMD ["nginx"."-g"."daemon off;"]
Copy the code

Wouldn’t it be neat if we didn’t have to re-build the image locally, and we knew that the useless stuff wouldn’t be in the image we were building, because we didn’t have to do anything else, just copy and launch, and we’re done.

An automated build

Image after the optimization, the biggest problem we solved, then to solve things, is we can’t endless always build locally, such as more busy operating multiple projects at the same time, or you need to different functions in different branches of frequent development, build yourself again and again, will be yourself to death.

The purpose of optimization is to improve work efficiency and reduce the cost of repetitive work, so if manual build, it is not as good as that, because manual build always has mistakes, often walk in the river, where there is no wet shoes.

In this case, I implemented an automated build based on Git hooks, which have pre-push hooks that do things before code is pushed.

In development, every time the code is pushed, it means THAT I may have to deploy a release to the server, either for testing or officially.

Every time we publish the image, the image name can be the same, but it needs to be distinguished by tag. Currently, I do the tag by time string

// .huskyrc.js
module.exports = {
  hooks: {
    'pre-push': 'NPM run build && docker build-t images: Tag PATH(current project directory) && // sent here to the platform for image publishing',}}Copy the code

Environment to distinguish the

In a project, it is not possible to have only one branch, and it is not possible to have only one server, at least we have to distinguish between one test, one formal server and two servers.

Git flow: Git flow: git flow: git flow: git flow: git flow: git flow

// Get the current branch name
const branch = execSync('git rev-parse --abbrev-ref HEAD')
  .toString()
  .replace(/\s+/.' ')
Copy the code

Branches to distinguish between build commands, images image names, and dockerfile files:

var branchAuthority = {
  'dev': {
    docker: 'Dockerfile.test'.image: 'local-test'.build: 'npm run build:test',}}Copy the code

Modify. Huskyrc. Js:

module.exports = {
  hooks: {
    'pre-push': ` \${build} && \
      docker build -f ${docker} -t ${image:tag} ${path}
    `,}}Copy the code

The overall process is probably like this, the rest is some details of the optimization, such as if planning branchAuthority structure, mirror construction is completed, after the completion of the release of the need to delete the local mirror and other optimization behavior.

conclusion

Effect of contrast

Before optimization: image size 1.65g, construction and release time about 600s;

After optimization: image size 350M, build and release time 120s

Optimized steps

  • The installationgit hooksdockerfile
  • Do environment, image, docker differentiation
  • After building locally, start a container locally, first test whether there is a problem with the process, there is no problem in embeddingpre-push
  • Finally, you can run

At the end

In fact, there is no technical difficulty in the overall sorting out, and it is very simple, it is a process of optimization, a solution that I have nothing to do, maybe we have a better way to solve the problem of project construction and deployment, if you can communicate with each other.

I haven’t written an article for nearly a year. A lot of things have happened in this year. With the change of work, a year has passed, and I don’t know if we can understand the layout and text, and if there is anything unclear, we will point it out, and the article will be updated normally.