Deploying static files


#1

I basically just want to deploy a SPA to the nginx root directory. I have come along this post here https://www.habitat.sh/blog/2017/08/Packaging-a-Website-with-Nginx-and-Habitat/ and I am using a plan similar to the one in github, which looks like that:

pkg_name=www
pkg_origin=myorg
pkg_version="0.1.0"

do_build() {
  return 0;
}

do_install() {
  mkdir -p "/srv/www"
  cp -vR dist/* "/srv/www/"
}

default.toml is unchanged and all the other directories within the habitat directory are empty.

then I enter the hab studio via: hab studio enter
build the package via: build
and load the package: hab svc load myorg/www

sup-log then shows the following entries, which continues until I unload the service:

www.default(UCW): Watching user.toml
www.default(HK): Hooks compiled
www.default(SR): Error finding run file: No such file or directory (os error 2)
www.default(SR): Initializing
www.default(SV): Starting service as user=hab, group=hab
www.default(SR): Service start failed: hab-sup(ER)[components/sup/src/error.rs:509:9]: Unknown: Unable to spawn process, No such file or directory (os error 2)
www.default(SV): Starting service as user=hab, group=hab
www.default(SR): Service restart failed: hab-sup(ER)[components/sup/src/error.rs:509:9]: Unknown: Unable to spawn process, No such file or directory (os error 2)
www.default(SV): Starting service as user=hab, group=hab
www.default(SR): Service restart failed: hab-sup(ER)[components/sup/src/error.rs:509:9]: Unknown: Unable to spawn process, No such file or directory (os error 2)
www.default(SV): Starting service as user=hab, group=hab
www.default(SR): Service restart failed: hab-sup(ER)[components/sup/src/error.rs:509:9]: Unknown: Unable to spawn process, No such file or directory (os error 2)
www.default(SV): Starting service as user=hab, group=hab
www.default(SR): Service restart failed: hab-sup(ER)[components/sup/src/error.rs:509:9]: Unknown: Unable to spawn process, No such file or directory (os error 2)

however from within the hab studio it seems all my files were installed:

 ls -al /srv/www/
total 24
drwxr-xr-x 3 root root 4096 Jun 19 14:04 .
drwxr-xr-x 3 root root 4096 Jun 19 14:04 ..
drwxr-xr-x 2 root root 4096 Jun 19 14:04 assets
-rw-r--r-- 1 root root  585 Jun 19 14:04 crossdomain.xml
-rw-r--r-- 1 root root 1825 Jun 19 14:04 index.html
-rw-r--r-- 1 root root   51 Jun 19 14:04 robots.txt

Simpler Scaffolding for Static Websites
#2

Ah the issue here is you haven’t given the package a run hook. The error actually is saying: www.default(SR): Error finding run file: No such file or directory (os error 2) which is referring to the run hook required for a service to be able to start. That first planfile is explicitly for taking your static content and creating a package from it. But, it doesn’t have any services attached to it. It’s effectively a glorified tarball that includes all your static content that can then be included like a library dependency. A little further down that blog post theres an example of packaging this static content up with nginx after getting the nginx config and the run hooks in place!


#3

Adding @Hummingbird’s response from slack:

I was under the impression that the run hook is added to the nginx package, but not the static files package, which contains the website… so I am a little confused here now… I tried to add a run hook which just exists with status 0, now my error has changed a little:

hab-launch(SV): Child for service 'www.default' with PID 3420 exited with code exit code: 0```

#4

@Hummingbird Hooks and config aren’t inherited from packages you depend on. You need to create those yourself


#5

sorry, maybe I just don’t get it. I don’t depend on any other packages. I only want to tell habitat to take the files in this directory. And on the server, place those files at that location. But clearly I am missing something within my plan or hook or config.

EDIT: maybe I should also add that I do not use a nginx package within habitat. Chef is setting up nginx. And I only want to use habitat to deploy the SPA files.


#6

Oh, yes this is a misunderstanding of the way that Habitat works, I would definitely suggest checking out our tutorials over here, or if you’re like me and you prefer to learn by doing more practical work, following the blog post substituting your content for the Hello World file that Chris puts in place.


#7

Ohh, we’ll in that case you should never actually run that static site plan. You just install it and point your nginx config for static files to /hab/pkgs/<origin>/<pkg_name>/<version>/<timestamp>


#8

Ahh, I need to deploy those files as config? Not using hab svc load, but hab config apply…


#9

nope, just hab pkg install origin/thing


#10

you’re basically using Habitat like a tarball for your build artifacts


#11

@elliott-davis thank you, that does make sense now…

@eeyun thank you. I have been through all the tutorials. However, they were only helpful to get a overview about the basic usage of habitat. And I keep getting 404s for about half the tutorials that were still there last week. I found the github sources for scaffolding much more helpful in the end, once I found them… But yet, they don’t show how to just get a bunch of files over the wire… Sorry, if those questions seem a little stupid, I am mostly just getting started with habitat.


#12

There are no stupid questions! Please let us know if you need anything at all!


#13

just in case someone comes across this post in the future, I don’t think copying files to /whatever works as I thought it would. The files listed inside the studio probably just were leftovers from building the package.

Secondly, telling nginx using the chef cookbook to change its root directory was a little tricky. That’s what I ended up with so far to get the file location where hab installed it and tell nginx to use that:

ruby_block 'get nginxRoot' do
  block do
    node.run_state['nginxRoot'] = shell_out('hab pkg path myorigin/mypkg').stdout.chomp
  end
end
include_recipe 'nginx'

and the template then needs to consume the run_state attribute:
root <%= node.run_state['nginxRoot'] %>;


#14

Yes I should clarify, your plan doesn’t correctly copy your materials into the package which means on install your package isn’t going to have the appropriate static items. In the blog post example, the first plan for creating an artifact of static files is basically exactly how you need your plan to look. You should copy your content into ${pkg_prefix} in your install step.

Chris only copies the one file index.html but you would copy all of your static content.