Summary and table of contents

With the machine in place and the Docker infrastructure in place, let’s deploy GitLab with Docker and implement a CICD process with a standard front-end engineering

Install Gitlab

Installing GitLab is our top priority

  • Pull it off the Docker
docker pull gitlab/gitlab-ce
Copy the code
  • Configure it
$ sudo docker run --detach \
  --hostname gitlab.example.com \   Note that ⚠️ is best set to your Intranet Ip address--publish 443:443 --publish 80:80 --publish 22:22 \ name gitlab \ # gitlab-ce --restart always \ # Set the restart mode, always means always on, Server will open automatically after boot - volume/SRV/gitlab/config: / etc/gitlab \ # to map gitlab configuration file directory to/SRV/gitlab/config directory - volume / SRV/gitlab/logs: / var/log/gitlab \ # will gitlab log file directory mapping to/SRV/gitlab/logs directory - volume/SRV/gitlab/data: / var/opt/gitlab Gitlab /gitlab-ce:latest # Image to run

#443:443: maps HTTP :443 to external port 443
#99:80: Maps Web :80 to external port 9000
#22:22: Maps SSH :22 to external port 22

#I finally got it rightDocker run -d --hostname 192.168.1.5 -p 443:443 -p 80:80 -p 233:233 --name gitlab --restart always -v/srv/gitlab/config:/etc/gitlab -v /srv/gitlab/logs:/var/log/gitlab -v /src/gitlab/data:/var/opt/gitlab docker.io/gitlab/gitlab-ceCopy the code

Otherwise, your git repository’s default address is [email protected]:// XXX, but the correct address should be your own IP address, and the setup is very simple

#Change the SSH address first
#-v /home/gitlab/config: /etc/gitlab 
$ vim /home/gitlab/config/gitlab.rbGitlab_rails ['gitlab_ssh_host'] = '192.168.52.129' change to your own IP address ++++
#After that, go to bash and restart the GitLab application in the container
$ docker exec -it gitlab /bin/bash
$ gitlab-ctl reconfigure
$ gitlab-ctl restart

#Then change the HTTP address
$ vim /home/gitlab/data/gitlab-rails/etc/gitlab.ymlHost: 192.168.52.129
#After that, go to bash and restart the GitLab application in the container
docker exec -it gitlab /bin/bash
gitlab-ctl restart

Copy the code
  • About the password

After gitlab is started, you can see the password of root here, remember to change the password after login, we have a simple command to check (because we are docker installed, so it is relatively easy, if you are not Docker installed, you need to find another method).

$ sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
Copy the code
#And when you're done with that,
#When you see the Gitlab container, it means your container is up and running, and you can then enter the host IP for web accessroot@joney-N8xEJEK:~# docker ps asCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 989f74cd9bbc Gitlab /gitlab-ce:latest "/assets/wrapper" 4 weeks ago Up 7 days (healthy) 0.0.0.0:80->80/ TCP, ::80->80/ TCP, 22/ TCP, 0.0.0.0:443 - > 443 / TCP, : : : 443 - > 443 / TCP gitlab root @ joney - N8xEJEK: ~ #Copy the code

GitlabCI

After everything is ready, we will do the CI process (based on GitlabCI), here is the simplest implementation, there are many functions that have not been implemented in the subsequent articles we will optimize a little bit. GitlabCI + Docker + React + Flybook swarm robot

First, let’s introduce GitlabCI

CI is an automated build, which is when you write code, submit it to the repository, trigger some event, and then the server automatically builds your application, CD is when you automatically publish your application after you automatically build it

Concept to explain

  1. We can implement different CI processes for different projects by configuring different.gitlab-ci.yml files under different projects, which will look something like this
stages: # section
   - package
   - install
   - lint
   - build
   - deploy

cache: # cache
   paths:
       - node_modules
       - build
       - gitlab_test_ci.tar

package-job: # job1
   tags:
       - hot
   only: 
       - develop
       - release
       - master
   stage: package
   script:
       - npm config set registry https://registry.npm.taobao.org/

install-job: # job2
   tags:
       - hot
   only: 
       - develop
       - release
       - master
   stage: install
   script:
       - npm install

lint-job: # job3
   tags:
       - hot
   only: 
       - develop
       - release
       - master
   stage: lint
   script:
       - npm run prettier-format
       - npm run lint
Copy the code
  1. Pipeline & Job: Pipeline is a process executed by Gitlab according to the.gitlab-ci.yml file of the project. It is composed of many task nodes, and each task node on these pipelines is an independent Job

The configuration of jobs in YML is described in the following sections. For now, you need to know that each Job is configured with a stage attribute, which indicates the stage of the Job.

A Pipleline has several stages, and each stage has at least one Job, as shown in the figure below:

  1. Who’s going to run our jobs?

Once we know the basics, let’s ask ourselves, who is responsible for doing what we do? Gitlab-runner is a small program responsible for these jobs, which is specially born for Gitlab-CI. Many jobs can be run on this program. Of course, it usually requires some configuration to use, see below for details.

