Document installation of app, including in production. Add smf manifest so
we can run this in a Joyent-branded zone too.
This commit is contained in:
parent
db8758cc30
commit
51028156c9
81
README.md
81
README.md
@ -1,25 +1,74 @@
|
|||||||
|
# Installing in Production
|
||||||
|
|
||||||
|
Be familiar with the steps in [Installation][] below, since it is needed to
|
||||||
|
build the Angular app first.
|
||||||
|
|
||||||
|
Once the Angular app is built, provision a small base-64-lts 20.4.0 VM,
|
||||||
|
connected solely to the external network (aka public Internet). From within
|
||||||
|
the VM, the following steps are needed:
|
||||||
|
|
||||||
|
pkgin in gmake
|
||||||
|
mkdir -p /opt/spearhead/portal
|
||||||
|
|
||||||
|
From this repo, copy in bin/, cfg/, smf/, static/ (since this is a symlink,
|
||||||
|
this means the build in app/dist should be copied into static/ in prod), and \*.
|
||||||
|
Notably, avoid app/ and node\_modules. In production, adjust the config in
|
||||||
|
/opt/spearhead/portal/cfg/prod.json. Lastly:
|
||||||
|
|
||||||
|
pushd /opt/spearhead/portal
|
||||||
|
npm install
|
||||||
|
svccfg import smf/service.xml
|
||||||
|
svcadm enable portal
|
||||||
|
popd
|
||||||
|
|
||||||
|
The application will now be running.
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
|
First install the server-side libraries:
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
# Generate server certificates
|
Then install the Angular compiler needed for the client-side app:
|
||||||
|
|
||||||
From within the config/ directory:
|
npm install -g @angular/cli
|
||||||
|
pushd app && npm install && popd
|
||||||
|
|
||||||
|
## Build the client-side app:
|
||||||
|
|
||||||
|
pushd app && npm run build && popd
|
||||||
|
|
||||||
|
## Generate server certificates
|
||||||
|
|
||||||
|
pushd config
|
||||||
openssl genrsa -out key.pem
|
openssl genrsa -out key.pem
|
||||||
openssl req -new -key key.pem -out csr.pem
|
openssl req -new -key key.pem -out csr.pem
|
||||||
openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
|
openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
|
||||||
rm csr.pem
|
rm csr.pem
|
||||||
|
popd
|
||||||
|
|
||||||
# Configuration
|
## Configuration
|
||||||
|
|
||||||
Ensure the config file in config/ matches your details.
|
Ensure the config file in config/ matches your details. If running in
|
||||||
|
production, name the config file config/prod.json.
|
||||||
|
|
||||||
|
Relevant configuration attributes:
|
||||||
|
|
||||||
|
- server.port: the port this server will serve the app from
|
||||||
|
- server.key: path to the private key for TLS
|
||||||
|
- server.cert: path to the PKIX certificate for TLS
|
||||||
|
- urls.local: the domain or IP the SSO will redirect back to (aka this server)
|
||||||
|
- urls.sso: the URL to the SSO
|
||||||
|
- urls.cloudapi: the URL to cloudapi
|
||||||
|
- key.user: name of Triton user who has "Registered Developer" permission set
|
||||||
|
- key.id: SSH fingerprint of Triton user (same as what node-triton uses)
|
||||||
|
- key.path: path to private key of Triton user
|
||||||
|
|
||||||
The SSH key used must be the correct format, e.g. generated with:
|
The SSH key used must be the correct format, e.g. generated with:
|
||||||
|
|
||||||
ssh-keygen -m PEM -t rsa -C "your@email.address"
|
ssh-keygen -m PEM -t rsa -C "your@email.address"
|
||||||
|
|
||||||
# Running the server
|
## Running the server
|
||||||
|
|
||||||
node bin/server.js config/prod.json
|
node bin/server.js config/prod.json
|
||||||
|
|
||||||
@ -31,18 +80,18 @@ and instead:
|
|||||||
|
|
||||||
# Endpoints
|
# Endpoints
|
||||||
|
|
||||||
## GET /*
|
## GET /\*
|
||||||
|
|
||||||
This is where all the front-end code goes. All files will be served as-is as
|
This is where all the front-end code goes. All files will be served as-is as
|
||||||
found in that directory (by default a symlink to app/dist). The default is
|
found in that directory (by default a symlink from static/ to app/dist). The
|
||||||
static/index.html. There is no authentication; all files are public.
|
default is static/index.html. There is no authentication; all files are public.
|
||||||
|
|
||||||
## GET /api/login
|
## GET /api/login
|
||||||
|
|
||||||
Call this endpoint to begin the login cycle. It will redirect you to the SSO
|
Call this endpoint to begin the login cycle. It will redirect you to the SSO
|
||||||
login page: an HTTP 302, with a Location header.
|
login page: an HTTP 302, with a Location header.
|
||||||
|
|
||||||
## GET/POST/PUT/DELETE/HEAD /api/*
|
## GET/POST/PUT/DELETE/HEAD /api/\*
|
||||||
|
|
||||||
All calls will be passed through to cloudapi. For these calls to succeed,
|
All calls will be passed through to cloudapi. For these calls to succeed,
|
||||||
they MUST provide an X-Auth-Token header, containing the token returned from
|
they MUST provide an X-Auth-Token header, containing the token returned from
|
||||||
@ -50,12 +99,12 @@ SSO.
|
|||||||
|
|
||||||
# Interaction cycle
|
# Interaction cycle
|
||||||
|
|
||||||
client --- GET /api/login --------> this server
|
client --- GET /api/login --------> this server
|
||||||
<-- 302 Location #1 ----
|
<-- 302 Location #1 ----
|
||||||
|
|
||||||
client --- GET <Location #1> --> SSO server
|
client --- GET <Location #1> --> SSO server
|
||||||
<separate SSO cycle>
|
<separate SSO cycle>
|
||||||
<-- 302 with token query arg
|
<-- 302 with token query arg
|
||||||
|
|
||||||
From now on call this server as if it were a cloudapi server (using [cloudapi
|
From now on call this server as if it were a cloudapi server (using [cloudapi
|
||||||
paths](https://github.com/joyent/sdc-cloudapi/blob/master/docs/index.md#api-introduction)),
|
paths](https://github.com/joyent/sdc-cloudapi/blob/master/docs/index.md#api-introduction)),
|
||||||
@ -63,8 +112,8 @@ except prefixing any path with "/api". Also always provide the X-Auth-Token.
|
|||||||
|
|
||||||
For example, to retrieve a list of packages:
|
For example, to retrieve a list of packages:
|
||||||
|
|
||||||
client --- GET /api/my/packages --> this server
|
client --- GET /api/my/packages --> this server
|
||||||
<-- 200 JSON body ------
|
<-- 200 JSON body ------
|
||||||
|
|
||||||
The most useful cloudapi endpoints to begin with will be ListPackages,
|
The most useful cloudapi endpoints to begin with will be ListPackages,
|
||||||
GetPackage, ListImages, GetImage, ListMachines, GetMachine, CreateMachine and
|
GetPackage, ListImages, GetImage, ListMachines, GetMachine, CreateMachine and
|
||||||
|
4
smf/run.sh
Executable file
4
smf/run.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cd /opt/spearhead/portal
|
||||||
|
/opt/local/bin/node bin/server.js cfg/prod.json &
|
15
smf/service.xml
Normal file
15
smf/service.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version='1.0'?>
|
||||||
|
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
|
||||||
|
<service_bundle type='manifest' name='portal:default'>
|
||||||
|
<service name='spearhead/portal' type='service' version='1'>
|
||||||
|
<create_default_instance enabled='false' />
|
||||||
|
<single_instance />
|
||||||
|
|
||||||
|
<method_context>
|
||||||
|
<method_credential user='root' group='root' />
|
||||||
|
</method_context>
|
||||||
|
|
||||||
|
<exec_method name='start' type='method' exec='/opt/spearhead/portal/smf/run.sh' timeout_seconds='60'/>
|
||||||
|
<exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'/>
|
||||||
|
</service>
|
||||||
|
</service_bundle>
|
Reference in New Issue
Block a user