GIANTCRAB / gitlabby-dockerish-laravel

What happens when you Dockerize your Laravel testing environment and throw it at Gitlab CI?
MIT License
33 stars 12 forks source link

How to deploy laravel after succesfull test? #1

Closed gandra closed 7 years ago

gandra commented 7 years ago

Hi! Thanks for this. Very helpfull. I have found this repo after HOW TO: LARAVEL TESTING ON GITLAB CI WITH DOCKER

I have managed to succesfully run test build on Gitlab CI using Gitlab Runner on digitaocean. Now I am wondering if it is possible to do deplyment after test has been executed.

This is my deploy process on my staging env:

cd MY_PROJECT_ROOT_DIR
git reset --hard HEAD
git checkout master
git pull
composer install
composer update
php artisan migrate
php artisan db:seed

How I can manage to include this deploy after test is done?

GIANTCRAB commented 7 years ago

Hello, thank you for filing this issue.

Currently, the GitLab config file is written in a way which isn't very staging or deployment friendly. I'll work on it and include 'jobs' section.

To answer your question, it is possible. You can add a script to do a git push to your DigitalOcean after build is complete. Here's a quick theoretical example:

# This usually how you push code from your computer to GitLab
git push origin master
# By setting up a new REMOTE as your Digital Ocean droplet, you will be able to do this
git push staging HEAD:master
GIANTCRAB commented 7 years ago

Hi, I've made a new branch for this -- https://github.com/GIANTCRAB/gitlabby-dockerish-laravel/tree/5.3-develop

I'll test this when I get home, meanwhile, feel free to test this branch and let me know if it works for you. Thank you.

gandra commented 7 years ago

Thank you. I will try it.

gandra commented 7 years ago

I do not get how to setup .gitlab-staging-deploy.sh: git push "$GIT_DEPLOYMENT_REMOTE" HEAD:"$GIT_DEPLOYMENT_BRANCH" What are example values of those vars?

GIANTCRAB commented 7 years ago

Hmmm, I noticed that your CD pipe is a "pull" and not a "push". The one that was included is a "push" config which requires the staging server to also be a Git server and act as a remote.

I'll write another one for "pull" style and let you know again. Thank you!

GIANTCRAB commented 7 years ago

I have made a new commit to help integrate and solve the issue you have. ea2a8f2ebbba59b8cb8b82ded7d23c7a31ed4623

For this pull configuration, the variables for GIT_DEPLOYMENT_REMOTE GIT_DEPLOYMENT_BRANCH are the GitLab repository information.

Let me know if you have any other questions. Thank you! :)

gandra commented 7 years ago

Thank you! I will check it and give you feedback.

But at the moment I am stucked with another problem. I have to create one database in dockerish env. I have tried to execute following command inside .gitlab-ci.sh: mysql -u root -psecret -e "create database external-db-mock";

but this fails on GitLab CI with following error:

mysql: command not found

Here is last few lines from CI console:

The compiled services file has been removed. '.env.gitlab-testing' -> '.env' Application key [base64:9pCDG7QfjgEcynEnbauiP/GgDMXgntb+7wedcPN5OB4=] set successfully. Generating optimized class loader The compiled services file has been removed. Configuration cache cleared! .gitlab-ci.sh: line 31: mysql: command not found ERROR: Build failed: exit code 1

Any idea how to access mysql from .gitlab-ci.sh or how to create additional mysql databases in this environment to assure having those db before migrations run?

GIANTCRAB commented 7 years ago

The Docker image provided is minimal and does not contain mysql. Hence, you would need to do it through PHP. Create a PHP file with the following code (edit as needed) and then execute it through the command line:

$hostname = '';
$root = '';
$root_password = '';

$db = '';
$username = '';

$dbh = new PDO("mysql:host=$hostname", $root, $root_password);
$dbh->exec("CREATE DATABASE `$db`; CREATE USER '$username'@'localhost' IDENTIFIED BY '$password'; GRANT ALL ON `$db`.* TO '$username'@'localhost'; FLUSH PRIVILEGES;") or exit(var_dump($dbh->errorInfo()));

If you would want to do it through Laravel, it is also possible -- https://laravel.io/forum/09-13-2014-create-new-database-and-tables-on-the-fly

gandra commented 7 years ago

Thanks man!!!! Fixed via laravel! Now can return to try to do deployment. :)

gandra commented 7 years ago

I have tried deployment but build fails .. not sure why: https://www.diigo.com/file/image/sspsorrzdqbdaqeqqzcqoobsqa/build_job+%28%2310336317%29+%C2%B7+Jobs+%C2%B7+kibernum-dnc+%2F+kibernum-dnc-api+%C2%B7+GitLab.jpg

here is my .gitlab-ci.yml gist

NOTE: This problem is fixed thanks to https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_5081166

In short - you have to copy your entire private key into variable.

gandra commented 7 years ago

New problem ... previous one fixed now some problem related to access to my sql. Build pipeline fails: https://www.diigo.com/file/image/sspsorrzdqbdbcseqzcqoocboo/build_job+%28%2310337323%29+%C2%B7+Jobs+%C2%B7+kibernum-dnc+%2F+kibernum-dnc-api+%C2%B7+GitLab.jpg