There are two types of Runner: Specific Runne (left) and Shared Runner (right).

Shared Runner is a free Runner program provided by the Gitlab platform, which is supported by the Google Cloud Platform and has dozens of developers per team. It is free to use for public open source projects and has a maximum CI time of 2000 minutes per month for private projects.

Specific Runner is a self-defined Runner program that runs on the machine we choose. Gitlab provides us with a command line software called Gitlab-Runner. As long as you download and install this software on the corresponding machine, And run the Gitlab-Runner register command, and then enter the token obtained from the Gitlab-CI interface to register, you can run the pipeline program remotely on your own machine.

Shared Runner can be used by all projects, while Specific Runner can only run for Specific projects. Shared Runner runs on docker by default, An environment for pipeline execution without pre-assembly, such as Node, etc. As for Specific Runner, you can freely choose platforms, such as various types of machines, such as Linux/Windows, and assemble the necessary running environment on them. Of course, you can also choose private projects such as Docker/K8s to use Shared Runner, which is limited by running time. Specific runners are completely free to use.

Executor concept

What is an Executor? As mentioned above, Specific Runner is executed on the platform of our choice, which is now called “Executor”. For simplicity, we chose shell instead of Docker. I have also posted the comparison chart of the official document for your reference and selection of your own

Reference links: docs.gitlab.com/runner/exec…

  1. . Gitlab-ci. yML basic knowledge literacy. So that you can get started faster

Before we start, I hope you have some understanding of the following concepts. Gitlab-runner is executed step by step according to the.gitlab-ci.yml file

stages: 
    - package  # These correspond to the markers at 1. To indicate which stages to proceed
    - lint
    - build
    - deploy

cache: # cache Settings
    paths:
        - node_modules
        - build
        - gitlab_test_ci.tar

package-job: # job1 
    tags:  # tag, you want to run your runner on the specified tag, you want to throw the job to the runner represented by the tag
        - hot
    only:   # flag which branch is valid on this job
        - develop
        - release
        - master
    stage: package  # 1. What is a "job stage"
    script:  The shell command you want to execute
        - npm config set registry https://registry.npm.taobao.org/

#... There are more jobs down there but for the most part that's the structure
Copy the code

Practical operation

The github repository is my own initial react-TS infrastructure that contains Lint and COMMIT and ESLint as well as Peptic. We don’t care how this is constructed, we’ll cover it in another article). Next we prepare the other materials

  1. First we have a React template on Github that contains some basic functionality.
  2. We have built our Own GitLab, and now we will put the React template into our own GitLab repository.
  3. Configure runner for our warehouse.
  4. Start writing.gitlab-ci.yml.
  5. Debug and run.
  • Lazio starts with a React-TS template and uploads it to its Own GitLab repository.
$ git clone https://github.com/BM-laoli/react-ts-template
$ cd react-ts-template 
$ git checkout react-tpl
#To do this, you need to set up a repository in your GitLab
$Git remote add http://192.168.1.5/bigfe/ci-react-pc-test.git org 
$ git checkout -b develop

#Pull an Develop branch to do it
$ git push org develop 
Copy the code
  • The configuration of runner

Download runner, here I did not throw runner into docker, directly put the host machine, the main reason is that it is very troublesome to build docker image and operate and interact with the host machine if it involves runner on docker. Did more than a week with no results, then gave up), decisively put runner in the host machine

# Linux x86-64
$ sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

$ sudo chmod +x /usr/local/bin/gitlab-runner

$sudo gitlab-runner install --working-directory=/home/gitlab-runner

$ sudo gitlab-runner start
Copy the code

To configure it, first let’s open the project on GitLab and follow the diagram to find it

Then a few parameters of 👇 are important

$ sudo gitlab-runner register
#Then follow the command line to.... As for the parameters to be filled in, you can find them in the figure above, especially the tag. Let's write a random one here called hot
#After completing the above operations, enter the following command to execute
$ sudo gitlab-runner verify --delete

#In this case, you can directly enter the runner to observe which jobs are running, which jobs fail, and why they fail. There is a bug that I have encountered here is that the piple has not moved and cannot run. After I run into the runner, it will be fine.
$ sudo gitlab-runner run

Copy the code

After following the above steps, we come to GitLab and if the color green indicates OJBK, we will finish the next task

  • Write. Gitlab – ci. Yml

Every project has different deployment requirements, so YML is not static. Here I design the implementation according to the following scenario

There are two major phases, culminating in the use of Node to open build static file access

Phase 1 Front-end framework packaging:

Node_modules download node_modules download node_modules download node_modules download node_modules download node_modules download node_modules download node_modules download node_modules download node_modules download node_modules download node_modules

Phase 2 CV the static file into the Docker image

Use Node to start a static resource service for external access: Use Dockerfile to CV the static file into a Docker image that contains nodeJS. Finally, run the container, and improve the container update and automatic restart upgrade

.gitlab-ci.yml

