Issue
I am learning gitlab ci/cd and my ci assignment has this script in it:
ssh $REMOTE_SERVER_ADDRESS '(docker stop $(docker ps -q -f ancestor=$CI_PROJECT_NAME))) && echo CONTAINER $CI_PROJECT_NAME STOPPED || echo $CI_PROJECT_NAME NOT FOUND'
To clarify.
I haven't found how gitlab can connect to ssh without terminating the session, so I have to make connections time after time and execute commands.
$VARIABLE - gitlab environment variables.
I need to pass an environment variable in the arguments to the remote command.
ssh $REMOTE_SERVER_ADDRESS ' ....... '
- if I use single quotes, I'm running the command remotely and I don't have access to environment variables, except for one option I found, but more on that later.
ssh $REMOTE_SERVER_ADDRESS " ....... "
- if you use double quotes, the command is executed locally and variables are picked up.
After googling the problem, I found the only solution in different variations that somehow works:
ssh [email protected] test=docker-ci-cd 'printenv test'
- I get my variable
ssh [email protected] test=docker-ci-cd 'echo $test'
- I get empty output
I tried passing in arguments like this, but it didn't work:
ssh [email protected] test=docker-ci-cd 'docker ps -f ancestor=$(printenv test)'
How do I pass the value of this environment variable into the remote command arguments? - If it is even created on the remote server, I'm not sure yet, but the env output suggests that
Solution
To pass an environment variable to a remote command in SSH, you need to make sure the variable is expanded on the local machine before the command is sent to the remote server. That can be achieved by using double quotes instead of single quotes, as double quotes allow variable expansion.
Local Machine (GitLab CI Runner) Remote Machine (SSH Server)
----------------------------- --------------------------
| | | |
| $CI_PROJECT_NAME variable | -- SSH Command -> | Execute Docker Command |
| (e.g., your Docker image) | | |
| | | |
----------------------------- --------------------------
Your original command should be modified to use double quotes for the SSH command so that $CI_PROJECT_NAME
is expanded before the command is sent to the remote server.
ssh $REMOTE_SERVER_ADDRESS "docker stop \$(docker ps -q -f ancestor=$CI_PROJECT_NAME) && echo CONTAINER $CI_PROJECT_NAME STOPPED || echo $CI_PROJECT_NAME NOT FOUND"
Escape the $
in $(docker ps -q -f ancestor=$CI_PROJECT_NAME)
with a backslash (\
) to prevent it from being expanded on the local machine. That way, docker ps
command runs remotely.
Answered By - VonC Answer Checked By - Mary Flores (WPSolving Volunteer)