Deployer: Use of Gitlab CI environment variables

Created on 31 Mar 2016  路  7Comments  路  Source: deployphp/deployer

| Q | A |
| --- | --- |
| Issue Type | Question/Bug |
| Deployer Version | Deployer version 3.1.2 |
| Local Machine OS | Ubuntu 14.04.4 LTS x86_64 |
| Remote Machine OS | Ubuntu 14.04.4 LTS x86_64 |

Description

Here is our use-case, which I'm trying to implement. We have an GitLab CI server, with a build script configured to run tests and if none failed run deployer to deploy release to the server.

To not expose sensitive information to other developers (like SSH password), CI server is configured to export needed environment variables on build. The idea here is to have deployed pickup those exported variables and use them for SSH authentication.

The issue is that I can not configure deployer to pickup those variables. I have tried 2 methods:

  1. Set deployer env variable with a value from bash env variable, and then use them in server configuration:
env('ssh_production_username', function () {
    return runLocally('echo $DEPLOYER_PRODUCTION_USERNAME')->toString();
});

env('ssh_production_password', function () {
    return runLocally('echo $DEPLOYER_PRODUCTION_PASSWORD')->toString();
});
  1. Run runLocally directly in server configuration, as shown in below listing.

Neither of these 2 method worked for me.

Can you please review and let me know what I'm doing wrong. The goal in to read bash environment variable values and pass them to server configuration.

P.S. I have double checked with export command, and needed variables correctly exported by CI server.

Content of deploy.php

<?php

require 'deploy/recipes/laravel.php';

// Set configurations
set('repository', '...');

set('shared_files', ['.env']);

set('shared_dirs', [
    'storage/app',
    'storage/framework/cache',
    'storage/framework/sessions',
    'storage/framework/views',
    'storage/logs',
]);

set('writable_dirs', ['bootstrap/cache', 'storage', 'vendor']);

// configure servers
server('production', 'production.domain.com')
    ->user(runLocally('echo $DEPLOYER_PRODUCTION_USERNAME')->toString())
    ->password(runLocally('echo $DEPLOYER_PRODUCTION_PASSWORD')->toString())
    ->env('deploy_path', '/path/to/httpdocs');

// migrate database
task('database:migrate', function () {
    run('php {{release_path}}/' . 'artisan migrate --force');
})->desc('Migrate database');

// optimize application
task('deploy:optimize', function () {
    run('php {{release_path}}/' . 'artisan optimize');
    run('php {{release_path}}/' . 'artisan route:cache');
    run('php {{release_path}}/' . 'artisan config:cache');
})->desc('Optimize Application');

// restart php-fpm after deployment
task('php-fpm:restart', function () {
    run('sudo /usr/sbin/service plesk-php70-fpm restart');
})->desc('Restart PHP-FPM service');

// main deployment task
task('deploy', [
    'deploy:prepare',
    'deploy:release',
    'deploy:update_code',
    'deploy:vendors',
    'deploy:shared',
    'deploy:symlink',
    'database:migrate',
    'deploy:optimize',
    'cleanup',
    'php-fpm:restart',
])->desc('Deploy your project');

// report success after deployment successfully finished
after('deploy', 'success');

Output log

$ dep deploy production -vvv
PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'Key `` is invalid' in phar:///usr/local/bin/dep/src/Type/DotArray.php:59
Stack trace:
#0 phar:///usr/local/bin/dep/src/Type/DotArray.php(140): Deployer\Type\DotArray->explodeKey(NULL)
#1 phar:///usr/local/bin/dep/src/Server/Environment.php(149): Deployer\Type\DotArray->offsetSet(NULL, NULL)
#2 phar:///usr/local/bin/dep/src/functions.php(568): Deployer\Server\Environment::setDefault(NULL, NULL)
#3 phar:///usr/local/bin/dep/src/functions.php(316): env()
#4 /home/gitlab-runner/builds/8c992323/0/WeQubit/waremakers/deploy.php(22): runLocally('echo $DEPLOYER_...')
#5 phar:///usr/local/bin/dep/bin/dep(60): require('/home/gitlab-ru...')
#6 /usr/local/bin/dep(4): require('phar:///usr/loc...')
#7 {main}
  thrown in phar:///usr/local/bin/dep/src/Type/DotArray.php on line 59

ERROR: Build failed with: exit status 1

Most helpful comment

Hi, I also use gitlab CI with variables to deploy after tests, here's our deploy task in .gitlab-ci.yml:

