angular-fullstack / generator-angular-fullstack

Yeoman generator for an Angular app with an Express server
https://awk34.gitbook.io/generator-angular-fullstack
6.12k stars 1.24k forks source link

Amazon deployment #501

Open nschurmann opened 10 years ago

nschurmann commented 10 years ago

Is there a plan to build a command line that deploys and rollbacks to amazon web services?, that would be super useful.

JaKXz commented 10 years ago

I would find this useful too. @nschurmann would you happen to have an implementation you could put into a PR?

nschurmann commented 10 years ago

@JaKXz i don't have an implementation, actually i'm trying to deploy the app into a debian server without any success.

remicastaing commented 10 years ago

Have you take a look at this: https://github.com/bevacqua/grunt-ec2?

nschurmann commented 10 years ago

@remicastaing looks good, my only doubt is that this lib uses pm2 to keep it running, how you should put this together?

remicastaing commented 10 years ago

Absolutely no idea! I just googled it to find if someone else already wrote something to deploy apps with grunt on ec2.

nschurmann commented 10 years ago

@JaKXz for now my deployment strategy is mainly using git. Just code as you always do and when you need to deploy go into de server, do a pull to a specific commit (the production branch) and then start testing, if something goes wrong then you can make a rollback to a specific commit that used to work.

nschurmann commented 10 years ago

Of course this is the manual process, an automated process should be a script or command line tool that logins to your amazon ec2 instance, navigate to the folder, make a backup, pull latest changes.

And also receive a command that can make a rollback (get into server, navigate to folder, put back the backup).

nschurmann commented 10 years ago

I was missing the command that kept the application, after some time googling i found that this:

nohup grunt serve:dist --force &

works quite well. The --force param is needed because there is no desktop environment (because is a server) and prevents from failing at the very end. nohup is for no hangup and the & is for running in background.

If you still don't recover the control of the command line just press enter, it should do the trick.

thomporter commented 10 years ago

I haven no ec2/node experience (yet,) but this article describes a method using forever, which is a nice node module for keeping your app alive. There is another one here and more by googling "ec2 node forever"

nschurmann commented 10 years ago

@thomporter you know how to use this with servers launched with grunt?

thomporter commented 10 years ago

You won't launch the server with grunt this way. You should only be using grunt to launch your server for development. In production, grunt will just get in the way..

But, I believe this is the core command you'd need:

cd /path/to/server/folder/ && forever start app.js 

Let me know if that helps. If not, I might try setting up an ec2 instance myself and see if I can't get the demo project running on it.

P.S You'll need to install forever globally first: npm install -g forever

thomporter commented 10 years ago

I was able to get our demo app running on an ec2 instance will fairly little hassle...

http://ec2-54-68-53-8.us-west-2.compute.amazonaws.com:8080/

I used the Ubuntu ec2 instance. Once in, I setup a few things. First, I created a new user "appuser" to run the app as and setup my public key:

sudo adduser appuser --system --disabled-password --group --shell /bin/bash
cd /home/appuser
mkdir .ssh
cd .ssh
echo "--paste your public key here--" >> authorized_keys
chmod 600 authorized_keys

I also installed mongo, ruby & sass

sudo apt-get update
sudo apt-get install mongodb ruby
gem install sass

Then I logged into the server as the app user, and installed NVM:

curl https://raw.githubusercontent.com/creationix/nvm/v0.15.0/install.sh | bash

Next I setup node:

nvm install v0.10.31
nvm default v0.10.31

Then I installed yo & forever, and our generator:

npm install -g yo forever generator-angular-fullstack

Next I built a simple app:

mkdir ~/app && cd $_ && yo angular-fullstack

I built it with everything, though I didn't actually setup the passport stuff for 3rd parties, not sure why I even enabled them, but I did. =)

Next I setup my environment:

export NODE_ENV="production"

I built the app:

grunt build

Lastly, I launched it:

cd dist
forever server/app.js &

The & at the end tells the process to run in the background, so I can log out even and it will keep running.

