Wednesday, October 27, 2021

[SOLVED] Gitlab-ci configure docker runner for deployment with SSH keys

Issue

I'm trying to use gitlab-ci and capistrano to deploy my symfony application. But I can't deploy using SSH by injecting keys into docker, the script keeps prompting for password when connecting. I'm using a local instance of gitlab.

In gitlab's SSH_PRIVATE_KEY private variable, I added the git user's private key, and in SSH_SERVER_HOSTKEYS, the ssh-keyscan -H 192.168.0.226 command's result.
In file authorized_keys from deploy's .ssh folder, I put the git user's public key.

Here are the configurations files:

gitlab-ci.yml:

image: php:7.1

cache:
  paths:
  - vendor/

before_script:
# Install dependencies
- bash ci/docker_install.sh > /dev/null
- bash ci/ssh_inject.sh

stages:
  - deploy

deploy:
  stage: deploy
  script:
  - apt-get install ruby-full -yqq
  - gem install capistrano -v 3.8.0
  - gem install capistrano-symfony
  - cap production deploy
  environment:
    name: production
    url: http://website.com
  only:
  - master

ssh_inject.sh: link

#!/bin/bash

set -xe

# Install ssh-agent if not already installed, it is required by Docker.
# (change apt-get to yum if you use a CentOS-based image)
which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )

# Run ssh-agent (inside the build environment)
eval $(ssh-agent -s)

# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
ssh-add <(echo "$SSH_PRIVATE_KEY")

mkdir -p ~/.ssh
[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts

deploy.rb:

# config valid only for current version of Capistrano
lock '3.8.0'

set :application, 'symfony'
set :repo_url, '[email protected]:symfony.git'

# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, '/home/symfony'

set :symfony_env,  "prod"

set :composer_install_flags, '--no-dev --prefer-dist --no-interaction --optimize-autoloader'

set :symfony_directory_structure, 3
set :sensio_distribution_version, 5

# symfony-standard edition directories
set :app_path, "app"
set :web_path, "web"
set :var_path, "var"
set :bin_path, "bin"

set :app_config_path, "app/config"
set :log_path, "var/logs"
set :cache_path, "var/cache"

set :symfony_console_path, "bin/console"
set :symfony_console_flags, "--no-debug"

# asset management
set :assets_install_path, "web"
set :assets_install_flags,  '--symlink'

# Share files/directories between releases
set :linked_files, %w(app/config/parameters.yml)
set :linked_dirs, %w(web/uploads)

# Set correct permissions between releases, this is turned off by default
set :permission_method, false
set :file_permissions_paths, ["var/logs", "var/cache"]
set :file_permissions_users, ["apache"]

before "deploy:updated", "deploy:set_permissions:acl"
after "deploy:updated", "symfony:assetic:dump"

and production.rb:

server '192.168.0.226', user: 'deploy', roles: %w{app db web}

What could be wrong? I tried to set forward_agent to true but it's not working eather.

If I build the docker container manually and install all dependencies, the ssh connexion can be established without asking for password...

Here is the error: password error

EDIT:

Is there something to add in the runner configuration ? Here it is:

concurrent = 1
check_interval = 0

[[runners]]
  name = "Docker runner"
  url = "http://gitlab.local/ci"
  token = "mytoken"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "php:7.1"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
  [runners.cache]

Solution

Solved by moving ssh_inject.sh content into gitlab-ci.yml.

If anyone has an idea about why it needs to be in gitlab-ci.yml, I'd like to understand.



Answered By - thomas-hiron