# @format

[package]
# node_module install
# check husky, code formatting, check eslint
[docker] # docker [docker]
# rundocker [rundocker]

We need to give some variables to control ci/ CD execution but we won't write them here

stages: # section
    - package
    - install
    - lint
    - build
    - deploy

cache: # cache
    paths:
        - node_modules
        - build
        - gitlab_test_ci.tar

package-job:
    tags:
        - hot
    only: 
        - develop
        - release
        - master
    stage: package
    script:
        - npm config set registry https://registry.npm.taobao.org/

install-job:
    tags:
        - hot
    only: 
        - develop
        - release
        - master
    stage: install
    script:
        - npm install

lint-job:
    tags:
        - hot
    only: 
        - develop
        - release
        - master
    stage: lint
    script:
        - npm run prettier-format
        - npm run lint

build-job:
    tags:
        - hot
    only: 
        - develop
        - release
        - master
    stage: build
    script:
        - npm run build
        Give a path to a build directory
        Since gitlab CI is the product of delete job by default, we use cache to cache part of the content
        For subsequent jobs
        
deploy-job: The operation here is mainly to get build from runner and send it to the remote server, and then build docker image on the remote server
    tags:
        - hot
    only: 
        - develop
        - release
        - master
    stage: deploy
    script:
        - docker image build -t gitlab-runner-ci-test .
        Stop the running container and immediately update it to run with a shell script
        - sshpass -p "your-password" chmod 777 build.sh
        -  ./build.sh

# Here you can change whether to deploy to dev, Pre or PRD based on your actual situation. In our case, there is also a prebld. sh script to build the local environment and inject THE API address, so that the environment can be configured
# deploy-job: # Get the build from the runner and send it to the remote server, and then build the Docker image on the remote server
# tags:
# - hot
# stage: deploy
# only:
# - master
# script:
# - docker image build -t gitlab-runner-ci-test .
# # Stop the running container and immediately update it to run with a shell script
# - sshpass -p "your-password" chmod 777 build.sh
# - ./build.sh
Copy the code

dockerfile

Get the Node environment
# get NPM
# get serve
# CV build file
# Run the run command

# SSH container running
FROM node:alpine
COPY ./build /app
WORKDIR /app
RUN npm config set registry https://registry.npm.taobao.org 
RUN npm install serve -g
CMD ["serve"."."."-p"."3002"]
EXPOSE 3002

Copy the code

Build. sh here explains why scripts are needed. The main reason is that in order to reduce volume consumption and container duplication and container conflict during docker container update, we can complete image restart and version iteration according to it

#! /bin/bash
## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#If the container doesn't exist, create it. If it does, update it
## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #docker stop gin-gotest docker container rm -f $( docker ps -aq --no-trunc --filter name=gin-gotest) if [[ "$?" -eq '0' ]]. Then docker container run --name=gin-gotest -d -p 8200:8000 go-gin echo "Update succeeded" else Docker container run --name=gin-gotest -d -p 8200:8000 GO-gin echo "Initialization successful" "FI echo" Deployment complete"Copy the code
  • Run and debug

Would see us finally succeeded after several attempts, now let’s have some other things, such as to the process with a group of flying book direction robot (mainly fly book document configured with a webhook), according to the documents we need, first create a group, and then according to the graphic operation Combining fly books official documentation configuration, For example, here is a very simple configuration is just a section of connection, because we use the Webhook mechanism, so after we configure, we first use Postman to try, if there is no problem, then your flying book robot will be triggered. Now we drop it into the CI process, here I drop it into a later build Success phase, and report it to the group if it succeeds

#! /bin/bash
## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#If the container doesn't exist, create it. If it does, update it
## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #docker stop gin-gotest docker container rm -f $( docker ps -aq --no-trunc --filter name=gin-gotest) if [[ "$?" -eq '0' ]]. Then docker container run --name=gin-gotest -d -p 8200:8000 go-gin echo "Update succeeded" else Docker container run --name=gin-gotest -d -p 8200:8000 GO-gin echo "Initialization successful" "FI echo" Deployment complete"
#Send flying book notice, the follow-up need to write a service to integrate their own account systemcurl --location --request POST 'https://open.feishu.cn/open-apis/bot/v2/hook/youer-authkey' \ --header 'Content-Type: Application/json \ '- data - raw' {" msg_type ":" post ", "content" : {" post ": {" zh_cn" : {" title ":" project update notification ", "content" : [[{" tag ", "text", "text", "project update:"}, {" tag ":" a ", "text", "see", "href" : "Http://192.168.1.5/big_ef/gitlab_test_ci"}}}}}]] '-Copy the code

conclusion

Gitlab-runner is a relatively simple and low-cost CICD tool I have contacted so far, and most CICD tools are the same. I hope students can learn it well, especially Shell script writing. As a developer, Shell script writing is a necessary skill no matter whether it is front-end or back-end

Refer to the connection

Ruan Yifeng Docker introduction

Docker Chinese Community