remicastaing commented 10 years ago

Well, but @thomporter you didn't deploy an app on ec2, you build an app from scratch on an ec2 instance.

For openshift, the generator help to build an app locally and then help to deploy it on an openshift gear.

thomporter commented 10 years ago

Shouldn't be a problem. Build your app locally and just copy the dist folder up to the server...

nschurmann commented 10 years ago

Totally loved this. Now i can deploy with forever.

2014-09-04 16:10 GMT-04:00 Thomas Porter notifications@github.com:

Shouldn't be a problem. Build your app locally and just copy the dist folder up to the server...

— Reply to this email directly or view it on GitHub https://github.com/DaftMonk/generator-angular-fullstack/issues/501#issuecomment-54536979 .

remicastaing commented 10 years ago

You're right. I just compared your recipe (witch is really helpful) with the single yo angular-fullstack:openshift command to deploy on openshift.

I thought what @nschurmann was seeking is to deploy on ec2 in the same way.

thomporter commented 10 years ago

@remicastaing @nschurmann :smile:

Having a yo angular-fullstack:aws.ec2 might be possible, we'd just have to setup some parameters on what's required on the instance up front, which would vary depending on what is picked during app generation. Ruby & Sass for instance were only needed because I choose them during the setup, and was actually building the app on the instance. If you're building the app offsite and just deploying a dist folder, (as you probably should be) then they wouldn't be needed.

I haven't even looked at the deployment parts of the generator yet, perhaps someone with more experience in that area could chime in? @DaftMonk can you give insight or @ someone who can? =)

thomporter commented 10 years ago

I just looked at grunt-ec2. :+1: @remicastaing

This would be an excellent way to add support for ec2 to the generator...

JaKXz commented 10 years ago

If anyone has started working on a PR, it would be nice to keep in mind that using grunt-build-control would be the best way to go about it... something like what I suggested in #517.

BTW, can any Azure users confirm my suggestion? I was honestly spitballing but it should work.

thomporter commented 10 years ago

For what it's worth, the above recipe works great for just distributing the dist folder to the ec2 instance. Only had to install Node and MongoDB and then run npm install in the dist folder once it was on the server. After that I set the NODE_ENV environment varialbe to production and was able to startup the app with forever as shown above. It went really smoothly - 0 issues. :smile:

On another note, I'm using the generator to build a project for #hack4good 0.6. I'll send a link once the project is done. If anyone's looking for something to do this weekend, I could use some help writing tests! :wink: Here's some info on the project I'm working on at the moment. If interested, join the event, get into Hipchat and then ping me using @ThomasPorter. Or find me in the #sploopy room.

mescalito commented 9 years ago

the main problems why you CAN NOT deploy the /dist folder to any other cloud, apart of Heroku and Openshift is because:

  1. There are only two recipes: yo angular-fullstack:openshift and yo angular-fullstack:heroku. If you want more then you are screw and have to create your own solution (lovely!)
  2. On top of this madness, the stupid /dist folder is not deployable (WTF!). Yes you read it right, you spend the whole fricking day to understand how everything work to realize you can't just simply commit or ftp the /dist folder to you server, that is BS!

Yes, you always can work around, but isn't this generator created to save time, not to make it harder?

thomporter commented 9 years ago

@mescalito a little harsh there no? I mean, this is free software you're using to help you get a job done. The generator surely helps you generate a well structured, full-stack app (client & server.) It does this incredibly well, and saves you TONS of time, just in boilerplate code alone. For me at least, deployment is just a bonus.

Furthermore, you CAN simply copy (scp, ftp, rsync) the /dist folder to your server, but you have to make sure your server can run node apps, that you setup the environment variables properly, and you have to install the dependencies (cd dist/ && npm install) on the server once you copy it there - something that has to be done always (though some platforms do it for you.) I've been able to get apps built by this generator running under 3 completely different environments/hosts now this way.

