Deploy Yeoman full-stack app with Apache2 Reverse Proxy? - angularjs

I have a Yeoman full-stack app #2.0.13 with the exact same directory structure as in this tutorial.
Everything works fine - grunt serve:dist etc works without any errors. Now I want to go in production and deploy the app on a apache server as example.com/xxx using mod_proxy. I copy the grunt build generated /dist directory to a home directory and start up the server app :
NODE_ENV=production node server/app.js
The app starts up, populating users and so on. Everything works well. Now I setup virtual host settings for the node app :
<Location /html/xxx/>
ProxyPass http://127.0.0.1:9000/
ProxyPassReverse http://127.0.0.1:9000/
</Location>
This sort of works. The weird thing is, that index.html from the dist directory is loaded correct
dist
├── public
│ ├── app
│ ├── assets
│ ├── bower_components
│ └─ index.html <---
|
└── server
├── api
├── auth
├── components
├── config
├── views
├─ app.js
└─ router.js
The proxyPass works, index.html is loaded - but the files index.html is referring to (the 4 assembled public/app files/ vendor.js, app.js and so on) is not. I get a 404 no matter what I have tried, no matter what setup from any guide I have tested
Have really spent many hours on this. To me it seems that the reverse proxy somehow alters the internal urls? The setup works if i replace dist/ with a node script that just listens on port 9000 and returns hello world.
What am I missing? Is there another way to do this?

