One, foreword

As a front-end dishes chicken, the server is not good. When I first deployed the website on the Linux server, I usually packaged the front-end code and manually uploaded it through FTP. The back-end code was directly connected to the server using SSH in vscode to directly synchronize the code changes. But black as a life of endless torment of the monkey program, certainly to explore a more fun and efficient way, so this time, WE began to torment the next automation deployment scheme

Second, preparation

1. Continuous integration Service (CI) scheme selection

Automated workflows for code submission rely on continuous integration (CI) (or continuous delivery (CD)) services. The mainstream public free continuous integration services include:

  • Travis CI
  • Jenkins
  • Circle CI
  • Azure Pipeline
  • GitHub Actions

GitHub Actions is GitHub’s own continuous integration and automation workflow service, which is easy to use and is also the service xiaohei uses this time. It’s as simple as creating a. Github /workflows folder in your repository root directory and putting your workflow configurations (YAML files) in that directory to enable github Actions.

Xiaohei’s website is deployed to Tencent cloud server, so the configuration process used the server related configuration, if you want to put the website on GitHub Pages, that only need to have a GitHub warehouse can start to toss up, the following configuration about the remote server can be ignored.

2. Add the deployment key

To deploy files to a remote server, you must first resolve the issue of login verification. Common ones are password login, SSH key login, or VNC login. You are advised to use an SSH key to log in to the system for security.

2.1. Generate an SSH key pair

If you need to deploy to the server remotely, you must have configured the SSH key pair already. Therefore, we can copy the contents of the private key file directly, and then configure it in GitHub. Here small black no longer repeat

2.2. Set automatic configuration items on GitHub

After the SSH key pair is generated, the preparation is almost complete. The last step is to configure the configuration items in the YAML file to Github. Click Setting > Secrets > New sceret, and then add the copied key file content, server host and login user name to the configuration corresponding to the following picture, so that even if the project is open source like Xiao Hei, the privacy information will not be disclosed.

With this configured, we are ready to write the workflow file

3. Configuration process

1. Write workflow files

Created in the warehouse the root directory. Making/workflows folder, create a YAML file, file name set, I here named deploy yml, so the full path to the file should for. Making/workflows/deploy yml, within the meaning of the configuration is written in the comments! Of course, xiaohei will briefly introduce the key configuration items

1.1. Basic configuration of files

The first is the basic configuration of YAML files

The content in on is important, specifying the events that automatically trigger the workflow file, or you can set the workflow to run only on certain branches, paths, or tags. For example, black is triggered when a push is made on the master branch and changes to readme. md and LICENSE files are ignored

In Jobs, there are all the following work flows to be run. Hei sets a job called build-production, and multiple jobs can be set as required

This is a new virtual machine that runs on GitHub and is not compatible with the OS or server system that runs the job. This is a virtual machine that runs on GitHub and is not compatible with the OS or server system that runs the job. Just set it to Ubuntu-Latest like Black

Node-version in the strategy may not be configured, but is configured for consistency with the local node version

Steps are the steps that need to be executed

name: Blog CI/CD

on:
  push:
    branches:
      - master  # Push triggers deployment only on master
    paths-ignore:   Changes to the following files do not trigger deployment and can be added on their own
      - README.md
      - LICENSE

jobs:
  build-production:

    runs-on: ubuntu-latest   # use ubuntu image to run automatic scripts (tips: it doesn't matter which OS or server you are using, I use windows10 locally, centos for cloud server)
    strategy: (optional)
      matrix:
        node-version: [12.x] Configure the required node version
    steps:  # Automated steps
    ...
Copy the code

1.2. Download the code

This step is to checkout your repository and download the code inside to runner,actions/checkout@v2 is the official self-made wheel, just use it

    - uses: actions/checkout@v2   Step 1, check out the warehouse copy
Copy the code

1.3 (Optional) Configuring the Node Version

This step is to install node, wheel is also official, version optional, use NPM to package (do not need to package the project can be omitted 1.3-1.5)

    - name: Use Node.js The ${{ matrix.node-version }} 
      uses: actions/setup-node@v1
      with:
        node-version: The ${{ matrix.node-version }} # Specify node.js version (optional)
Copy the code

1.4. Install dependencies

I don’t need to explain this step

    - name: Install dependencies  # Step 2, install dependencies
      run: npm install
Copy the code

1.5. Package code

The –if-present flag is used to avoid non-zero exit if the script is not defined

    - name: Build              # 3, package the code
      run: npm run build --if-present
Copy the code

When deploying the server, xiao Hei stepped on a big pit, which was clearly packaged, but did not end the task, into the next step

Even after paying to go to the toilet, he still hasn’t finished the Build task. It’s thanks to the training of loving each other with the product that hei didn’t feel upset

Change to YARN packaging? Failed +1 to change node version? Failure + 2… ??????? Failure + N

Uncle can not endure, uncle can endure his aunt can not endure! This is going to force black to make a big move! Face the wind!

