在AWS Ubuntu实例中为NodeJS部署设置GitLab CI

时间:2016-11-09 17:57:56

标签: node.js amazon-web-services ubuntu gitlab gitlab-ci

我有一个配置了GitLab CE的AWS Ubuntu实例。现在我想配置GitLab CI以在每次提交后部署我的NodeJS应用程序。我没有任何适当的逐步解决方案。

我的NodeJS应用程序在/var/www/mean/my-app http://myapp.mydomain.com上运行,主机由Apache Proxy处理,

<VirtualHost *:80>
    ServerAdmin anshad@mydomain.com
    ServerName gitlab.mydomain.com
    ServerAlias www.gitlab.mydomain.com

    ServerSignature Off

    ProxyPreserveHost On

    AllowEncodedSlashes NoDecode

    <Location />
       Require all granted
       ProxyPassReverse http://localhost:8080
       ProxyPassReverse http://gitlab.mydomain.com/
    </Location>

    RewriteEngine on

    RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f [OR]
    RewriteCond %{REQUEST_URI} ^/uploads/.*
    RewriteRule .* http://127.0.0.1:8080%{REQUEST_URI} [P,QSA,NE]

    DocumentRoot /home/git/gitlab/public

    LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common_forwarded
    ErrorLog /var/log/apache2/gitlab_error.log
    CustomLog /var/log/apache2/gitlab_forwarded.log common_forwarded
    CustomLog /var/log/apache2/gitlab_access.log combined env=!dontlog
    CustomLog /var/log/apache2/gitlab.log combined
 </VirtualHost>

该应用程序使用forever模块

进行自举
forever start app.js

gitlab配置检查sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production给出,

Checking GitLab Shell ...

GitLab Shell version >= 4.0.0 ? ... OK (4.0.0)
Repo base directory exists?
default... yes
Repo storage directories are symlinks?
default... no
Repo paths owned by git:git?
default... yes
Repo paths access is drwxrws---?
default... yes
hooks directories in repos are links: ... 
dev / my-app ... ok
Running /home/git/gitlab-shell/bin/check
Check GitLab API access: OK
Access to /home/git/.ssh/authorized_keys: OK
Send ping to redis server: OK
gitlab-shell self-check successful

Checking GitLab Shell ... Finished

Checking Sidekiq ...

Running? ... yes
Number of Sidekiq processes ... 1

Checking Sidekiq ... Finished

Checking Reply by email ...

Reply by email is disabled in config/gitlab.yml

Checking Reply by email ... Finished

Checking LDAP ...

LDAP is disabled in config/gitlab.yml

Checking LDAP ... Finished

Checking GitLab ...

Git configured with autocrlf=input? ... yes
Database config exists? ... yes
All migrations up? ... yes
Database contains orphaned GroupMembers? ... no
GitLab config exists? ... yes
GitLab config outdated? ... no
Log directory writable? ... yes
Tmp directory writable? ... yes
Uploads directory setup correctly? ... yes
Init script exists? ... yes
Init script up-to-date? ... yes
projects have namespace: ... 
dev / my-app ... yes
Redis version >= 2.8.0? ... yes
Ruby version >= 2.1.0 ? ... yes (2.3.1)
Your git bin path is "/usr/bin/git"
Git version >= 2.7.3 ? ... yes (2.7.4)
Active users: 1

Checking GitLab ... Finished

我以前使用系统中的SSH登录实例,

ssh -i API-Key.pem ubuntu@ec2-XX-XX-XXX-XXX.ap-south-1.compute.amazonaws.com

使用命令

创建密钥
ssh-keygen -t rsa

/etc/gitlab-runner/config.toml

上的亚军配置
concurrent = 1
check_interval = 0

[[runners]]
  name = "Production Runner"
  url = "http://gitlab.mydomain.com/ci"
  token = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
  executor = "ssh"
  [runners.ssh]
    user = "ubuntu"
    host = "ip-XXX-XX-XX-XXX"
    identity_file = "/home/ubuntu/.ssh/id_rsa"
  [runners.cache]

.gitlab-ci.yml上的代码

test_async:   
 script:    
  - npm install

由于配置错误,跑步者会出错,

Running with gitlab-ci-multi-runner 1.7.1 (f896af7)
Using SSH executor...
ERROR: Preparation failed: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
Will be retried in 3s ...

我的困惑是:

将{1}}文件的内容用于将已提交的代码部署到应用程序位置应该是什么?

如何为此配置跑步者?如果我必须使用.gitlab-ci.yml跑步者,那里的配置应该是什么?

更新

ssh文件提供为.pem后,收到以下错误

identity_file

