0

I have created CI (Continuous Integration) between GitLab, Docker and AWS with the following configuration:

Dockerfile.

# install node.js
FROM node:latest

# create necessary directories and
# permissions
RUN mkdir -p /home/node/{project_name}/node_modules && chown -R node.node /home/node/{project_name}

# copy package.json files in directory
# check and switch to node user.
USER node

# copy project files.
COPY . /home/node/{project_name}

# switch to working directory
WORKDIR /home/node/{project_name}

docker-compose.yml

version: '3'
services:
  server:
    container_name: truckpeserver
    restart: always
    build: .
    command: 'npm run dev'
    links:
      - redis
      - prisma
    env_file:
      - ./.env
    volumes:
      - .:/home/node/truckpeserver/
    working_dir: /home/node/truckpeserver/
    ports:
      - '3000:3000'
  redis:
    container_name: "redisserver"
    image: redis:latest
    restart: always
    command: ["redis-server", "--bind", "redis", "--port", "6379"]
  prisma:
    image: prismagraphql/prisma:1.34
    restart: always
    ports:
      - '4466:4466'
    environment:
      PRISMA_CONFIG: |
        port: 4466
        databases:
          default:
            connector: mysql
            host: mysql
            port: 3306
            user: root
            password: prisma
  mysql:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: prisma
    volumes:
      - mysql:/var/lib/mysql
volumes:
  mysql: ~

gitlab-ci.yml

# Node docker image on which this would be run
image: node:10.15.3

#This command is run before actual stages start running
before_script:
  - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
  - 'apt-get update && apt-get upgrade -y && apt-get install git -y'

stages:
  - test
  - deploy

# lint and test are two different jobs in the same stage.
# This allows us to run these two in parallel and making build faster

# Job 1:
deployToAWS:
  only:
    - master
  stage: deploy
  script:
    - bash ./deploy.sh

deploy.sh

#!/bin/bash

# any future command that fails will exit the script
set -e

# Lets write the public key of our aws instance
eval $(ssh-agent -s)
echo "$PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null

# ** Alternative approach
# echo -e "$PRIVATE_KEY" > /root/.ssh/id_rsa
# chmod 600 /root/.ssh/id_rsa
# ** End of alternative approach

# disable the host key checking.
chmod 755 ./disableHostKeyChecking.sh
./disableHostKeyChecking.sh

# we have already setup the DEPLOY_SERVE R in our gitlab settings which is a
# comma seperated values of ip addresses.
DEPLOY_SERVERS=$DEPLOY_SERVERS

# lets split this string and convert this into array
# In UNIX, we can use this commond to do this
# ${string//substring/replacement}
# our substring is "," and we replace it with nothing.
ALL_SERVERS=(${DEPLOY_SERVERS//,/ })
echo "ALL_SERVERS ${ALL_SERVERS}"

# Lets iterate over this array and ssh into each EC2 instance
# Once inside the server, run updateAndRestart.sh
for server in "${ALL_SERVERS[@]}"
do
  echo "deploying to ${server}"
  ssh ubuntu@${server} 'bash' < ./production.sh
done

Production.sh

#!/bin/bash

# exist script any error occur
set -e

if [ -d "./truckpeserver" ]

# if directory exists than kill old
# containers
then
  # move to server directory.
  cd ./truckpeserver

  # down all services.
  docker-compose down

  # get out of directory and remove directory
  cd .. && rm -rf ./truckpeserver

fi

# pull truckpeserver
git clone git@gitlab.com:rootandleaves/truckpeserver.git

# move to server directory.
cd ./truckpeserver

# install node_modules.
yarn

# build and up all containers.
docker-compose build && docker-compose up

with its production.sh which deploys the application to AWS over SSH. The problem now is that publishing the app on git causes the runner to run the CI task which will SSH to the AWS server and start executing the app installation (cloning, yarn etc) process. But how can I tell GitLab runner to exit from SSH on successfully running application?

  • 4
    Maybe post the bash script which is likely more relevant than the Dockerfile. – xenoid Dec 23 '19 at 9:13
  • Please explain what you mean by "exit silently". Are you talking about the return code? – Panki Dec 23 '19 at 9:28
  • @panki means keep my running application and exit from SSH and let deployment CI Runner mark task as completed... – Nitesh Yadav Dec 23 '19 at 11:16
0

My guess is - you're not running the app on background and the script keeps waiting while the app is running.

You'll have to replace something like:

yarn run start
# this line only executes after yarn _exits_

with

nohup yarn run start &
# this line executes as soon as yarn _starts_

Note the & at the end of the line which runs the command as a background process and immediately continues with the next line.


UPDATE: As per the OP comment he uses docker-compose. You can run the containers in detached mode with --detach which means that docker-compose up --detach will not wait for them to exit.

Try this:

docker-compose up --detach

Hope that helps :)

  • well it execute docker-compose up instead running yarn directly – Nitesh Yadav Dec 23 '19 at 11:17
  • @NiteshYadav updated my answer – MLu Dec 25 '19 at 21:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.