Deploy:
  type: deploy
  only: [ "master" ]
  tags: [ "php5.6" ]
  script:
    - mkdir -p ~/.ssh
    - echo $DEPLOY_SERVERS_YML > app/config/servers.yml
    - echo $DEPLOY_PRIVATE_KEY > ~/.ssh/id_rsa
    - echo $DEPLOY_PUBLIC_KEY > ~/.ssh/id_rsa.pub
    - chmod 700 ~/.ssh
    - chmod 600 ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
    - composer install -n --prefer-dist --no-progress
    - php vendor/bin/dep deploy dev -v

Keys & server configuration are stored in gitlab CI variables.

In deploy.php we have serverList('app/config/servers.yml')

In $DEPLOY_SERVERS_YML we have something like

dev:
  host: host
  user: user
  identity_file: ~
  stage: dev
  deploy_path: /path

I hope it will help!

All 7 comments

Was able to reproduce this even with minimal configuration:

deploy.php:

<?php

localServer('localhost');

var_dump(runLocally('echo $FOO')->toString());

Then to test execute on terminal:

  1. Export test variable:
$ export FOO=bar
  1. Confirm variable is exported and available:
$ echo $FOO
bar
  1. Run deployer on local server:
$ dep local -vvv
PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'Key `` is invalid' in phar:///usr/local/bin/dep/src/Type/DotArray.php:59
Stack trace:
#0 phar:///usr/local/bin/dep/src/Type/DotArray.php(140): Deployer\Type\DotArray->explodeKey(NULL)
#1 phar:///usr/local/bin/dep/src/Server/Environment.php(149): Deployer\Type\DotArray->offsetSet(NULL, NULL)
#2 phar:///usr/local/bin/dep/src/functions.php(568): Deployer\Server\Environment::setDefault(NULL, NULL)
#3 phar:///usr/local/bin/dep/src/functions.php(316): env()
#4 /root/deployer-test/deploy.php(5): runLocally('echo $FOO')
#5 phar:///usr/local/bin/dep/bin/dep(60): require('/root/deployer-...')
#6 /usr/local/bin/dep(4): require('phar:///usr/loc...')
#7 {main}
  thrown in phar:///usr/local/bin/dep/src/Type/DotArray.php on line 59

You were run runLocally() without a task.
I think it will run ok if you edit your deploy.php to:

<?php
// deploy.php
localServer('localhost');

env('ssh_production_username', function () {
    return runLocally('echo $DEPLOYER_PRODUCTION_USERNAME')->toString();
});

task('foo', function(){
    echo env('ssh_production_username');
});

In your case, i think you should try using getenv() function.

Hi, I also use gitlab CI with variables to deploy after tests, here's our deploy task in .gitlab-ci.yml:

Deploy:
  type: deploy
  only: [ "master" ]
  tags: [ "php5.6" ]
  script:
    - mkdir -p ~/.ssh
    - echo $DEPLOY_SERVERS_YML > app/config/servers.yml
    - echo $DEPLOY_PRIVATE_KEY > ~/.ssh/id_rsa
    - echo $DEPLOY_PUBLIC_KEY > ~/.ssh/id_rsa.pub
    - chmod 700 ~/.ssh
    - chmod 600 ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
    - composer install -n --prefer-dist --no-progress
    - php vendor/bin/dep deploy dev -v

Keys & server configuration are stored in gitlab CI variables.

In deploy.php we have serverList('app/config/servers.yml')

In $DEPLOY_SERVERS_YML we have something like

dev:
  host: host
  user: user
  identity_file: ~
  stage: dev
  deploy_path: /path

I hope it will help!

Your solution is very clever @Baldinof !
In my case (we are using jenkins), I had to echo the DEPLOY_SERVERS_YML surrounded by quotes to preserve the YAML line breaks and indentation:
echo "$DEPLOY_SERVERS_YML" > ./servers.yml

I think, i can find some solution to this. What is best way to use env in deploy.php?

No env in v4. Only set/get. Closing.

I know this is old but I'm doing something similar and thought I'd share my solution.

in .gitlab-ci.yml:

deploy:
  stage: deploy
  when: on_success
  tags:
    - deploy
  environment: development
  variables:
    DEPLOY_PATH: /var/www/deployments/
    DEPLOY_SERVER: server.com
  script:
    - dep deploy -v

In deploy.php on the runner:

server(getenv('CI_ENVIRONMENT_NAME'), getenv('DEPLOY_SERVER'))
    ->user('username')
    ->identityFile()
    ->set('deploy_path', getenv('DEPLOY_PATH').'/'.getenv('CI_PROJECT_NAME'))
    ->pty(true);
Was this page helpful?
0 / 5 - 0 ratings