Features
(click on a feature to read more)
Static hosting
Push state url routing
If you are creating a single page application you probably want to have nice urls and use push state instead of the old hash navigation. Most modern web framework have routers that support this, other systems supports it with some confusing rewrite modules.
Tundra supports this by first check if a request is "direct" by locking for a dot "." in the last part of the request url. If the request is direct the asset is served or returns a 404 response if missing. Just lika a normal fileserver. If the request is missing a dot in the end it checks for the file and starts to serve that file. If the file is missing It looks for a parent folder and tries to serve that file.
Example:
http://tundra-site.tndr.io/javascripts/all.js -> http://tundra-site.tndr.io/javascripts/all.js
http://tundra-site.tndr.io/javascript/missing.js -> 404
http://tundra-site.tndr.io/index.html -> http://tundra-site.tndr.io/index.html
http://tundra-site.tndr.io/some/sub/folder -> http://tundra-site.tndr.io/index.html
http://tundra-site.tndr.io/some/sub/folder/file.html -> 404
http://tundra-site.tndr.io/angular.html/sub/folder/ -> http://tundra-site.tndr.io/angular.html
Deployment versioning
Every deploy gets its own version number as a unique sub domain. Which you can browse to and test before setting the version to the default version.
If you deploy to versioname: stage
and projectname : example
your deploy will be hosted at
http://stage.example.tndr.io. You can then visit and test the page and if you are happy with the result you can
set stage as the default version with set production in the menu. The site can then be accessed with the shorter
http://example.tndr.io
The version name can include som special strings that are replace during deployment.
DATE => 20150509, todays date
TIME => 201632, time right now
RANDOM => as2a3yt3, a 8 chars random string, useful for hard to guess urls.
stage-DATETIME => stage-20150509201739
semiprivate-RANDOMRANDOM => semiprivate-669wlhkmfpxpmm17
Rollbacks are easy. Just set a previous version as your default version.
Access restriction
In the configuration (se below) it possible to define a list of users with access. If you omit the visit array the site will be public for all to visit.
"users" : {
"visit" : [
"user@example.com:pwd",
"test:test"
],
"admin" : [
"admin@example.com:test"
]
},
Or use a randomized version name to limit the access to only the users with correct url
"versiontemplate" : "test-RANDOM",
"options" : {
"setasdefault" : false
},
HTTPS and gzip
The certificate is self signed for now. To be able to use the bookmarklet on a https site first visit https://tndr.io and accept the certificate.
Custom domain names
To be able to use your own domain. Point your domain name to tndr.io in your DNS. The add a alias in your config.json.
"config" : {
[...]
"alias" : {
"example.com" : "example.tndr.io",
}
[...]
}
It's also possible to point to a specific version of a project:
"config" : {
[...]
"alias" : {
"example.com" : "example.tndr.io",
"stage.example.com" : "stage.example.tndr.io",
}
[...]
}
API
Cross domain request proxy
If you ever tried to access data from a remote server on another doamin you have probably stumbled over No 'Access-Control-Allow-Origin' header is present, CORS and things like that.
To fetch a remote url without worrying about that, use the http proxy:
http://[projectname].tndr.io/api/proxy/http://example.com
To be able to use the proxy a white list have to be defined in the config. It's also possible to add replacements in the config. Which is useful if you need a API key in your request but don't want to expose API keys in the client.
http://[projectname].tndr.io/api/proxy/http://example.com/service/?API_KEY=EXAMPLE_KEY
Make sure you don't use a key name that appear in the url, since it will be replaced.
"config" : {
[...]
"proxy" : {
"domains" : [
"example.com"
],
"replace" : {
"EXAMPLE_KEY" : "thekey"
}
}
[...]
}
Emailing from client
Just add a request to the email endpoint.
In jquery it would look something like:
$.post('http://tndr.io/api/email', {
to : ['to@example.com'],
from : 'to@example.com',
subject : 'the subject of the message',
text : 'the plain textversion',
html : '<h1>and the html version</h1>'
}, callback);
Its possible to define a white list of from or to addesses in the email section in the config to prevent the possiblity to use the server for email spaming. A subject property can be used to allow only one subject.
"config" : {
[...]
"email" : {
"to" : "email1@example.com,email1@example.com",
"from" : "email@example.com"
}
[...]
}
File upload
Upload files to the server to be shared between versions.
Simple form upload:
<form action="http://tndr.io/api/release/upload" method="post" enctype="multipart/form-data">
<input type="text" name="example">
<input type="text" name="callback_url" value="http://example.tndr.io/upload_done#">
<input type="file" name="files">
<input type="submit">
</form>
The callback_url specifies a url to redirect to after the upload, it might be useful if you put the upload within an iframe.
The path to the uploaded files will be appended to the callback_url, so add a ? or # to be able to read it with javascript.
If you add the base url to the server the redirect will go the image. If the callback is missing a json response is returned instead.
Or do a more advanced javascript upload with FileReader and Blobs as the editor does.
Download sites
All releases that you have access to are downloadable. It's convinient if you want to test and modify a site on the web. Just navigate to it, deploy it to tundra and then download the site. Do the modifications and redeploy it.
Simple text editing
A simple editor are included in the menu. Just put an attribute to a block to make it editable. Works with images as well.
html editor:
<section data-tundra-editor="small_section">
</h1>Header text</h1>
</p>Some texts</p>
</section>
image upload:
<img data-tundra-upload="the_image" src="logo.jpg"/>
Deployments
Bookmarklet deployments
Add the bookmarklet to your browser and click the bookmarklet to op en the menu on the page you want to deploy.
Deploy button
Add this code snipplet for a deploy button to your page. When you press the button the page is deployed to the server, super easy. The button will self destruct on the way to the server.
<script type="text/javascript" src="http://tndr.io/api/assets/js/deploy.js"></script>
<button data-tundra-deploy="[version].[project]">Deploy</button>
The data-tundra-deploy attribute defines the version and project name of te deploy. If a config file is present the attribute can be empty.
<button data-tundra-deploy="[version].[project]" [...] > //uses the version and project separated by a dot
<button data-tundra-deploy="[project]" [...] > //uses the project name and DATETIME as default version template, unless defined in config.
<button data-tundra-deploy [...] > //uses the configuration in the config file
Easy configuration
You can deploy to the server without any configurations. But to be able to use the email and proxy apis you need to place a config file in the web root of you application named tundra.json. You can download one from the bookmarklet menu.
Example:
/* Comments in JSON are stripped out before parsing. */
/* The config are shared between all versions in a project. */
{
/* The name of the project */
"projectname" : "tundra-site",
/* Defined the format of versions, default is 'DATETIME' eg. 160209132802
DATE, TIME and RANDOM are replaced during deploy to todays date, time or a random 8 char string.
Can be combined with other strings eg. stage-RANDOM or DATE-TIME */
"versiontemplate" : "DATETIME",
"options" : {
/* Sets the latest deploy as the default version. eg example.tndr.io are set to 160209132802.example.tndr.io,
if that is tha latest deploy. */
"setasdefault" : false,
/* The depth for follow links in html files. */
"recursionDepth" : 5,
/* If false, shorthand for recursion_depth 0 */
"followLinks" : true
},
/* Lists users that are allowed to visit and update the site.
The format are username:password and the protection is basic auth */
"users" : {
/* Uncomment and update the list if you want to restrict access to only these users */
/* "visit" : [
"visitor@example.com"
], */
/* All admin users are also allowed as visitors. At least one admin user are required */
"admin" : [
"test:test"
]
},
/* Config for email sending, mailing are restricted with whitelists to avoid spaming */
"email" : {
/* allowed to adresses. Used for "contact us" senarios. Remove to accept all */
"to" : [
"support@example.com"
],
/* allowed from adresses. Used for mailinglist senarios. Remove to accept all */
"from" : [
"info@example.com"
]
},
/* Config for request proxing */
"proxy" : {
/* Allowed domains to proxy to. */
"domains" : [
"example.com"
],
/* Strings in uris to be replaced, useful for API keys that can't be exposed in the client */
"replace" : {
"APIKEY" : "the_key"
}
}
}
It's also possible to add a `filelist.txt` with a list of all files to upload in the web root. The filelist.txt is a list of files with a filename on each row. The simpliest way to do it is to run
find . -type f > filelist.txt
CLI and CI
If you don't like the magic of the bookmarklet its possible to create releases with curl instead. Here is an example using middleman and uploading a zip.
#!/bin/bash
middleman build
cd build
zip -r ../build.zip .
cd ..
read -s -p "Enter Password: " password
curl --user user@example.com:$password \
--form _zip=@"build.zip" \
--form config="`<build/tundra.json`" \
--form versionname="`git rev-parse --short HEAD`" \
http://tndr.io/api/release/createFromZip?projectname=example
A similar approach can of course be used by Jenkins, Codeship or other CI tools.
Installation and deployment
Basic deployment
- 1. Add the tundra menu bookmarklet to your browser
- 2. Navigate to the page you want to deploy. On localhost, intranet, public internet or whatever
- 3. Press the bookmarklet
- 4. Choose a name and and if subpages should be deployed
- 5. Click deploy
- 6. Done! click on the link to visit the page
Add to bookmarks: Tundra
Configuration deployment
To avoid others to deploy to the same subdomain, the subdomain need to be reserved with a configuration file. The configuration also allows the project to use more features as emailing, proxy, user restriction.
- 1. Open the menu
- 2. In the menu, select download configuration
- 3. Chose your username (email) and a password
- 4. Click download and add the file to your public folder
- 5. Edit the file to configure the project
- 6. Deploy the project as in basic deployment above
Contact
If you have any bugs, improvements suggestions or questions. Don't hesitate to send a message with this tundra proxied google form.