So I was looking all over the place for quite some time as well but finally found this link:
Apache and Yeoman built NodeJS app on the Same Server... Virtual Hosts?
Which brought me on the right track, so I think what should fix it is to change the base tag in your header section of the index.hml file to:
<base href="/xxx/">
And they should be accessible, at least for me.
My vhost settings look like this:
<Proxy /xxx/*>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /xxx http://127.0.0.1:6969/
ProxyPassReverse /xxx http://127.0.0.1:6969/

For anyone else having this problem I ended up using port 80. This works. In a node environment you not need or use a /www or apache / nginx anyway. So get rid of this and use
// Server port
port: process.env.OPENSHIFT_NODEJS_PORT ||
process.env.PORT ||
80,
in the yeoman production.js file. Thats it. An entire application can be served from within a user home/ directory without installing any kind of server http software. Just upload dist to anywhere on your server and use forever to run :
sudo NODE_ENV=production forever start server/app.js

Related

Mern Project Folder structure help neeeded

root/
├─ frontend/
├─ backend/
.gitignore
.git/
I have a root folder and inside of that root i have two folders one is frontend and another one is backend. and i have git initialize on the root folder. Now I want to deploy frontend on firebase and backend on the heroku. The problem is that to deploy backend on herko 'coz it'll ask me to git initialize. how to handle this situation.

Docker - send http request from one container to another

I cannot send an HTTP request to backend container when I'm running app on AWS server production. However, when I'm running app locally I can make requests to backend just fine. For making requests I use fetch:
fetch('http://localhost:8000/something')
Here is how project structure looks like:
.
├── docker-compose.yml
|
├── backend
│   ├── Dockerfile
│   └── server.js
|
└── frontend
├── Dockerfile
├── package.json
├── public
│   └── index.html
└── src
   ├── components
   ├── data
   ├── index.js
   ├── routes.js
   ├── static
   ├── tests
   └── views
docker-compose.yml:
version: '3'
services:
frontend:
build:
context: .
dockerfile: frontend/Dockerfile
volumes:
- ./frontend:/frontend
ports:
- "80:5000"
links:
- backend
backend:
build:
context: .
dockerfile: backend/Dockerfile
volumes:
- ./backend:/backend
ports:
- "8000:8000"
Dockerfile in frontend:
FROM node:latest
RUN mkdir -p /frontend
WORKDIR /frontend
ADD . /frontend
VOLUME ["/frontend"]
EXPOSE 5000
CMD yarn && yarn build && yarn global add serve && serve -s build
Dockerfile in backend:
FROM node:latest
RUN mkdir -p /backend
WORKDIR /backend
ADD . /backend
VOLUME ["/backend"]
EXPOSE 8000
CMD yarn && yarn start
Can someone explain me what is wrong with my config? I'm very confused, because it works without any issues locally.
TLDR: Need to change the frontend code to call the current host instead of 'localhost'
The problem is your app is saying 'hey localhost' instead of 'hey VPS ip', when visiting from YOUR browser. You need to edit your frontend code to visit the current host you're visiting. That's why you're receiving a request on YOUR localhost server.
Instead of fetch("http:///localhost:8000/something") change it to fetch("http://"+location.host+":8000") (There are better ways, this gets it done).
Also note docker containers are a little different in terms of networking as well. A docker container doesn't really have a concept of 'localhost' the same way non docker container apps do. You have to use the VPS's IP/Local IP when making the call from server to server. A trick I use is to use docker's default docker0 bridge 172.17.0.1.
I tend to use networks over 'links' and actually cant comment fully on it, but when containers were on the same docker network, you could access the other container by using the container's name. This only works for server side code however, ie: node.js server -> node.js server/mongo db. Example mongodb connection would be mongodb://mongo_server:27017/mydatabase and mongo_server would resolve to the container's IP.
Another thing you'll possibly encounter when attempting to use the IP is your firewall, you would have to allow that particular ip/port in through your firewall as well.

How do I make vendoring work with Google App Engine?

I am trying to introduce Go vendoring (storing dependencies in a folder called vendor) to an existing App Engine project. I have stored all dependencies in the vendor folder (using Godep as a helper) and it looks right, but running the application locally I get the following error:
go-app-builder: Failed parsing input: package "golang.org/x/net/context" is imported from multiple locations: "/Users/erik/go/src/github.com/xyz/abc/vendor/golang.org/x/net/context" and "/Users/erik/go/src/golang.org/x/net/context"
I believe the two locations should resolve to the same location, as Go applications should look in the vendor folder first. Is there a way to make Appengine understand that both dependencies are the same?
Your project directory (where app.yaml is) is probably in the GOPATH/src.
It shouldn't be.
The go-app-builder will take everything in the app.yaml folder (and below) and additionally merge your GOPATH into it, meaning now you have it twice.
The solution is to move app.yaml out of the GOPATH/src folder.
Additionally you'll find that goapp test works differently from goapp serve and goapp deploy when it comes to resolving dependencies.
So this is the solution I have been using (haven't used golang app engine in a while already) and it's the only setup I've found to work properly for all the goapp commands and for govendor to work properly (not sure about godep)
/GOPATH
├──/appengine
| ├── app.yaml
| └── aeloader.go
└──/src
└── /MYPROJECT
├── main.go
├── /handler
| └── handler.go
└── /vendor
details:
file: GOPATH/appengine/aeloader.go (NOTE the init function is necessary, probably a bug though)
package mypackage
import (
_ "MYPROJECT"
)
func init() {
}
now run goapp serve and goapp deploy from ../GOPATH/appengine/ and goapp test ./... from ../GOPATH/src/MYPROJECT
P.S. I find the global GOPATH thing silly and simply set my GOPATH to current project folder (in the example above /GOPATH) and check the whole thing into version control.
I use a Makefile to move the vendor directory to a temporary GOPATH:
TMPGOPATH := $(shell mktemp -d)
deploy:
mv vendor $(TMPGOPATH)/src
GOPATH=$(TMPGOPATH) gcloud app deploy
mv $(TMPGOPATH)/src vendor
I store this Makefile at the root of my service near the vendor directory and simply use make deploy to deploy manually or from the CI.
It works with Glide, Godeps or any tool that respects the Go vendor spec.
Please note, that you really need to move the vendor directory out of the build directory, otherwise the GoAppEngine compiler will try to build the vendor dependencies, potentially causing compile errors.
I just ran into this issue myself actually. The problem occurs when you're using the App Engine tools to build any package which imports something that is using vendoring, but the package you're trying to run doesn't have the import within it's vendor directory.
So, for example, if I'm trying to run package foo, which imports package bar, and both of which use the github.com/gorilla/mux library, if the bar repository has a vendor/ directory that contains gorilla/mux, but the foo package doesn't have gorilla mux in it's vendor/ directory, this error will occur.
The reason this happens is that the bar package will prioritize it's own vendor package over the one in the GOPATH, which is what foo will be using, causing a difference in the actual location of the imported paths.
The solution I found to this issue is to make sure that the foo directory is in the GOPATH and has the vendor directory properly installed. It's important to note that the vendor/ convention only works from within the GOPATH.
I managed to resolve this error using govendor instead of Godeps. The root cause appears to have been that vendored references with their own vendored references was not resolved correctly by Godeps.
The answer provided by Su-Au Hwang is also correct - you do have to keep app.yaml separate from your source.
Also got the same problem.
In the docs Google suggests the following:
For best results, we recommend the following:
Create a separate directory in your app's directory for each service.
Each service's directory should contain the service's app.yaml file and one or more .go files.
Do not include any subdirectories in a service's directory.
Your GOPATH should specify a directory that is outside your app's directory and contain all the dependencies that your app imports.
But this messes up my project structure, which looks like this:
GOPATH/
└── src
└── github.com
└── username
└── myproject
├── app.yaml
├── cmd
│   └── myproject
│   └── main.go
├── handlers
│   └── api.go
├── mw
│   ├── auth.go
│   └── logger.go
└── vendor
Where the myproject directory is a git project and the vendor folder contains all dependencies.
Running gcloud deploy from the myproject directory where app.yaml file lives doesn't work because first, main.go file is not in the same directory and second (from the same doc):
you must be careful not to place your source code at or below your app's directory where the app.yaml file is located
What I ended up doing is building my own custom runtime instead, which turned out to be a very clean solution.
Simply generate the Dockerfile with the following command:
gcloud beta app gen-config --custom
Modify it, then specify runtime: custom in your app.yaml and deploy normally.
The trick here is of course that you're in control what gets copied where.
Here is my Dockerfile:
# Dockerfile extending the generic Go image with application files for a
# single application.
FROM gcr.io/google-appengine/golang
ENV GOPATH /go
# The files which are copied are specified in the .dockerignore file
COPY . /go/src/github.com/username/myproject/
WORKDIR /go/src/github.com/username/myproject/
RUN go build -o dist/bin/myproject ./cmd/myproject
# All configuration parameters are passed through environment variables and specified in app.yaml
CMD ["/go/src/github.com/username/myproject/dist/bin/myproject"]
Don't forget that App Engine expects your application listening on port 8080. Check out Building Custom Runtimes doc for more details.

possible to change where github pages looks for index.html?

I have a site generated with yeoman's generator-angular and I'd like to publish this site using github pages. I create the gh-pages branch but my repo does not show up in myusername.github.io/myreponame I think the reason is because index.html is in the app/ directory not the root.
app/
|-- index.html
|-- scripts/
dist/
Gruntfile.js
etc..
Can I tell github pages to load index.html from the app folder? How can I launch a site generated w/ angular-generator to gh pages?
Running grunt build is important as without it dist directory is not created. Also changes will appear on gh-pages only after they are added and pushed to the subtree.
Remove dist from .gitignore file
Run grunt build in console
After the project is built the dist directory needs to be added to the GitHub. Run this command in console: git add dist && git commit -m "Initial dist subtree commit"
And then push the subtree to the gh-pages branch: git subtree push --prefix dist origin gh-pages
All of your answers can be found here!
In a nutshell, you will generate the deployment-ready version of your site. You do this by running grunt. That will generate the optimized, production site in a folder called dist. You will then push the contents of dist directly to gh-pages.
A frequent contributor to Yeoman also made this task: grunt-build-control, which will let you simply run something like grunt deploy.

How do I create a new Google App Engine project in IntelliJ 12 which works?

I'll begin by saying that I have no prior GAE experience - I'm trying to get GAE working in IntelliJ 12 but having issues, was wondering if anyone could have a look over what I'm doing and tell me if there's anything wonky here.
Steps:
Create Java project in IntelliJ with JDK 1.7.0_51. Click Next.
Select Web Application > Google App Engine on desired techs page
with path to appengine-java-sdk-1.8.9. Click Finish.
Copy files from appengine-java-sdk-1.8.9/demos/new_project_template/ to project
directory
I now have a main directory structure like:
.
├── COPYING
├── build.xml
├── html
│   └── index.html
├── src
│   ├── META-INF
│   │   └── jdoconfig.xml
│   ├── WEB-INF
│   │   ├── appengine-web.xml
│   │   └── web.xml
│   ├── log4j.properties
│   ├── logging.properties
│   └── org
│   └── example
│   └── HelloAppEngineServlet.java
├── test.iml
└── web
├── WEB-INF
│   ├── appengine-web.xml
│   └── web.xml
└── index.jsp
Running this will run the webserver with the index.jsp in the web directory.
A few questions around this - should there be a 'web' and an 'html' directory? Why are there two WEB-INF directories and should they both be the same? Should I manually edit both of them each time I update one?
If I then follow the instructions at https://developers.google.com/appengine/docs/java/gettingstarted/creating it mentions a 'war' folder - I confess that I'm confused about the 'war', 'web' and 'html' folders - I think somewhere I've also seen referenced a 'www' folder. Do these folder names actually matter?
Following the tutorial I create a guestbook folder within the 'src' folder and make the java file. When I enter the info in the web.xml (both of them) I get an error for the line
<servlet-name>guestbook</servlet-name>
"A field of identity constraint 'web-app-servlet-name-uniqueness' matched element 'web-app', but this element does not have a simple type"
To top that off - guestbook.GuestbookServlet doesn't resolve.
There has to be a simpler way of getting this running in Intellij - can anyone help me?
Unfortunately, IntelliJ does not make this process simple. It seems like they expect you to use Maven to handle a lot of this. But this makes things a lot harder on people trying to get started with GAE on IntelliJ.
Your project is a mess right now. You have combined things that IntelliJ added for your web module with some of the files from the demo projects. So to start, remove your files and remove your web module from IntelliJ.
Now go back to the demo folder that you want to use, it should include the COPYING, build.xml, and a src and war dir. Copy all of those to your project. Then go into project structure->modules and import module. This will allow IntelliJ to detect your web module and avoid creating duplicate files and dirs.
You also need to configure your Application Server under Settings->IDE Settings->Application Servers. Add a Google App Engine Dev Server and specify your SDK directory.
Then go back to your Project Structure->Module->Dependencies and add a Library. Select the Application Server Library that you just defined. If your project uses more advanced features of GAE, you will need to go to Project Structure->Artifacts and add the libraries to your artifact.
Also for the settings on the Artifact, you need to create an 'exploded war' definition that points to your war dir.
There is likely more configuration needed... but I can't think of it all right now. Let me know what you get stuck on next and I can try to help.
IntelliJ IDEA 14 Ultimate has integrated GAE support. How comprehensive this is I'm not totally sure yet. I'll update this answer shortly with more details.
https://www.jetbrains.com/idea/features/google_app_engine.html

Resources