… %… *(¥@ (¥@ (∗(*(∗)) Look at my operation as fierce as tiger ~

Finally, after offering three precious hair, let xiao Hei finally find the problem

I’m bald and I’m strong! – the little black

The node. js process does not terminate after the package is packed. You did not notice this problem by manually closing the node. js process with Ctrl + C.

Storm cry ~

The webpack is only a scratch, and the observation mode is not enabled. Baidu Google searched the document again and again, and I don’t know which one is using the Node.js process. Exit (0); Just kill!

Push a try, as expected Build task successfully completed, I am a f * * king genius, reward yourself delicious feed a catty!

1.6. Push deployment to the server

The packaging was successful, and then it was time for the exciting deployment to the server, where we still used the wheel that someone else had built

DEPLOY_KEY, SERVER_IP, and USERNAME are the SSH private keys, host names, and login names that we have just configured in Github

The main things to watch out for are FOLDER and SERVER_DESTINATION, which is our push FOLDER and destination FOLDER. Make sure to write the path correctly here.

Source code: rsync-deploy

    - name: Deploy to Server  Step 4, rsync push files
      uses: AEnterprise/[email protected]  # Use someone else's packaged step image
      env:
        DEPLOY_KEY: The ${{ secrets.DEPLOY_KEY }}   SSH private key
        ARGS: -avz --delete --exclude='*.pyc'   The # rsync parameter excludes. Pyc files
        SERVER_PORT: '22'  # SSH port
        FOLDER: ./build/*  The path of the folder to be pushed is relative to the root directory of the repository
        SERVER_IP: The ${{ secrets.SSH_HOST }}  Host name (IP address or domain name domain.com)
        USERNAME: The ${{ secrets.SSH_USERNAME }}  # reference configuration, server login name
        SERVER_DESTINATION: /www/wwwroot/lmsworld.cn/   Deploy to target folder
Copy the code

I’m here is to build a folder file replace directly to web root directory, there is not file cannot be replaced with the same situation, intended to first remove web root folder to replace, but consider the packaging the possibility of failure or deployment, delete may not be able to access the site, hence temporarily don’t use this method, the subsequent have time continue to improve, Write here still hope big guy gives directions much ~

1.7 restart the service (Depending on the situation)

If is only deployed front-end code, it likely won’t have to restart the service, if want to back-end code, is about to restart the service Can in YAML configuration file plus a backend deployment job, using the need to control the workflow, and then in the script, in turn, write down the server running on the command line, Small black is written with node background, for reference only

    - name: Restart server   Step 5: Restart the service
      uses: appleboy/ssh-action@master
      with:
        host: The ${{ secrets.SSH_HOST }}  The following three configurations are similar to the previous step
        username: The ${{ secrets.SSH_USERNAME }}
        key: The ${{ secrets.DEPLOY_KEY }}
        Migrate database and restart servers. Migrate database and restart servers
        script: | cd /www/server/web-server/ pm2 reload app.jsCopy the code

1.8 complete configuration files

Stick a complete configuration file, modify the configuration according to their own projects on the line, can not be used to small black message

name: Blog CI/CD

on:
  push:
    branches:
      - master  # Push triggers deployment only on master
    paths-ignore:   Changes to the following files do not trigger deployment and can be added on their own
      - README.md
      - LICENSE

jobs:
  build-production:

    runs-on: ubuntu-latest   # use ubuntu image to run automatic scripts (tips: it doesn't matter which OS or server you are using, I use windows10 locally, centos for cloud server)
    strategy:
      matrix:
        node-version: [12.x] Configure the required node version
    steps:  # Automated steps
    - uses: actions/checkout@v2   Step 1, check out the warehouse copy

    - name: Use Node.js The ${{ matrix.node-version }} # Specify node.js version (optional)
      uses: actions/setup-node@v1
      with:
        node-version: The ${{ matrix.node-version }}

    - name: Install dependencies  # Step 2, install dependencies
      run: npm install

    - name: Build                 # 3, package the code
      run: npm run build --if-present

    - name: Deploy to Server      Step 4, rsync push files
      uses: AEnterprise/[email protected]  # Use someone else's packaged step image
      env:
        DEPLOY_KEY: The ${{ secrets.DEPLOY_KEY }}   SSH private key
        ARGS: -avz --delete --exclude='*.pyc'   The # rsync parameter excludes. Pyc files
        SERVER_PORT: '22'  # SSH port
        FOLDER: ./build/*  The path of the folder to be pushed is relative to the root directory of the repository
        SERVER_IP: The ${{ secrets.SSH_HOST }}  Host name (IP address or domain name domain.com)
        USERNAME: The ${{ secrets.SSH_USERNAME }}  # reference configuration, server login name
        SERVER_DESTINATION: /www/wwwroot/lmsworld.cn/   Deploy to target folder

    Step 5: Restart the server
    # uses: appleboy/ssh-action@master
    # with:
    ${{secretsecrets.SSH_HOST}
    # username: ${{ secrets.SSH_USERNAME }}
    # key: ${{ secrets.DEPLOY_KEY }}
    Restart scripts: Migrate database and restart servers
    # script: |
    # cd /www/server/web-server/
    # pm2 reload app.js
Copy the code

2. Final effect

Black can’t wait to modify the configuration file after push to the warehouse, this workflow run smoothly, nothing wrong reported, it is perfect!

In this panel you can see the specific tasks each step of the time and output information, error information can also be queried here oh

Finally, if you are deployed to Tencent Cloud, Ali Cloud and other cloud service platforms, you will generally receive oneSafety warning noticeFor example, Xiao Hei uses Tencent CloudThere are fromIP: 40.122.43.158Abnormal login, this IP is whose, let the small black checkMicrosoft Data Center? It is the IP address of the Github server. It is not a big problem. We will leave it here and find a way to solve it later

4. The part to be optimized

Xiao Hei is too busy recently, so I simply realized the automatic deployment function first, but I haven’t had time to optimize it, so I left a pit first and then more

Caching dependencies speed up workflow

GitHub document – cache dependencies

2. COS optimized deployment

GitHub Actions + COS optimized deployment

Five, the reference

Due to xiao Hei’s shallow knowledge and limited level, there must be a lot of inadequacies in what he wrote.

The following documents, blog to the small black great help, in this express fried chicken thanks!

1. GitHub Actions document

2, How to deploy a create-react-app with github actions

3. Use GitHub Actions to automate blog deployment