Where is physical location of code which executes? How IP 172.17.0.3 appears there? Who put this IP?

Maybe the problem is in the context:

Is this build code executing inside Docker on GitlabCI or DROPLET_1 or DROPLET_2?

NOTE:

This problem is fixed. Here is info for others who find themselfes in the same situation. First build is executing inside dokcker in Gitlab CI, in the cloud far from our deploy target. So, MYSQL_ROOT_PASSWORD inside file .gitlab-ci.yml is the same password used for mysql inside dokcer - check .env.gitlab-testing(secret). With this info you will have build process pass.

gandra commented 7 years ago

Now my test pipeline fails with Could not open input file: vendor/bin/phpunit ... here is more context info: https://www.diigo.com/item/t/70W%2BwFLoMp9QT2fhC25u8PZnqxTnw0XNSg0Z3J26dMOKNUQ3CZ%2FQikee0DB1%0AQJRx%0A

Seems that phpunit is not installed on test? Why on this file file https://gitlab.com/kibernum-dnc/kibernum-dnc-api/blob/master/.gitlab-ci.yml you have on the line 8: phpunit:php-laravel-env:mysql:phpunit:php-laravel-env:mysql:?

NOTE: This problem is fixed. I have noticed that test pipeline fails with Could not open input file: vendor/bin/phpunit .. so no phpunit. Then I have copied entire .gitlab-ci.sh content inside .gitlab-test.sh before line php vendor/bin/phpunit --colors. In a such way I have assured that in test I have also phpunit so my fional .gitlab-test.sh which pass is:

#!/bin/bash
# Ensure we fail fast if there is a problem.
set -eo pipefail

# Move the files over to current directory
mv /root/composer.phar .
mv /root/composer.lock .
mv /root/vendor .

# Ensure that php is working
php -v

# Ensure that mysql server is up and running
ping -c 3 mysql

# Update packages
apt-get update -y

# Update project dependencies.
php composer.phar update

# Copy over testing configuration. This configuration is used for Gitlab CI unit testing
cp -v .env.gitlab-testing .env

# Generate an application key. Clear config and cache route
php artisan key:generate
php artisan optimize
php artisan config:clear

# https://laracasts.com/discuss/channels/laravel/why-unable-to-prepare-route-for-serialization-uses-closure
# php artisan route:cache

# Run database migrations and seed the data
php artisan migrate --seed

# Run unit testing with PHPUnit
php vendor/bin/phpunit --colors

@GIANTCRAB , what do you think about that?

Also I have changed first line in .gitlab-ci.yml to use laravel 5.4: image: woohuiren/php-laravel-env:5.4

Now test pipeline pass! Great! Finally going to deploymen pipeline :)

gandra commented 7 years ago

Now deploy fails with

Permission denied (publickey,password)

:(

Here is info: https://www.diigo.com/file/image/sspsorrzdqbddpardzcqoocpbd/stage_job+%28%2310339576%29+%C2%B7+Jobs+%C2%B7+kibernum-dnc+%2F+kibernum-dnc-api+%C2%B7+GitLab.jpg

@GIANTCRAB, inside .gitlab-ci.yml SSH_PRIVATE_KEY is the value of my private ssh key? Can you give me some info about this:

I have generated this key with following command: ssh-keygen -t rsa -b 4096 -C "your_email@example.com" on my laptop and copied content of the generated public key in digitalocean droplet where deployment should be done inside ~/.ssh/authorized_keys

NOTE: Deploy problem fixed. Problem is related with ssh key. Didn't understand why @GIANTCRAB approach didn't work. Here is my fix:

  1. I have added following 2 lines of code AT THE END of the file .gitlab-key-inject.sh:
    echo "$SSH_PRIVATE_KEY" > ~/.ssh/digocean_private_key
    chmod 400 ~/.ssh/digocean_private_key
  2. I have changed .gitlab-staging-pull-deploy.sh part for ssh from: ssh "$STAGING_SERVER_HOSTNAME" to ssh "$STAGING_SERVER_HOSTNAME" -i ~/.ssh/digocean_private_key`

and that's it! :)

GIANTCRAB commented 7 years ago

Hi, thanks for testing and giving information. (I was asleep at the time of which you posted the comments)

Seems that phpunit is not installed on test?

That is very weird since the build stage runs before test. I'll look into this. Your current method works but it would mean that you would be running twice the actions of a build process.

Deploy problem fixed. Problem is related with ssh key. Didn't understand why @GIANTCRAB approach didn't work. Here is my fix:

That is a very odd issue indeed. Thank you, I'll incorporate these fixes!

gandra commented 7 years ago

Hey man, thank you for this branch and this great work!!!!

I think you caan slose issue or I should?

GIANTCRAB commented 7 years ago

I have fixed the test stage issue. It seems like files are not automatically saved over to the other job by default. A new commit has been made to add the use of artifacts and dependencies -- 1364f03a0fcf4f6a817d28aeeeb99c2e8c608fc1

I've tested the new one and it works fine for me. Thank you and have a great day ahead.