Travis-ci SSH Deploy
We know that the continuous integration tools such as Travis-ci can help us to do unit tests after the code is submitted. Is there any way to automatically deploy the code through SSH to the traget machine? The answer is yes. Today, let me talk about my automatic deployment path with my own blog.
1. From manual deployment to automated deployment
During the code deployment, I experienced manually deploy
to the shell semi-automatic deploy
and now Travis
auto-deployment.
1.1 Stone Age - Manual Deployment
Very early on, I deployed the code completely manually:
In this process, I need to write and debug the code locally and then upload it to the Git server, then manually log in to the machine to download the latest code through git pull, and finally compile and restart the service on the server.
This primitive model is works, but it means that you need to do a series of works manually, and each deployment becomes extremely cumbersome.
1.2 Bronze Age - Shell semi-automatic deployment
Later, I thought of handing over the login machine, compiling, and deploying
to the shell for automatic execution. So I wrote a shell script. The main content is: after the local compilation is completed, the shell script automatically packages the code and uploads it to the server. Then deploy and restart the service.
After using the shell, the hands are greatly liberated. Every time you decide to go online, you only need to execute sh deploy.sh
and wait for the result. But using the shell also has its drawbacks: every time you go online, you have to manually execute the deployment command, and then wait for the code to be automatically packaged and uploaded and deployed. If you encounter network jitter or the packaged file is too large, there is a possibility of failure. You need to do it again. To say that it is automation, in fact, it still needs manual observation and intervention, so Mofei thinks, can there be a more efficient way to deploy? So we have the way of deployment now.
1.3 Modern - Travis Automated Deployment
By using the Travis, we can achieve the following effects:
- Test deployment: Every time you push the code to the
dev
branch, Travis will automatically perform unit tests, then automatically deploy the code to the corresponding development machine via SSH and restart the service to keep the latest version on the development machine. - Formal deployment: When you decide to go online, you can push the code to the
deploy
branch. Travis will automatically deploy the code to the official development environment.
Of course, this process can be adapted to your team to determine when to deploy.
2.Tune Travis
Stepping into the topic, to complete the automatic deployment, Travis must be able to monitor changes to Git, and then Travis needs to have permission to log in to our SSH server for deployment:
- Configure Travis to let Travis listen to a branch of Git.
- After a branch of Git is submitted, Travis can automatically compile it.
- Travis deploys the compiled product to the machine specified to us via SSH.
2.1 Initializing Travis
Before you start, if you don't already have a Travis account, use Github to log in to Traivs and link your project.
Travis configures the task through the .travis.yml
file in the project. First we need to create the .travis.yml
file in the root directory of the project. Let's take this configuration as an example.
Create a new .travis.yml
file and write the following code:
language: node_js
node_js:
- 8
The language
refers to the project running language, because this is the node.js project, so we use node_js
. If you are using other languages, you can refer to the official documentation. The next -8
refers to the v8 version of node.js. Of course you can also specify multiple versions to execute the code separately, such as:
node_js:
- stable
- '6'
- '4'
After adding the .travis.yml
file, the code will automatically build by Travis once you push the code to Git. If that passed, you can see a green tick after the corresponding commit. If it fails, it will be a red cross.
Because we won't introduce the unit test content this time, you can change the test script
in the script to exit 0
in the package.json
file to skip the unit test, but in the actual project, it is recommended that you take the test seriously.
"scripts": {
"test": "exit 0"
}
After the Travis configuration is complete, let's take a look at how to authorize Travis to access our servers.
2.2 Travis adds an SSH key
Usually we use the ssh command with the username and password to access the server, although in theory we can also write scripts such as ssh mofei@zhuwenlong.com -p abc
in the travis command, but if such code submitted to the public repo, there will have a high risk of leaking server passwords so we have to fix that.
The usual secret-free login is based on the SSH trust relationship, so if we can keep the key in encrypted form on the Travis server, that means only Travis can decode and log in to our server. Here we can use Travis' file encryption function to encrypt our keys.
In this process, our key is encrypted by Travis, and the decrypted key is stored in Travis, which means that only Travis can decrypt it. So we can boldly upload this encrypted file to github without worrying about other people stealing our keys.
Since we want to use Travis to encrypt files, the first thing is to install Travis locally.
2.2.1 Installing Travis locally
We can execute the following code to install Travis
sudo gem install travis
Then run the command to install Travis again sudo gem install travis
After installing Travis, we need to log in to Travis on the command line
travis login --pro
Entering your github account and password all the way is quickly completed.
2.2.2 Generating and Encrypting SSH Keys
Now we just need to generate an SSH key, then add a trust relationship, and save it with Travis encryption.
Execute the following script on the command line:
# Generates the key in the current directory
ssh-keygen -t rsa -b 4096 -C 'build@travis-ci.org' -f ./deploy_rsa
# Travis encryption
travis encrypt-file deploy_rsa --add
# Add trust
ssh-copy-id -i deploy_rsa.pub <ssh-user>@<deploy-host>
# Delete sensitive files
rm -f deploy_rsa deploy_rsa.pub
# Add changes to git
git add deploy_rsa.enc .travis.yml
Let's take a closer look at the code (if you understand all the commands, you can skip this paragraph):
- Generate a key in the current directory
ssh-keygen -t rsa -b 4096 -C 'build@travis-ci.org' -f ./deploy_rsa
First, we use the command to generate an ssh key in the current directory. After this code is executed, it will generate 2 files in the directory, the private key deploy_rsa
and the public key deploy_rsa.pub
.
- Use Travis encryption
travis encrypt-file deploy_rsa --add
Because Travis only needs to use the private key, we will encrypt the private key here. After this sentence is executed, you will see that the following code (--add
) is automatically added to the .travis.yml file. An encrypted file, deploy_rsa.enc
, is also found in the folder.
before_install:
- openssl aes-256-cbc -K $encrypted_137f45644142_key -iv $encrypted_137f45644142_iv
-in deploy_rsa.enc -out deploy_rsa -d
The code that is automatically added to these lines means that the command to unpack the deploy_rsa.enc
file is executed before install and placed in the deploy_rsa for use, where $encrypted_137f45644142_key
and $encrypted_137f45644142_iv
are the two variables that unlock the file, stored on Travis's server.
- Add trust relationship
ssh-copy-id -i deploy_rsa.pub <ssh-user>@<deploy-host>
This sentence means to add the public key to the target server (<ssh-user>@<deploy-host>
) where the user and host need to be replaced with the username and address of the server). After the addition is successful, all the public keys are used. The private key access server will be authenticated directly. In other words, if Travis keeps the private key, you can log in to our server through ssh
.
- Delete sensitive files and add edits to git
rm -f deploy_rsa deploy_rsa.pub
和git add deploy_rsa.enc .travis.yml
The private key deploy_rsa
and the public key deploy_rsa.pub
have completed their mission, we can remove it to avoid malicious use by others, and add the generated encrypted file deploy_rsa.enc
and the modified .travis.yml
to git.
2.3 Travis deployment script
Once everything is ready, we can modify the .travis.yml
file for travis to deploy.
First, we need to decrypt the private key and make it work before deployment, so we add the following code:
before_deploy:
- openssl aes-256-cbc -K $encrypted_137f45644142_key -iv $encrypted_137f45644142_iv
-in deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy_rsa
- ssh-add /tmp/deploy_rsa
before_deploy
field identifies the commands that Travis needs to execute before deployment. The first line decrypts the ssh file, and the next three lines make the ssh key take effect.
Then, we add the deploy
field, which is what the code executes when it runs the deployment:
deploy:
provider: script
script: bash ./deploy.sh
skip_cleanup: true
on:
branch: deploy
Here we specify the script
to run, the content of the run is bash ./deploy.sh
, the effective branch is the deploy
branch, as for ./deploy.sh
is our specific deployment code, such as the deployment code file of my blog. Is some shell script: first compile, then package the compiled file to the machine, then log on to the machine to put the file into the location, and finally restart the service, the specific code is not posted, you can click View the link above.
Finally, we need to add the host information of our deployment machine so that Travis can access the server normally:
addons:
ssh_known_hosts: 47.99.143.70
The IP here refers to the IP of the deployment server.
The final .travis.yml
as follows:
language: node_js
node_js:
- 8
addons:
ssh_known_hosts: 47.99.143.70
before_deploy:
- openssl aes-256-cbc -K $encrypted_137f45644142_key -iv $encrypted_137f45644142_iv
-in deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy_rsa
- ssh-add /tmp/deploy_rsa
deploy:
provider: script
script: bash ./deploy.sh
skip_cleanup: true
on:
branch: deploy
After doing this, every time you push the code to the deploy
branch Travis will automatically deploy. If you want to check the deployment progress, you can open the compile status icon in the commit page.