Lastly - PRs are accepted. You're more than welcome to help write a deployment scheme for whatever your needs might be, to help improve the generator.

flt123 commented 9 years ago

@mescalito I normally don't comment on rants but I must say you sir, are one ungrateful human being. These guys have been putting time into this for over a year and all you have to say is that this does not meet your exact needs. Really!

Show some appreciation and respect for those that have shared their codes, especially when they are some of the best in that field.

mescalito commented 9 years ago

I did my own recipe, I even a video:

Deploy AngularJS into Amazon EC2 using Yeoman Angular-Fullstack Generator https://www.youtube.com/watch?v=nU7R41-90u0

you can avoid the first 13 minutes setting up and go direct to the important part:

https://www.youtube.com/watch?v=nU7R41-90u0#t=687

Deploy AngularJS into Amazon EC2 - From start to end.

$: sudo apt-get update
$: sudo apt-get install -y python-software-properties python g++ make
$: sudo add-apt-repository ppa:chris-lea/node.js
$: sudo apt-get update
$: sudo apt-get install nodejs
$: sudo apt-get install git
$: sudo npm install forever -g
$: cd ~/
$: mkdir repo_do_not_delete
$: cd repo_do_not_delete
$: git init --bare
$: cd repo_appNico/hooks/
$: cat > post-receive
#!/bin/sh
GIT_WORK_TREE=/home/ubuntu/www
export GIT_WORK_TREE
git checkout -f
$: chmod +x post-receive
$: cd ~/
$: mkdir www/
[remote "AWS_production"]
    url = ssh://ubuntu@YOUR-IP/home/ubuntu/repo_do_not_delete/
    fetch = +refs/heads/*:refs/remotes/repo_do_not_delete/*
    puttykeyfile = C:\\Users\\YOUR-USER\\.ssh\\private.ppk
$: cd ~/www/ 
$: sudo npm update
$: sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
$: sudo iptables -t nat -L -n --line-number
$: node www/serv/app.js

this is very hacky and is not the way to go, u need to place this on the hook

:grin: :grin:

:grin: Now everything is working, Open your browser on your IP address :grin:

But here is the BIG!!! problem: you will lose your changes on file server/app.js in your next deploy. The solution is to use tell the hook to execute a file start.sh, this fill will run the server for you with your NODE_ENV variables

:black_nib:

$: cd ~/www/
$: cat > start.sh
# this file is execute by post-receive everytime a Git Commit is made
# Path: /home/ubuntu/repo_uc3d_dmanager_DO_NOT_DELETE/hooks/post-receive
forever stopall
NODE_ENV='production' forever start server/app.js
$: chmod +x start.sh
$: cd ~/repo_do_not_delete/hooks/
$: nano post-receive

> add this code:
> cd $HOME/www
> ./start.sh

Now make a new commit and everything should work automatically.

And there you have a deployment workflow for to Deploy AngularJS into Amazon EC2 using Yeoman Angular-Fullstack Generator

https://www.youtube.com/watch?v=nU7R41-90u0#t=687


In general I do not like the workflow used by the Angular-Fullstack because deploying is extremely complicated due to the ENV variables :rage:.

Also the Grunt.js file provided by the Angular-Fullstack Generator should have meaningful comments :rage:. Why is so poor documented due to the fact that is the most critical piece on the generator?

eduals commented 9 years ago

Awesome @mescalito

rgr2k commented 9 years ago

sucks !!!

tinisasa commented 9 years ago

@mescalito you rock!

wmyers commented 9 years ago

@mescalito there's a lot of really useful stuff in your recipe.

One possible issue - if you are binding the NODE_ENV setting to when git commits from the client (which stops and restarts forever process manager), what happens if the server restarts for a different reason? Presumably the production env would not get passed...

This link is quite handy

Btw I'm not crazy about the lack of comments in the angular-fullstack Gruntfile but it is still a great free resource.

Geoide commented 9 years ago

Yes, .bash_profile solution :)

ghost commented 8 years ago

I have some problem. I am connected to my EC2 server on amazon using SSH, the code "node server/app.js" it is working very good. and i can see the web page. But when i finish the SSH connection the node sever is stopped and the web page it not avaliable. Someone can me suggest some thing to solution it? Thanks

Awk34 commented 8 years ago

@victorhugoviiii That's because any running process will close once you close a terminal session. Using something like nohup node server/app > log should work.

chinnichaitanya commented 8 years ago

You can use pm2 too. It has many more features.

Tom2277 commented 8 years ago

thanks @mescalito I used most of your recipe to deploy on AWS EC2 . I also got a mongo DB working

I'll share a couple things that I worked through :

1) I couldn't figure out how to push a single directory (dist) from within an existing git repo(I do want to track my entire project) into the new distrepo . I opted for cutting and pasting the dist files into the separate distrepo I tried all sorts of git subtree stuff but finally decided copying and replacing all wouldn't be much a burden.

2) on a mac that "puttykeyfile" or any other names I guessed didn't work. I worked around it using first two lines mescalito put in his gitconfig file and then I easily set a ssh on my mac like this: ssh-add /Users/tomn/documents/projects/awskeystorage/ThisProjectPair.pem

3) I used @wmyers suggested link and setup bash to set the NODE_ENV to production: $ echo export NODE_ENV=production >> ~/.bash_profile $ source ~/.bash_profile it just seemed more straightforward and more useful in other cases of server shutdown than the .sh file

4) I got a mongodb working using directions here http://programmersdiary.com/node/deploy-mean-stack-app-on-amazon-ec2/ and here https://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/

IF you followed 3 and set NODE_ENV to production you'll avoid npm install intalling all of dev dependencies avoiding much of - Dependencies unmet: I had hundreds of warnings I believe due to my initial attempts to compile via grunt instead of using the mescalitos technique of pushing dist.

note: node comes with an old npm version and 'npm update' doesn't update it. You should google around but worked for me was 'sudo npm install -g forever' TWICE first time didn't do it. http://askubuntu.com/questions/562417/how-do-you-update-npm-to-the-latest-version again might be a better more current way for that.

Note 2: AWS ec2 instances evidently go awry with some frequency. I spoke to a AWS support person at their pop-up loft in SF and he advised me that a very very early thing to try when things start working is to launch a new EC2 instance and try your code on that before assuming your code is at fault. "is the cord plugged in" debugging almost. I wasted a couple weeks looking for issues with my passport-facebook and passport-twitter ouath which went away after I launched a new ec2 instance.

ghost commented 8 years ago

@mescalito thank you for your comments. I'm a macosx user and had to do few changes as also tom suggested

chmod ug+x hooks/post-receive

ssh-add <pathtokey>.pem

then updating the git config files file as below

[remote "production"]
    url = ssh://ubuntu@xxxxxxxxx.us-west-2.compute.amazonaws.com/home/ubuntu/xxxxxx/
    fetch = +refs/heads/*:refs/remotes/xxxxxx/* 
#!/bin/bash

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`
  if [ "production" == "$branch" -o "master" == "$branch" ]; then

    git --work-tree=/home/ubuntu/www checkout -f $branch

    echo 'Changes pushed to Amazon EC2 PROD.'
  fi
done
  curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
  sudo apt-get install -y nodejs
duncan-p commented 8 years ago

I know this issue is quite old now and there has been some good input already on deploying to AWS, but in case anyone is interested, here's a guide I put together for my team detailing the steps needed to take an Angular Fullstack app from development to production using AWS OpsWorks.

https://gist.github.com/duncan-p/8b8df883babf65c0350a6c2553d864ab

I know this differs from Heroku/Openshift deployment in that it doesn't push directly to your production servers, but I'm a huge fan of OpsWorks and since I started using it a year or so ago, I haven't looked back.
The biggest advantage for me is it gives Devs and QA testers the power to launch a new instance with a couple of clicks and have their server up-and-running with the latest tagged version of the app in a couple of minutes.