现在有一个问题,git克隆的http不能正常工作,但ssh克隆工作正常。

注意: gitlab和构建环境都是相同的主机(相同的aws实例)

GitLab中也报告了

Bug(http克隆问题)。

1 个答案:

答案 0 :(得分:4)

在/etc/gitlab-runner/config.toml

concurrent = 1
check_interval = 0

[[runners]]
  name = "Production Runner"
  url = "http://gitlab.mydomain.com/ci"
  token = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
  executor = "ssh"
  [runners.ssh]
    user = "ubuntu"
    host = "ip-XXX-XX-XX-XXX"
    identity_file = "/home/ubuntu/.ssh/id_rsa"
  [runners.cache]

您定义

  • 宿主
  • 用户
  • 和身份文件

主机应该是您的构建主机IP(换句话说,您将在哪里执行您的构建)
用户应该是构建主机的用户。 不在gitlab主机上

您可以通过

测试您的密码减去ssh的工作方式
  1. 以root身份登录gitlab主机
  2. ssh -i /home/ubuntu/.ssh/id_rsa ubuntu @ ip-XXX-XX-XX-XXX
  3. 如果有效并且没有要求您输入密码 - 一切都很好 如果中断 - 意味着您没有正确设置密码。

    设置基于密码的公钥的最简单方法是使用名为

    的命令
    ssh-copy-id
    

    例如,我想在我的gitlab和我的构建主机之间设置密码少ssh auth 我的构建主机IP是192.168.0.42,主机名是build.home
    我已经在gitlab主机上的/home/ubuntu/.ssh下生成了我的id_rsa和id_rsa.pub。

    现在让我们将我们的公钥从gitlab主机推送到我们的构建主机。第一次它会要求您输入密码。

    [root@gitlab ~]# ssh-copy-id -i /home/ubuntu/.ssh/id_rsa.pub ubuntu@build.home
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    ubuntu@build.home's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'ubuntu@build.home'"
    and check to make sure that only the key(s) you wanted were added.  
    

    请注意,在上面的示例中,我将公钥推送到远程主机。

    但是当我现在要连接到这个远程主机时 - 我将指定我的私钥。

    [root@gitlab ~]# ssh -i /home/ubuntu/.ssh/id_rsa ubuntu@build.home
    [ubuntu@build ~]$ hostname
    build.home
    

    尝试在gitlab主机和远程主机之间测试您的公钥验证并更新您的问题。

    资源:

    编辑1:

    这是我的配置 我的gitlab主机名为gitlab.home 192.168.0.41
    我有另一个名为sshbuild.home的虚拟机192.168.0.43

    以下是我添加ssh runner的方式

    步骤1.在我的gitlab.home上安装 yum install gitlab-ci-multi-runner并将我的远程sshbuild.home VM注册为ssh runner

    enter image description here

    enter image description here

    我还需要确保密码少auth在我的gitlab.home和sshbuild.home之间有效,所以

    [root@gitlab gitlab-runner]# ssh-copy-id 192.168.0.43
    The authenticity of host '192.168.0.43 (192.168.0.43)' can't be established.
    ECDSA key fingerprint is b4:6a:1b:72:d1:7d:1f:34:f7:bb:ef:ad:69:42:11:13.
    Are you sure you want to continue connecting (yes/no)? yes
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    root@192.168.0.43's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh '192.168.0.43'"
    and check to make sure that only the key(s) you wanted were added.
    
    [root@gitlab gitlab-runner]# ssh 192.168.0.43
    Last login: Fri Nov 18 17:05:06 2016 from 192.168.0.101
    [root@sshbuild ~]# exit
    

    然后我禁用了我的其他跑步者(shell跑步者)并制作了新的SSH跑步者项目,以确保在我提交时 - 它将在ssh跑者身上执行

    enter image description here

    我确实承诺并且瞧 - 我们在sshbuild.home主机上运行了我们的成功测试

    enter image description here

    以下是一些可能有助于更好地理解此主题的链接

    P.S:这是我的/etc/gitlab-runner/config.toml文件

    [root@gitlab gitlab-runner]# cat /etc/gitlab-runner/config.toml 
    concurrent = 1
    check_interval = 0
    
    [[runners]]
      name = "sshbuild"
      url = "http://gitlab.home/"
      token = "2bc1825d8fbde09fd632637c60e9e7"
      executor = "ssh"
      [runners.ssh]
        user = "root"
        host = "192.168.0.43"
        port = "22"
        identity_file = "/root/.ssh/id_rsa"
      [runners.cache]
    

    P.S:如果我在网络界面的“设置”下为我的仓库禁用HTTP,我会遇到类似的错误。但错误不是500而是403.

    enter image description here

    编辑2:

    现在我将基于一个简单的HelloWorld项目来介绍.gitlab-ci.yml 在我的HelloWorld中,我有一个名为server.js的文件,当从节点运行时,它将简单地创建在端口3000上运行的Web服务器,并将回复&#34; Hello World&#34;关于GET请求。

     1  const http = require('http');
     2  
     3  const hostname = '0.0.0.0';
     4  const port = 3000;
     5  
     6  const server = http.createServer((req, res) => {
     7    res.statusCode = 200;
     8    res.setHeader('Content-Type', 'text/plain');
     9    res.end('Hello World!\n');
    10  });
    11  
    12  server.listen(port, hostname, () => {
    13    console.log(`Server running at http://${hostname}:${port}/`);
    14  });
    

    我的目标是能够针对它运行测试用例。在这种情况下,我将运行简单的

    curl localhost:3000 | grep "Hello World" 
    

    但是我需要把它放到一个单独的脚本中,成功时退出状态为0,失败时退出非零

    cat -n simpletest.sh 
         1  #!/bin/bash
         2  
         3  cleanup () 
         4  {
         5   count=`netstat -anp|grep ":3000"|grep LISTEN|awk '{print $NF}'|cut -d\/ -f1|wc -l`
         6   if [ $count -ne 0 ]
         7    then 
         8     pid=`netstat -anp|grep ":3000"|grep LISTEN|awk '{print $NF}'|cut -d\/ -f1`; 
         9     echo "Need to kill PID $pid"; 
        10     kill $pid
        11   fi
        12  }
        13  
        14  echo "Running simple test"
        15  curl localhost:3000|grep "Hello World"
        16  if [ $? -eq 0 ]
        17   then
        18    echo "Test was successfull"
        19    echo "Clean up node.js process"
        20    cleanup
        21    exit 0
        22   else
        23    echo "Test failed"
        24    echo "Clean up node.js process"
        25    cleanup
        26    exit 1
        27  fi
    

    现在让我们覆盖我的.gitlab-ci.yml

    cat -n .gitlab-ci.yml
         1  test:
         2  
         3    before_script:
         4    - echo "Before script"
         5    - hostname
         6    - /bin/bash cleanup.sh
         7  
         8    script: 
         9    - echo "Main Script"
        10    - node server.js &
        11    - sleep 3
        12    - /bin/bash simpletest.sh
    

    我有一个名为test的作业。
    在before_script中,它运行了cleanup.sh脚本,它只是在发现的情况下杀死了端口3000上的PID监听。

    cat -n cleanup.sh 
         1  #!/bin/bash
         2  count=`netstat -anp|grep ":3000"|grep LISTEN|awk '{print $NF}'|cut -d\/ -f1|wc -l`
         3  if [ $count -ne 0 ]
         4   then 
         5    pid=`netstat -anp|grep ":3000"|grep LISTEN|awk '{print $NF}'|cut -d\/ -f1`; 
         6    echo "Need to kill PID $pid"; 
         7    kill $pid
         8  fi
         9  exit 0
    

    在脚本下:它用我的server.js运行节点,给它3秒钟启动,然后对它运行测试。
    这个测试也将在测试完成后处理节点PID。

    因此,让我们提交并检查构建的状态

    enter image description here

    现在让我们改变我们的server.js输出不是&#34; Hello World&#34;但是&#34; HelloWorld&#34;,所以两者之间没有空间。我希望我的测试用例会失败,因为它确实需要#34; Hello World&#34;。它确实失败了。

    enter image description here

    这是我能提出的最简单的CI用例 现在,如果基于测试用例的状态,您希望将代码部署到另一个环境 - 您将不得不开始使用

    • 阶段 和
    • 环境

    所以你的.gitlab-ci.yml会变成这样的东西(实际工作的例子)

    cat -n .gitlab-ci.yml
         1  stages:
         2  - test
         3  - deploy
         4  
         5  run_test_case:
         6   stage: test
         7   before_script:
         8   - echo "Before script"
         9   - hostname
        10   - /bin/bash cleanup.sh
        11  
        12   script: 
        13   - echo "Main Script"
        14   - node server.js &
        15   - sleep 3
        16   - /bin/bash simpletest.sh
        17  
        18  deploy_to_production:
        19   stage: deploy
        20   script: 
        21   - echo "Run code here to do production deployment"
        22   environment:
        23    name: production
    

    在git push上会成功。
    在第21行,我只是运行echo,但这可以用脚本替换,该脚本将推送到远程登台或生产环境。

    enter image description here

    enter image description here