50 | )
51 |
--------------------------------------------------------------------------------
/components/api/sections/errors/oauth2.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import Section, { components } from '../../section'
3 | import { Code } from '../../../text/code'
4 | import { InternalLink } from '../../../text/link'
5 | import immutable from '../../../../lib/immutable-component'
6 |
7 | function OAuth2() {
8 | return (
9 | OAuth2 related endpoint}.
15 | `
16 | ],
17 | [
18 | markdown(components)`
19 | ### Client Not Found
20 | `
21 | ],
22 | [
23 | markdown(components)`
24 | The OAuth2 client ID could not be found or doesn't exists.
25 | `,
26 | markdown(components)`
27 | ${{`{
28 | "error": {
29 | "code": "not_found",
30 | "message": "OAuth client doesn't not found: CLIENT_ID"
31 | }
32 | }`}}
33 | `
34 | ]
35 | ]}
36 | />
37 | )
38 | }
39 |
40 | export default immutable(OAuth2)
41 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Zeit Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/components/api/deprecated.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default class Deprecated extends React.PureComponent {
4 | render() {
5 | const { hash, children } = this.props
6 | const link = `/api${hash}`
7 |
8 | return (
9 |
73 | )
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/components/api/file-icon.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default class FileIcon extends React.PureComponent {
4 | render() {
5 | return (
6 |
26 | )
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # ZEIT Documentation
2 |
3 | This is the public documentation for **ZEIT now** all other related services.
4 | You can access this documentation online at https://zeit.co/docs .
5 |
6 | ### Running Locally
7 |
8 | Download the copy of this repostory.
9 |
10 | ~~~sh
11 | git clone https://github.com/zeit/docs.git
12 | ~~~
13 |
14 | Then visit to the downloaded repository and install dependencies with:
15 |
16 | ~~~sh
17 | npm install
18 | ~~~
19 |
20 | Then you can run the app with:
21 | (The app is written in [Next.js](https://github.com/zeit/next.js))
22 |
23 | ~~~sh
24 | npm run dev
25 | ~~~
26 |
27 | Now the documentation is running at http://localhost:5800
28 |
29 | ### Editing Docs Content
30 |
31 | You can find the source of the documentation inside the `pages/docs` directory. Documentation is mostly written in markdown with the help of some React components.
32 |
33 | Those components give us additional features which are not available in markdown.
34 |
35 | ### Adding New Docs
36 |
37 | You can start writing the new docs page by adding it to the `pages/docs` directory starting with the following code:
38 |
39 | ~~~js
40 | import markdown from 'markdown-in-js'
41 | import withDoc, { components } from '../../../lib/with-doc'
42 |
43 | import { TerminalInput } from '../../../components/text/terminal'
44 |
45 | // prettier-ignore
46 | export default withDoc({
47 | title: 'The Title for the New Guide',
48 | date: '23 June 2017',
49 | authors: [],
50 | editUrl: 'pages/docs/category/file.js',
51 | })(markdown(components)`
52 |
53 | This is the content written in Markdown.
54 |
55 | ${
56 | # this is how we show the terminal input
57 | }
58 |
59 | `)
60 | ~~~
61 |
62 | Then you can add it to the sidebar by editing the file located at: `lib/data/docs.js`.
63 |
64 | ### Adding Images and Assets
65 |
66 | You can add images and assets into the `static` directory. Always try to avoid using hosted images.
67 | If you are creating a new docs page, keep you images inside a subdirectory under `static/docs`.
68 |
69 | ### New Components
70 |
71 | Always try to use the existing components and features in markdown. Create a new component or use a component from NPM, unless there is no other option.
72 |
73 | ### Submiting Changes / New Doc Pages
74 |
75 | You can simply send a PR. It's simple as that.
76 |
--------------------------------------------------------------------------------
/pages/docs/deployment-types/static.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { leo, jamo, rauchg } from '../../../lib/data/team'
5 | import Now from '../../../components/now/now'
6 | import { Code, InlineCode } from '../../../components/text/code'
7 | import { TerminalInput } from '../../../components/text/terminal'
8 |
9 | // prettier-ignore
10 | export default withDoc({
11 | title: 'Deploying Static Apps',
12 | date: '09 March 2017',
13 | authors: [leo, jamo, rauchg],
14 | editUrl: 'pages/docs/deployment-types/static.js',
15 | })(markdown(components)`
16 |
17 | ${} comes with a native support for static deployments. It considers all projects that don't have a \`Dockerfile\`, nor a \`package.json\` as a static deployment.
18 |
19 | Deploying such a static project is still as easy as running a single command:
20 |
21 | ${now}
22 |
23 | ## Under the Hood
24 |
25 | The technology behind our servers is a Node.js module called [serve](https://github.com/zeit/serve), which you can download, fork, extend and even operate locally during development.
26 |
27 | What does this mean for your team and your business? Great user experience with zero lock-in.
28 |
29 | If you can’t wait for us to add a certain capability to our static deployments support, you can just create a \`package.json\` like this:
30 |
31 | ${
32 | {`{
33 | "name": "extensible",
34 | "scripts": {
35 | "start": "serve ."
36 | },
37 | "dependencies": {
38 | "serve": "latest"
39 | }
40 | }`}
41 | }
42 |
43 | Then run \`now\`, and we will detect the presence of \`package.json\` and deploy it as a \`npm\` deployment.
44 |
45 | ## Behavior
46 |
47 | - If a ${index.html} file exists, it will be rendered
48 | - If only a single file was uploaded, the deployment URL will respond with it directly (you can
49 | still access it under its original path - e.g.: ${/image.png})
50 | - When uploading multiple files, a directory listing will be displayed
51 |
52 | ### Deployment Inactivity
53 |
54 | Old deployments always stay around forever if you don't remove them using \`now remove\`.
55 |
56 | However, the new static deployments, without the \`package.json\` are **never** put to sleep but are always quickly accessible.
57 | `)
58 |
--------------------------------------------------------------------------------
/pages/docs/getting-started/environment-variables.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { arunoda } from '../../../lib/data/team'
5 | import { TerminalInput } from '../../../components/text/terminal'
6 | import { Code } from '../../../components/text/code'
7 | import { InternalLink } from '../../../components/text/link'
8 | import Now from '../../../components/now/now'
9 |
10 | // prettier-ignore
11 | export default withDoc({
12 | title: 'Environment Variables',
13 | date: '6 August 2017',
14 | authors: [arunoda],
15 | editUrl: 'pages/docs/getting-started/environment-variables.js',
16 | })(markdown(components)`
17 |
18 | Almost every app needs to get configurations at runtime. These configurations could be anything, including:
19 |
20 | * Database connection details
21 | * Third-party API keys
22 | * Different customization parameters
23 |
24 | The best way to expose these configurations is to do so with [environment variables](https://en.wikipedia.org/wiki/Environment_variable), which is a universally available method that works across various programming languages, operating systems and hosting providers.
25 |
26 | Exposing environment variables with ${} is easy.
27 |
28 | ## Via CLI
29 |
30 | You can expose environment variables with the \`-e\` flag.
31 |
32 | ${now -e MONGO_URL="user:password@mydb.com" -e MY_API_TOKEN="XXXXX"}
33 |
34 | You can then access them inside your app.
35 | If your app is a Node.js app, here's how you can do that:
36 |
37 | ${{`const { MONGO_URL, MY_API_TOKEN } = process.env`}}
38 |
39 | ## Via “now.json”
40 |
41 | You can also expose these environment variables with [now.json](https://zeit.co/docs/features/configuration). For that, create a file named \`now.json\` inside your app root and add environment variables like this:
42 |
43 | ${
44 | {`{
45 | "env": {
46 | "MONGO_URL": "user:password@mydb.com",
47 | "MY_API_TOKEN": "XXXXX"
48 | }
49 | }`}
50 | }
51 |
52 | After that, \`now\` will use above environment variables when you deploy your app.
53 |
54 | > It's not a good idea to commit the \`now.json\` file to [Git](https://en.wikipedia.org/wiki/Git) if it contains secret information. For that, consider using ${{} Secrets}.
55 |
56 | `)
57 |
--------------------------------------------------------------------------------
/pages/docs/getting-started/logs.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import asset from 'next/asset'
3 | import withDoc, { components } from '../../../lib/with-doc'
4 |
5 | import { arunoda } from '../../../lib/data/team'
6 | import { TerminalInput } from '../../../components/text/terminal'
7 | import Image from '../../../components/image'
8 | import Now from '../../../components/now/now'
9 |
10 | // prettier-ignore
11 | export default withDoc({
12 | title: 'Logs',
13 | date: '4 August 2017',
14 | authors: [arunoda],
15 | editUrl: 'pages/docs/getting-started/logs.js',
16 | })(markdown(components)`
17 |
18 | Logs are important because it allows you to see what's happening inside the app, especially when a crisis happens. ${} keeps logs of all of your deployments and allows you to search them.
19 |
20 | Let's have a look at how you can access logs.
21 |
22 | ## Via CLI
23 |
24 | Accessing logs via the \`now\` CLI is simple as invoking this command:
25 |
26 | ${now logs [deployment-url]}
27 |
28 | You can also use the domain name of your app to search logs:
29 |
30 | ${now logs my-web-app.com}
31 |
32 | For more information on \`now logs\`, run the help command with:
33 |
34 | ${now logs --help}
35 |
36 | ${
37 |
43 | }
44 |
45 | Here's an advance \`now logs\` command to let you inspect the last 10 HTTP GET requests.
46 |
47 | ${now logs -a -q "GET" -n 10 my-web-app.com}
48 |
49 | ${
50 |
56 | }
57 |
58 | ## Via Dashboard
59 |
60 | You can also access and search logs via your web dashboard at [https://zeit.co/dashboard](https://zeit.co/dashboard).
61 | Click any of your deployment URLs inside the dashboard and start searching logs.
62 |
63 | > You may need to click the "Logs" link on the header (top right) to see logs.
64 |
65 | ${
66 |
72 | }
73 |
74 | `)
75 |
--------------------------------------------------------------------------------
/components/text/link.js:
--------------------------------------------------------------------------------
1 | // Packages
2 | import NativeLink from 'next/link'
3 | import PropTypes from 'prop-types'
4 |
5 | export const GenericLink = props => {
6 | if (props.href.startsWith('/')) {
7 | return
8 | }
9 |
10 | if (props.href.includes('@') || props.href.startsWith('#')) {
11 | return
12 | }
13 |
14 | return
15 | }
16 |
17 | export const InternalLink = ({ href, as, children, darkBg }) => (
18 |
19 |
20 | {children}
21 |
22 |
44 |
45 |
46 | )
47 |
48 | InternalLink.contextTypes = {
49 | darkBg: PropTypes.bool
50 | }
51 |
52 | export const AnchorLink = ({ href, onClick, children }) => (
53 |
54 | {children}
55 |
56 |
69 |
70 | )
71 |
72 | export const ExternalLink = ({ href, children }, { darkBg } = {}) => (
73 |
79 | {children}
80 |
81 |
98 |
99 | )
100 |
101 | ExternalLink.contextTypes = {
102 | darkBg: PropTypes.bool
103 | }
104 |
--------------------------------------------------------------------------------
/pages/docs/other/support-channels.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { sergio } from '../../../lib/data/team'
5 |
6 | // prettier-ignore
7 | export default withDoc({
8 | title: 'Support Channels',
9 | date: '21 Jul 2017',
10 | authors: [sergio],
11 | editUrl: 'pages/docs/other/support-channels.js',
12 | })(markdown(components)`
13 | We have a few support channels you can use to clarify doubts and solve issues.
14 |
15 | ## Platform Status
16 | Check our [Twitter status account](https://twitter.com/zeit_status) and our [status page](https://zeit-status.co/) to verify if the platform have some issue at the moment.
17 |
18 | ## Documentation
19 | Check the [documentation](/docs), here we have a lot of information about how you can use the CLI and the platform, and we have project examples and integration with third-party services
20 |
21 | ### API Documentation
22 | We also have a [documentation for our API](https://zeit.co/api). If you want to build something on top of our platform you will find a lot of information about it there.
23 |
24 | ## GitHub
25 | We have many [GitHub repositories](https://github.com/zeit) for almost every service or product we have. You can create issues in that repositories and the team and the community will help you as soon as possible. Some repositories you can access are [now-cloud](https://github.com/zeit/now-cloud), [now-cli](https://github.com/zeit/now-cli), [now-desktop](https://github.com/zeit/now-desktop), [now-client](https://github.com/zeit/now-client), [next.js](https://github.com/zeit/next.js), [hyper](https://github.com/zeit/hyper), [pkg](https://github.com/zeit/pkg), [micro](https://github.com/zeit/micro) and [more](https://github.com/zeit).
26 |
27 | ## zeit.chat
28 | Our community's Slack, there you can ask for help and either the community and the ZEIT Team will answer and help you solve any doubt you could have. You can access to it going to [zeit.chat](https://zeit.chat).
29 |
30 | ## Twitter
31 | You can use Twitter to send us a DM or mention to [@zeithq](https://twitter.com/zeithq) and a team member will contact you and help you with anything.
32 |
33 | ## Email
34 | The last but not least support channel is our [support@zeit.co](mailto:support@zeit.co) email. If you have very custom questions or related to private information (eg. billing issues) you don't want to share in Slack or you like more to use email you can contact us and we happily will help you as far as we could.
35 | `)
36 |
--------------------------------------------------------------------------------
/pages/docs/features/private-npm.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import asset from 'next/asset'
3 | import withDoc, { components } from '../../../lib/with-doc'
4 |
5 | import { rase, leo } from '../../../lib/data/team'
6 | import Now from '../../../components/now/now'
7 | import { InternalLink } from '../../../components/text/link'
8 | import { Code } from '../../../components/text/code'
9 | import { TerminalInput } from '../../../components/text/terminal'
10 | import Image from '../../../components/image'
11 |
12 | // prettier-ignore
13 | export default withDoc({
14 | title: 'Using Private npm Dependencies',
15 | date: '12 Mar 2017',
16 | authors: [rase, leo],
17 | editUrl: 'pages/docs/features/private-npm.js',
18 | })(markdown(components)`
19 |
20 | If your application is using projects with dependencies hosted in private npm scopes, you can deploy such with - true to our style - just one command (and a flag):
21 |
22 | ${now --forward-npm}
23 |
24 | This command will forward your npm credentials during the build process to fetch the required modules. Here's a little video of this feature in action, using a scoped private module in \`package.json\`:
25 |
26 | ${
27 |
32 | }
33 |
34 | ## Config Property
35 |
36 | If want to forward your [npm](https://npmjs.com/) credentials every time you create a new deployment using now, you can set the \`forwardNpm\` property inside your global \`~/.now.json\` file to \`true\`:
37 |
38 | ${
39 |
40 | {`{
41 | "forwardNpm": true
42 | }`}
43 |
44 | }
45 |
46 | You can read more about how to configure ${} to your needs ${here}.
47 |
48 | ## Why?
49 |
50 | [npm](https://npmjs.com/) makes it so radically easy to manage your organization's code. Sharing lots of small modules that do one thing well can make your team vastly more productive and your code easier to maintain and iterate on.
51 |
52 | To find out more about their plans visit [their website](https://npmjs.com/features).
53 |
54 | We're committed to giving you the best experience when deploying as an individual or in a team, and we hope this feature enhances that.
55 |
56 | ## Enterprise Support
57 |
58 | Neither the \`--forward-npm\` flag, nor the \`forwardNpm\` config property support npm's [enterprise plans](https://www.npmjs.com/enterprise) or packages hosted on a custom infrastructure at the moment. But don't worry, we're already working on it!
59 | `)
60 |
--------------------------------------------------------------------------------
/components/api/sections/api-basics/types.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import React from 'react'
3 | import Section, { components } from '../../section'
4 | import { ExternalLink } from '../../../text/link'
5 | import { Table, Row, Cell, BoldCell, FullWidthCell } from '../../table'
6 | import { InlineCode } from '../../../text/code'
7 | import immutable from '../../../../lib/immutable-component'
8 |
9 | function Types() {
10 | return (
11 |
21 | Name
22 | Definition
23 | Example
24 |
25 | }>
26 |
27 | ID
28 | A unique value used to identify resources.
29 | "V0fra8eEgQwEpFhYG2vTzC3K"
30 |
31 |
32 | String
33 | A string is a sequence of characters used to represent text.
34 | "ZEIT"
35 |
36 |
37 | Integer
38 | An integer is a number without decimals.
39 | 1234
40 |
41 |
42 | Float
43 | A float is a number with decimals.
44 | 12.34
45 |
46 |
47 | Map
48 | A data structure with a list of values assigned to a unique key.
49 | {`{ "service": "ZEIT" }`}
50 |
51 |
52 | List
53 | A data structure with only a list of values separated by a comma.
54 | ["ZEIT", 1234, 12.34]
55 |
56 |
57 | Enum
58 | A enum is a String with only a few possible valid values.
59 | "NPM" | "DOCKER"
60 |
61 |
62 | Date
63 | A String representing a date with the ISO 8601 format.
64 | "2018-09-03T19:48:46.555Z"
65 |
66 | }
67 | `
68 | ]
69 | ]
70 | }
71 | />
72 | )
73 | }
74 |
75 | export default immutable(Types)
76 |
--------------------------------------------------------------------------------
/pages/docs/other/billing.js:
--------------------------------------------------------------------------------
1 | // Packages
2 | import markdown from 'markdown-in-js'
3 |
4 | // Components
5 | import { InlineCode } from '../../../components/text/code'
6 |
7 | // Utilities
8 | import withDoc, { components } from '../../../lib/with-doc'
9 | import { leo } from '../../../lib/data/team'
10 |
11 | // prettier-ignore
12 | export default withDoc({
13 | title: 'Billing',
14 | date: '21 Jul 2017',
15 | authors: [leo],
16 | editUrl: 'pages/docs/other/billing.js',
17 | })(markdown(components)`
18 | This page describes the part of our platform
19 | that is responsible for payments, subscriptions and
20 | billing as specified in your plan.
21 |
22 | ## Failed Payments
23 |
24 | In the cases in which our system isn't able to charge
25 | your supplied payment method in the specified cycle (see
26 | our [Pricing](/pricing) page), it will firstly
27 | notify you about what happened and how you can fix it.
28 |
29 | This means that you'll receive a few emails containg
30 | details about how to update your billing information
31 | and why you couldn't be charged. The last email
32 | will be especially outstanding in terms of attracting
33 | your attention.
34 |
35 | In the case that you don't react to any of those
36 | emails, your subscription and
37 | associated resources will be suspended and you'll
38 | receive another email containg exactly that information
39 | and what you can do to activate
40 | your subscription again.
41 |
42 | At this point, if you haven't taken any action, you
43 | won't be able to access any platform features (like
44 | deployments, domains or certificates) anymore:
45 |
46 | - Deployments will return the status code ${402} and
47 | a page letting you know about the failed payment. This message
48 | can be seen by anyone trying to access the deloyment.
49 |
50 | - In addition to returning the error message, deployments
51 | will be scaled to 0 running instances. No code will
52 | be executed anymore.
53 |
54 | - API requests using a token issued by the account whose
55 | subscription was suspended will result in a JSON response
56 | with the ${error.code} property
57 | set to ${payment_required}.
58 |
59 | To prevent all of this from happening, please ensure
60 | that your specified payment method is always ready to be
61 | charged.
62 |
63 | In addition to that, it would also be a
64 | great advantage to ensure that emails from our platform
65 | don't land in your spam folder or get filtered out
66 | as junk (they're being sent by an address
67 | ending with ${@zeit.co}).
68 | `)
69 |
--------------------------------------------------------------------------------
/pages/docs/examples/travis.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 | import { devisscher } from '../../../lib/data/team'
4 | import { TerminalInput } from '../../../components/text/terminal'
5 | import { Code } from '../../../components/text/code'
6 |
7 | // prettier-ignore
8 | export default withDoc({
9 | title: 'Automate Deployment with Travis CI',
10 | date: '04 November 2017',
11 | authors: [devisscher],
12 | editUrl: 'pages/docs/examples/travis.js',
13 | })(markdown(components)`
14 |
15 | You might want to automate your Now deployments. Here is how you can achieve this by using Git and Travis. Every time you push or merge to the master branch a new build and deployment is initiated in Travis CI.
16 |
17 | 1. You need to get a [token](https://zeit.co/account/tokens) from Zeit. Go to the tokens page of your dashboard, under Account Settings, Tokens. Enter the name of the Token (e.g. Travis CI) and hit enter. A new token will be created which you can copy to your clipboard by clicking Copy.
18 | 2. Create a .travis.yml file in the root of your project.
19 | 3. Generate a secure variable for your Zeit token by running the following command with the token you obtained from your Zeit account. (You need to install [The Travis Client](https://github.com/travis-ci/travis.rb#installation)):
20 |
21 | ${travis encrypt -r username/repo NOW_TOKEN=xxxxxxxxxxxxxxxxxxxxxxx --add}
22 |
23 | 4. Now open your .travis.yml file and add the following:
24 |
25 | ${
26 | {
27 | `language: node_js
28 | node_js:
29 | - "node"
30 | cache: npm
31 | script: npm run deploy
32 | after_script: npm run alias
33 | env:
34 | global:
35 | secure:
36 | `}
37 | }
38 |
39 | 5. Open your package.json file and add the following information, tailored to your site information. This is used to run the alias command and point your domain to the correct deployment (You could also put this in a [now.json](
40 | https://zeit.co/blog/now-json) file):
41 |
42 | ${
43 | {`{
44 | ...
45 | "now": {
46 | "name": "example",
47 | "alias": "example.com
48 | }
49 | ...
50 | }`}}
51 |
52 | 6. Also add the following 2 scripts to the script property in your package.json file. These are used in your Travis config. The first is to deploy and the second is used to alias your latest deploy:
53 |
54 | ${
55 | {`{
56 | ...
57 | "scripts": {
58 | ...
59 | "deploy": "now -e NODE_ENV=production --token $NOW_TOKEN --npm",
60 | "alias": "now alias --token=$NOW_TOKEN"
61 | }
62 | }
63 | }`}
64 |
65 | }
66 |
67 | 7. Test it out by committing your code to Github. Check out your [travis-ci.org](https://travis-ci.org) build feed.
68 |
69 | `)
70 |
--------------------------------------------------------------------------------
/lib/fetch-api.js:
--------------------------------------------------------------------------------
1 | // Packages
2 | import fetch from 'isomorphic-unfetch'
3 | import retry from 'async-retry'
4 | import { parse as parseContentType } from 'content-type'
5 |
6 | // Helpers
7 | import env from './env'
8 |
9 | const API_URL = env.API_URL || 'https://zeit.co'
10 | const NETWORK_ERR_CODE = 'network_error'
11 | const NETWORK_ERR_MESSAGE = 'A network error has occurred. Please retry'
12 |
13 | const isServer = typeof window === 'undefined'
14 | const agents = new Map()
15 |
16 | export default async function fetchAPI(path, token = null, opts = {}) {
17 | const headers = opts.headers || {}
18 |
19 | if (token) {
20 | headers.Authorization = `bearer ${token}`
21 | }
22 |
23 | // accept path to be a full url or a relative path
24 | const url = path[0] === '/' ? API_URL + path : path
25 | let agent
26 |
27 | if (isServer) {
28 | const { parse } = require('url')
29 | const { protocol } = parse(url)
30 | if (protocol) {
31 | agent = getAgent(protocol)
32 | }
33 | }
34 |
35 | return retry(
36 | async bail => {
37 | let res, data, err
38 |
39 | try {
40 | res = await fetch(url, { ...opts, headers, agent })
41 | if (opts.throwOnHTTPError && (res.status < 200 || res.status >= 300)) {
42 | const { type } = parseContentType(res.headers.get('Content-Type'))
43 | if (type === 'application/json') {
44 | data = await res.json()
45 | err = new Error(
46 | data.error == null ? 'Unexpected Error' : data.error.message
47 | )
48 | err.res = res
49 | err.status = res.status
50 | // TODO: remove this hack https://github.com/zeit/front/issues/553
51 | err.code = data.error == null ? res.status : data.error.code
52 | } else {
53 | // handle it below as network error
54 | throw new Error('Unexpected response content-type: ' + type)
55 | }
56 | } else {
57 | data = await res.json()
58 | }
59 | } catch (e) {
60 | err = isServer ? e : new Error(NETWORK_ERR_MESSAGE + ` (${url})`)
61 | err.code = NETWORK_ERR_CODE
62 | err.res = null
63 | err.status = null
64 | }
65 |
66 | if (!err) return data
67 | if (err.status < 500) return bail(err)
68 | throw err
69 | },
70 | { retries: 3, maxTimeout: 2500 }
71 | )
72 | }
73 |
74 | const getAgent = protocol => {
75 | if (!agents.has(protocol)) {
76 | const http = require('http')
77 | const https = require('https')
78 | const module = protocol === 'https:' ? https : http
79 | const opts = {
80 | keepAlive: true,
81 | keepAliveMsecs: 10000,
82 | maxSockets: 100
83 | }
84 | const agent = new module.Agent(opts)
85 | agents.set(protocol, agent)
86 | }
87 |
88 | return agents.get(protocol)
89 | }
90 |
--------------------------------------------------------------------------------
/components/text/terminal.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import { GenericLink } from './link'
4 |
5 | export const TerminalInput = ({ children }, { darkBg = false }) => (
6 |
91 | )
92 | }
93 | }
94 |
95 | export const TerminalLink = props => (
96 |
97 |
98 |
105 |
106 | )
107 |
--------------------------------------------------------------------------------
/deploy-server/deploy.js:
--------------------------------------------------------------------------------
1 | const cp = require('child_process')
2 | const { resolve } = require('path')
3 | const fs = require('mz/fs')
4 | const GitHubApi = require('github')
5 | const jwt = require('jsonwebtoken')
6 | const logger = console
7 |
8 | const { ZEIT_TOKEN, GH_KEY } = process.env
9 |
10 | module.exports = async (pullRequestId, tarballName) => {
11 | // Extract the static app
12 | logger.log(`${pullRequestId}=> moving the tarball`)
13 | await fs.mkdir(`/tmp/${tarballName}`)
14 | await fs.rename(
15 | `/tmp/${tarballName}.tar.gz`,
16 | `/tmp/${tarballName}/app.tar.gz`
17 | )
18 |
19 | const execOptions = {
20 | cwd: `/tmp/${tarballName}`
21 | }
22 |
23 | logger.log(`${pullRequestId}=> extracting the tarball`)
24 | await exec('tar xzf app.tar.gz', execOptions)
25 |
26 | // Deploy it to now
27 | const nowPath = resolve(__dirname, 'node_modules/.bin/now')
28 |
29 | logger.log(`${pullRequestId}=> deploy the app`)
30 | const nowApp = await exec(`${nowPath} -p -n zeit-docs -t ${ZEIT_TOKEN}`, {
31 | cwd: `${execOptions.cwd}/out`
32 | })
33 |
34 | const deployUrl = nowApp.stdout
35 |
36 | // Add a GH comment
37 | const github = new GitHubApi({
38 | protocol: 'https',
39 | headers: {
40 | 'user-agent': 'ZEIT-docs-deployer'
41 | },
42 | Promise,
43 | followRedirects: true,
44 | timeout: 5000
45 | })
46 |
47 | const key = Buffer.from(GH_KEY, 'base64').toString('utf8')
48 | logger.log(`${pullRequestId}=> get the github token`)
49 | const token = await getToken(github, key, 3412, 36421)
50 |
51 | github.authenticate({
52 | type: 'token',
53 | token
54 | })
55 |
56 | logger.log(`${pullRequestId}=> create the deploy comment`)
57 | await github.issues.createComment({
58 | owner: 'zeit',
59 | repo: 'docs',
60 | number: pullRequestId,
61 | body: `You can view the modified docs at: ${deployUrl}/docs`
62 | })
63 |
64 | await exec(`rm -rf ${execOptions.cwd}`)
65 | }
66 |
67 | function exec(command, options = {}) {
68 | return new Promise((done, failed) => {
69 | cp.exec(command, options, (error, stdout, stderr) => {
70 | if (error) {
71 | error.stdout = stdout
72 | error.stderr = stderr
73 | failed(error)
74 | return
75 | }
76 |
77 | done({ stdout, stderr })
78 | })
79 | })
80 | }
81 |
82 | async function getToken(github, key, appId, installationId) {
83 | // Create the JWT token
84 | const now = Math.ceil(Date.now() / 1000)
85 | const jwtPayload = {
86 | iat: now,
87 | exp: now + 8 * 60,
88 | iss: appId
89 | }
90 | const token = jwt.sign(jwtPayload, key, { algorithm: 'RS256' })
91 |
92 | github.authenticate({
93 | type: 'integration',
94 | token
95 | })
96 |
97 | // Get the real github token
98 | const tokenInfo = await github.integrations.createInstallationToken({
99 | installation_id: installationId
100 | })
101 |
102 | return tokenInfo.data.token
103 | }
104 |
--------------------------------------------------------------------------------
/pages/docs/guides/updating-now-cli.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import asset from 'next/asset'
3 | import withDoc, { components } from '../../../lib/with-doc'
4 |
5 | import { leo } from '../../../lib/data/team'
6 | import Image from '../../../components/image'
7 | import {
8 | TerminalOutput,
9 | TerminalInput
10 | } from '../../../components/text/terminal'
11 |
12 | const updateMessage = {
13 | color: 'white',
14 | background: '#FF0000',
15 | padding: '1px 3px'
16 | }
17 |
18 | // prettier-ignore
19 | export default withDoc({
20 | title: 'Updating Now CLI',
21 | date: '20 Jan 2018 11:34 AM PDT',
22 | authors: [ leo ],
23 | editUrl: 'pages/docs/guides/updating-now-cli.js',
24 | })(markdown(components)`
25 |
26 | If there is a new release
27 | of [Now CLI](https://zeit.co/download#now-cli) available, you will
28 | see a message similiar to this one appear in your terminal output:
29 |
30 | ${UPDATE AVAILABLE The latest version of Now CLI is 8.4.0}
31 |
32 | This indicates that it is time to update your local instance of
33 | Now CLI. To make this as easy as possible, we have put together this
34 | guide for you.
35 |
36 | In order to know which action is the right one for you to take, you
37 | firstly need to ask yourself these questions:
38 |
39 | ## Is Now Desktop Installed and Running?
40 |
41 | If that is the case, you do not need to do anything – other than
42 | ensuring this option is marked as enabled in [Now Desktop](/download):
43 |
44 | ${}
49 |
50 | As long as that is the case, you will automatically receive
51 | the latest update for Now CLI once a new release comes out.
52 |
53 | ## Did You Install Now CLI Manually?
54 |
55 | Firstly, you need to determine whether or not the instance
56 | of Now CLI intalled on your device is a [canary release](/blog/canary) or
57 | not by running this command:
58 |
59 | ${now --version}
60 |
61 | If the output looks similiar to this (contains "canary", the exact version
62 | does not need to match), you can safely
63 | assume it is a canary release:
64 |
65 | ${10.0.0-canary.14}
66 |
67 | Now that you know which release channel you are
68 | using, you can pick the right way to update depending
69 | on where you installed it from:
70 |
71 | - [npm](#npm)
72 | - [yarn](#yarn)
73 |
74 | ---
75 |
76 | ## npm
77 |
78 | For the latest **stable update**, run this command:
79 |
80 | ${npm install -g now}
81 |
82 | To get the latest **canary update**, however, run this:
83 |
84 | ${npm install -g now@canary}
85 |
86 | ## yarn
87 |
88 | For the latest **stable update**, run this command:
89 |
90 | ${yarn global add now}
91 |
92 | To get the latest **canary update**, however, run this:
93 |
94 | ${yarn global add now@canary}
95 | `)
96 |
--------------------------------------------------------------------------------
/lib/data/last-edited.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages/docs/deployment-types/docker.js": "2018-02-14T17:18:59.026Z",
3 | "pages/docs/deployment-types/index.js": "2018-01-16T14:29:40.648Z",
4 | "pages/docs/deployment-types/lifecycle.js": "2018-01-16T14:29:40.648Z",
5 | "pages/docs/deployment-types/node.js": "2018-02-14T17:18:59.027Z",
6 | "pages/docs/deployment-types/static.js": "2018-01-31T22:23:56.375Z",
7 | "pages/docs/examples/chat.js": "2018-02-14T17:18:59.027Z",
8 | "pages/docs/examples/create-react-app.js": "2018-01-31T22:23:56.376Z",
9 | "pages/docs/examples/graphql.js": "2018-02-14T17:18:59.028Z",
10 | "pages/docs/examples/index.js": "2018-01-16T14:29:40.650Z",
11 | "pages/docs/examples/json-api.js": "2018-02-14T17:18:59.029Z",
12 | "pages/docs/examples/next.js": "2018-02-14T17:18:59.029Z",
13 | "pages/docs/examples/redirect.js": "2018-02-14T17:18:59.030Z",
14 | "pages/docs/examples/slack-slash.js": "2018-02-14T17:18:59.030Z",
15 | "pages/docs/examples/static.js": "2018-02-14T17:18:59.031Z",
16 | "pages/docs/examples/travis.js": "2018-01-31T22:23:56.379Z",
17 | "pages/docs/features/aliases.js": "2018-02-14T17:18:59.031Z",
18 | "pages/docs/features/certs.js": "2018-01-31T22:23:56.380Z",
19 | "pages/docs/features/configuration.js": "2018-02-14T17:18:59.032Z",
20 | "pages/docs/features/dns.js": "2018-01-31T22:23:56.381Z",
21 | "pages/docs/features/env-and-secrets.js": "2018-01-31T22:23:56.381Z",
22 | "pages/docs/features/index.js": "2018-01-16T14:29:40.653Z",
23 | "pages/docs/features/now-cli.js": "2018-01-31T22:23:56.382Z",
24 | "pages/docs/features/path-aliases.js": "2018-01-31T22:23:56.382Z",
25 | "pages/docs/features/private-npm.js": "2018-02-14T17:18:59.033Z",
26 | "pages/docs/features/repositories.js": "2018-02-14T17:18:59.033Z",
27 | "pages/docs/features/zero-downtime-migration.js": "2018-01-16T14:29:40.655Z",
28 | "pages/docs/getting-started/assign-a-domain-name.js": "2018-02-14T17:18:59.034Z",
29 | "pages/docs/getting-started/deployment.js": "2018-02-14T17:18:59.034Z",
30 | "pages/docs/getting-started/environment-variables.js": "2018-01-31T22:23:56.385Z",
31 | "pages/docs/getting-started/five-minute-guide-to-now.js": "2018-02-14T17:18:59.035Z",
32 | "pages/docs/getting-started/index.js": "2018-01-16T14:29:40.657Z",
33 | "pages/docs/getting-started/logs.js": "2018-02-14T17:18:59.035Z",
34 | "pages/docs/getting-started/scaling.js": "2018-02-14T17:18:59.036Z",
35 | "pages/docs/getting-started/secrets.js": "2018-02-14T17:18:59.036Z",
36 | "pages/docs/getting-started/whats-next.js": "2018-02-14T17:18:59.037Z",
37 | "pages/docs/guides/app-lifecycle-and-scalability.js": "2018-02-14T17:18:59.038Z",
38 | "pages/docs/guides/how-to-use-cloudflare.js": "2018-02-14T17:18:59.039Z",
39 | "pages/docs/guides/index.js": "2018-01-16T14:29:40.658Z",
40 | "pages/docs/guides/migrate-your-app.js": "2018-01-31T22:23:56.388Z",
41 | "pages/docs/guides/redirect.js": "2018-02-14T17:18:59.039Z",
42 | "pages/docs/guides/updating-now-cli.js": "2018-02-14T17:18:59.040Z",
43 | "pages/docs/index.js": "2018-01-20T15:29:17.000Z",
44 | "pages/docs/other/billing.js": "2018-02-14T17:18:59.040Z",
45 | "pages/docs/other/faq.js": "2018-02-14T17:18:59.041Z",
46 | "pages/docs/other/index.js": "2018-01-16T14:29:40.659Z",
47 | "pages/docs/other/support-channels.js": "2018-02-14T17:18:59.041Z"
48 | }
--------------------------------------------------------------------------------
/components/heading.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PermalinkIcon from './permalink-icon'
3 |
4 | class Heading extends React.Component {
5 | render() {
6 | const { component, className, children, ...rest } = this.props
7 | return React.cloneElement(
8 | component,
9 | {
10 | className: [className, component.props.className || ''].join(' '),
11 | ...rest
12 | },
13 | children
14 | )
15 | }
16 | }
17 |
18 | export default props => {
19 | const { offsetTop } = props
20 | const component = props.children
21 | const children = component.props.children || ''
22 |
23 | let id = props.id
24 | let text = children
25 |
26 | if (null == id) {
27 | // If there are sub components, convert them to text
28 | if (Array.isArray(children)) {
29 | text = children
30 | .map(child => {
31 | return typeof child === 'object' ? child.props.children : child
32 | })
33 | .join('')
34 | }
35 |
36 | id = text
37 | .toLowerCase()
38 | .replace(/\s/g, '-')
39 | .replace(/[?!]/g, '')
40 | }
41 |
42 | const targetStyle =
43 | null != offsetTop
44 | ? { marginTop: -offsetTop + 'px', paddingTop: offsetTop + 'px' }
45 | : null
46 | return (
47 |
52 |
53 | {children}
54 |
55 |
56 |
57 |
112 |
113 | )
114 | }
115 |
--------------------------------------------------------------------------------
/components/api/sections/errors/generic.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import Section, { components } from '../../section'
3 | import { Code, InlineCode } from '../../../text/code'
4 | import immutable from '../../../../lib/immutable-component'
5 |
6 | function Generic() {
7 | return (
8 | Is similar to the HTTP 403 Forbidden error.
26 | `,
27 | markdown(components)`
28 | ${{`{
29 | "error": {
30 | "code": "forbidden",
31 | "message": "Not authorized"
32 | }
33 | }`}}
34 | `
35 | ],
36 | [
37 | markdown(components)`
38 | ### Rate Limited
39 | `
40 | ],
41 | [
42 | markdown(components)`
43 | You exceeded the maximum alloted requests.
44 |
45 | The limit of request is per endpoint basis so you could continue using another endpoints even if some of them give you this error.
46 | `,
47 | markdown(components)`
48 | ${{`{
49 | "error": {
50 | "code": "rate_limited",
51 | "message": "Rate limit exceeded",
52 | }
53 | }`}}
54 | `
55 | ],
56 | [
57 | markdown(components)`
58 | ### Bad Request
59 | `
60 | ],
61 | [
62 | markdown(components)`
63 | There was an error with the request, the ${error.message} would contain information about the issue.
64 |
65 | `,
66 | markdown(components)`
67 | ${{`{
68 | "error": {
69 | "code": "bad_request",
70 | "message": "An english description of the error that just occurred",
71 | }
72 | }`}}
73 | `
74 | ],
75 | [
76 | markdown(components)`
77 | ### Internal Server Error
78 | `
79 | ],
80 | [
81 | markdown(components)`
82 | This errors is similar to the HTTP 500 Internal Server Error error code.
83 |
84 | `,
85 | markdown(components)`
86 | ${{`{
87 | "error": {
88 | "code": "internal_server_error",
89 | "message": "An unexpected internal error occurred"
90 | }
91 | }`}}
92 | `
93 | ],
94 | [
95 | markdown(components)`
96 | ### Resource Not Found
97 | `
98 | ],
99 | [
100 | markdown(components)`
101 | The endpoint you're requesting doens't handle the method you defined. The error message will contain the methods the endpoint responds to.
102 |
103 | `,
104 | markdown(components)`
105 | ${{`{
106 | "error": {
107 | "code": "method_unknown",
108 | "message": "This endpoint only responds to METHOD"
109 | }
110 | }`}}
111 | `
112 | ],
113 | [
114 | markdown(components)`
115 | ### Method Unknown
116 | `
117 | ],
118 | [
119 | markdown(components)`
120 | The endpoint you're requesting doens't handle the method you defined. The error message will contain the methods the endpoint responds to.
121 |
122 | `,
123 | markdown(components)`
124 | ${{`{
125 | "error": {
126 | "code": "method_unknown",
127 | "message": "This endpoint only responds to METHOD"
128 | }
129 | }`}}
130 | `
131 | ]
132 | ]}
133 | />
134 | )
135 | }
136 |
137 | export default immutable(Generic)
138 |
--------------------------------------------------------------------------------
/pages/docs/guides/redirect.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { sergio } from '../../../lib/data/team'
5 | import { Code } from '../../../components/text/code'
6 | import { TerminalInput } from '../../../components/text/terminal'
7 |
8 | // prettier-ignore
9 | export default withDoc({
10 | title: 'Setting up a Redirect with Now',
11 | date: '5 Nov 2017',
12 | authors: [sergio],
13 | editUrl: 'pages/docs/guides/redirect.js'
14 | })(markdown(components)`
15 | You usually want your users to access your site with or without \`www\`. The best way to achieve this is to redirect all the traffic coming to the \`www\` domain to your app's naked domain.
16 |
17 | Here are a few example redirects:
18 |
19 | ${{`* https://www.mycompany.com -> https://mycompany.com
20 | * https://www.mycompany.com/about -> https://mycompany.com/about
21 | `}}
22 |
23 | You can also add two aliases to your app like below:
24 |
25 | ${{`now alias my-deployment-url.now.sh mycompany.com
26 | now alias my-deployment-url.now.sh www.mycompany.com
27 | `}}
28 |
29 | It will do the job, but search engines consider them as **duplicate** content. This is not good for SEO and it might confuse users as well.
30 |
31 | Therefore, \`www\` redirect is the best option. There are two ways to achieve that for your app.
32 |
33 | ## 1. Using now-examples/redirect
34 |
35 | Now we are going to deploy a [simple web app](https://github.com/now-examples/redirect) which receives all the \`www\` traffic and redirect them to your naked domain.
36 |
37 | To deploy this, run the following command:
38 | (Make sure to add a trailing slash to the redirect url as shown below.)
39 |
40 | ${now -e REDIRECT_URL=http://mycompany.com/ now-examples/redirect}
41 |
42 | Then, you will get a deployment url like this: \`https://now-redirect-otytioldup.now.sh\`.
43 |
44 | Now, alias that into your \`www\` domain like this:
45 |
46 | ${now alias https://now-redirect-otytioldup.now.sh www.mycompany.com}
47 |
48 | Now, all the \`www\` traffic will be forwarded to your naked domain (in this case \`mycompany.com\`).
49 |
50 | > You only need deploy this app once.
51 |
52 |
53 | ## 2. Redirect Inside Your App
54 |
55 | In this case, your app accepts \`www\` traffic and it will redirect them from your app. If you are using [Express](https://expressjs.com/) for your app, you can do something like this:
56 |
57 |
58 | ${{`function redirect(req, res, next) {
59 | // if the request doesn't come from mycompany.com or from the deployment URL
60 | if (req.hostname !== 'mycompany.com' || req.hostname !== process.env.NOW_URL) {
61 | // redirect to mycompany.com keeping the pathname and querystring
62 | return res.redirect(\`https://mycompany.com/\${req.originalUrl}\`);
63 | }
64 | return next(); // call the next middleware (or route)
65 | }
66 |
67 | // make Express use our redirect middleware
68 | app.use(redirect);
69 | `}}
70 |
71 | If you are using some other language or a different web server, you can implement a similar logic as shown above.
72 |
73 | ### Set up Aliases
74 |
75 | Now, add an additional [alias](/docs/getting-started/assign-a-domain-name) to receive \`www\` traffic into your app. If you are using [now.json](/docs/features/configuration), you can add two aliases like this:
76 |
77 | ${{`{
78 | "aliases": [
79 | "www.mycompany.com",
80 | "mycompany.com"
81 | ]
82 | }`}}
83 |
84 | Then, every time you run \`now alias\`, it will alias your app into both of your aliases.
85 | `)
86 |
--------------------------------------------------------------------------------
/pages/docs/getting-started/secrets.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import asset from 'next/asset'
3 | import withDoc, { components } from '../../../lib/with-doc'
4 |
5 | import { arunoda } from '../../../lib/data/team'
6 | import { TerminalInput } from '../../../components/text/terminal'
7 | import { Code } from '../../../components/text/code'
8 | import { InternalLink } from '../../../components/text/link'
9 | import Image from '../../../components/image'
10 | import Now from '../../../components/now/now'
11 |
12 | // prettier-ignore
13 | export default withDoc({
14 | title: 'Secrets',
15 | date: '6 August 2017',
16 | authors: [arunoda],
17 | editUrl: 'pages/docs/getting-started/secrets.js',
18 | })(markdown(components)`
19 |
20 | If multiple people deploy your app or utilize a CI service, it's a better idea to use ${now.json} to expose environment variables.
21 |
22 | However, adding that file to [Git](https://en.wikipedia.org/wiki/Git) could cause potential issues. Secrets like API tokens and DB information are visible to anyone who has access to the source code. That's bad.
23 |
24 | ## Now Secrets
25 |
26 | That's where ${} Secrets can help you. It's a configuration store that works across your account. Let's see how to use it:
27 |
28 | First, add some secrets:
29 |
30 | ${{`now secrets add my-app-mongo-url "user:password@mydb.com"
31 | now secrets add my-app-my-api-token "XXXXX"`}}
32 |
33 | Then, you can get these values inside environment variables.
34 | Here's how to do that with \`now.json\`:
35 |
36 | ${{`{
37 | "env": {
38 | "MONGO_URL": "@my-app-mongo-url",
39 | "MY_API_TOKEN": "@my-app-my-api-token"
40 | }
41 | }`}}
42 |
43 | That's it.
44 |
45 | This \`now.json\` file no longer contains secret information and it's safe to add that to Git and share with anyone. Only the people who can deploy the app has access to these secrets.
46 |
47 | ## Operations
48 |
49 | You can perform a few sets of operations with ${} Secrets, including adding, renaming and removing secrets. But you can't read secrets from the terminal.
50 |
51 | > **WARNING**:
52 | >
53 | >Anyone who can deploy to ${} has access to these secrets. Disabling the ability to read secrets in the terminal is simply a barrier.
54 | >
55 | >A user can still deploy a simple app to dump these secrets.
56 |
57 |
58 | You can get more information about ${} Secrets by running the following Help command:
59 |
60 | ${{`now secrets --help`}}
61 |
62 | ${
63 |
69 | }
70 |
71 | ## Secrets with New Lines
72 |
73 | Sometimes, you need to add secrets which has new lines (or any other special characters) in them (eg: certificates). But you won't be able to add them by simply using \`now secrets add\`.
74 |
75 | Instead, you can encode the secret into [Base64](https://en.wikipedia.org/wiki/Base64) before adding it. Here's how you could do that on Mac/Linux with a single command:
76 |
77 | ${{`now secrets add my-cert $(cat /path/to/cert | base64)`}}
78 |
79 | Before you use the secret inside your app, you need to decode it. Here's how you could do it in a Node.js app.
80 |
81 | ${{`const cert = Buffer.from(certFromtheSecret, 'base64').toString()`}}
82 |
83 | >Base64 is a simple encoding algorithm which is available everywhere.
84 | > That's why we've used it. But it's okay to choose any text based encoding algorithm.
85 |
86 | `)
87 |
--------------------------------------------------------------------------------
/components/api/sections/endpoints/authentication.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import Section, { components } from '../../section'
3 | import { Code, InlineCode } from '../../../text/code'
4 | import { ExternalLink, InternalLink } from '../../../text/link'
5 | import {
6 | InputTable,
7 | OutputTable,
8 | Row,
9 | Cell,
10 | TypeCell,
11 | BoldCell,
12 | BooleanCell
13 | } from '../../table'
14 | import pure from '../../../../lib/pure-component'
15 | import Endpoint from '../../endpoint'
16 | import Request from '../../request'
17 |
18 | function Authentication() {
19 | return (
20 | }
32 |
33 | Request a new login for an user to get a token.
34 |
35 | #### Input
36 | ${
37 |
38 | email
39 | String
40 |
41 | The user email.
42 |
43 |
44 | tokenName
45 | String
46 |
47 | The desired name for the token. It will be displayed on the user account details.
48 |
49 | }
50 |
51 | ### Output
52 | ${
53 |
54 | token
55 | String
56 | The token used to verify the user accepted the login request.
57 |
58 |
59 | securityCode
60 | String
61 | The code the user is going to receive on the email. Must be displayed to the user so he can verify the request is the correct.
62 |
63 | }
64 | `,
65 | markdown(components)`
66 | Example request:
67 |
68 | ${}
79 |
80 | Example response:
81 |
82 | ${{`{
83 | "token": "T1dmvPu36nmyYisXAs7IRzcR",
84 | "securityCode": "Practical Saola"
85 | }`}}
86 | `
87 | ],
88 | [
89 | markdown(components)`
90 | ### Verify login
91 | `
92 | ],
93 | [
94 | markdown(components)`
95 | ${}
96 |
97 | Verify the user accepted the login request and get a authentication token. The user email address and the token received after ${requesting the login} must be added to the URL as a query string with the names ${email} and ${token}.
98 |
99 | #### Output
100 | ${
101 |
102 | token
103 | String
104 | The user authentication token you can use as described in API Basics - Authentication.
105 |
106 | }
107 | `,
108 | markdown(components)`
109 | Example request:
110 |
111 | ${}
114 |
115 | Example response:
116 |
117 | ${{`{
118 | "token": "sGkHhSH98wtJB0lyODZJ2bRe"
119 | }`}}
120 | `
121 | ]
122 | ]
123 | }
124 | />
125 | )
126 | }
127 |
128 | export default pure(Authentication)
129 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "version": "5.2.1",
4 | "private": true,
5 | "scripts": {
6 | "dev": "node server.js",
7 | "build": "cross-env NODE_ENV=production next build",
8 | "export": "cross-env NODE_ENV=production next export",
9 | "start": "cross-env NODE_ENV=production node server.js",
10 | "lint": "eslint .",
11 | "lint:staged": "lint-staged",
12 | "test": "npm run lint",
13 | "deploy": "node scripts/deploy",
14 | "last:edited": "node scripts/last-edited && git add lib/data/last-edited.json"
15 | },
16 | "babel": {
17 | "presets": [
18 | "next/babel"
19 | ],
20 | "plugins": [
21 | [
22 | "transform-define",
23 | "./env-config.js"
24 | ],
25 | "markdown-in-js/babel"
26 | ]
27 | },
28 | "dependencies": {
29 | "@skidding/react-codemirror": "1.0.2",
30 | "async-retry": "1.1.4",
31 | "babel-plugin-transform-define": "1.3.0",
32 | "babel-runtime": "6.23.0",
33 | "codemirror": "5.31.0",
34 | "content-type": "1.0.4",
35 | "cookie": "0.3.1",
36 | "cross-env": "5.0.1",
37 | "date-fns": "1.29.0",
38 | "glob": "7.1.2",
39 | "glob-promise": "3.1.0",
40 | "htmlescape": "1.1.1",
41 | "intersection-observer": "0.4.2",
42 | "isomorphic-fetch": "2.2.1",
43 | "isomorphic-unfetch": "2.0.0",
44 | "js-cookie": "2.2.0",
45 | "jsonwebtoken": "7.4.1",
46 | "lodash.debounce": "4.0.8",
47 | "markdown-in-js": "1.1.3",
48 | "micro": "9.1.0",
49 | "mitt": "1.1.2",
50 | "next": "5.0.1-canary.3",
51 | "nprogress": "0.2.0",
52 | "prop-types": "15.5.8",
53 | "query-string": "4.3.4",
54 | "react": "16.1.1",
55 | "react-dom": "16.1.1",
56 | "scroll-into-view-if-needed": "1.1.0",
57 | "smoothscroll-polyfill": "0.3.5"
58 | },
59 | "devDependencies": {
60 | "babel-eslint": "7.2.3",
61 | "eslint": "4.2.0",
62 | "eslint-plugin-import-b5a962": "2.3.0",
63 | "eslint-plugin-react": "7.1.0",
64 | "lint-staged": "4.0.0",
65 | "pre-commit": "1.2.2",
66 | "prettier": "1.7.4",
67 | "shelljs": "0.7.8"
68 | },
69 | "lint-staged": {
70 | "*.js": [
71 | "eslint",
72 | "prettier --write --no-semi --single-quote",
73 | "git add"
74 | ]
75 | },
76 | "pre-commit": [
77 | "last:edited",
78 | "lint:staged"
79 | ],
80 | "greenkeeper": {
81 | "ignore": [
82 | "prettier"
83 | ]
84 | },
85 | "eslintConfig": {
86 | "parser": "babel-eslint",
87 | "parserOptions": {
88 | "ecmaVersion": 8,
89 | "sourceType": "module",
90 | "ecmaFeatures": {
91 | "jsx": true,
92 | "impliedStrict": true,
93 | "experimentalObjectRestSpread": true
94 | },
95 | "allowImportExportEverywhere": true
96 | },
97 | "plugins": [
98 | "react",
99 | "import-b5a962"
100 | ],
101 | "extends": [
102 | "eslint:recommended",
103 | "plugin:react/recommended"
104 | ],
105 | "globals": {
106 | "VERSION": true,
107 | "IMAGE_ASSETS_URL": true,
108 | "VIDEO_ASSETS_URL": true,
109 | "RAW_ASSETS_URL": true
110 | },
111 | "env": {
112 | "es6": true,
113 | "browser": true,
114 | "node": true
115 | },
116 | "rules": {
117 | "func-names": [
118 | "error",
119 | "as-needed"
120 | ],
121 | "no-shadow": "error",
122 | "import-b5a962/no-mutable-exports": "error",
123 | "import-b5a962/no-anonymous-default-export": [
124 | "error",
125 | {
126 | "allowArray": true,
127 | "allowArrowFunction": true,
128 | "allowLiteral": true,
129 | "allowObject": true
130 | }
131 | ],
132 | "no-extra-semi": 0,
133 | "react/prop-types": 0,
134 | "react/react-in-jsx-scope": 0,
135 | "react/no-unescaped-entities": 0,
136 | "react/jsx-no-target-blank": 0,
137 | "react/no-string-refs": 0
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/pages/docs/features/dns.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { hbp, leo } from '../../../lib/data/team'
5 | import Now from '../../../components/now/now'
6 | import { InternalLink } from '../../../components/text/link'
7 | import { TerminalInput } from '../../../components/text/terminal'
8 |
9 | // prettier-ignore
10 | export default withDoc({
11 | title: 'DNS Management',
12 | date: '15 Mar 2017',
13 | authors: [hbp, leo],
14 | editUrl: 'pages/docs/features/dns.js',
15 | })(markdown(components)`
16 |
17 |
18 | Thanks to the \`now dns\` CLI command, managing existing DNS records with ${} is simple.
19 |
20 | > However, this only applies to domains you bought via ${} or domains configured with our [global DNS service](/world).
21 |
22 | In the examples shown below, the placeholder \`zeit.rocks\` represents a domain of your choice that was registered with \`now domains\` or \`now alias\`. Here are the main sub-commands you can use:
23 |
24 | ### now dns ls
25 |
26 | Lists all the DNS records available for this domain. The list doesn't include records generated automatically by the nameserver (like a default \`SOA\` record or \`A / AAAA\` records created automatically for \`ALIAS\` records).
27 |
28 | ### now dns add
29 |
30 | Adds a DNS record to a domain of your choice. The following record types are currently supported:
31 |
32 | * A
33 | * AAAA
34 | * ALIAS
35 | * CAA
36 | * CNAME
37 | * MX
38 | * SRV
39 | * TXT
40 |
41 | This is the syntax for the \`now dns\` command.
42 |
43 | ${
44 |
45 | now dns add <domain> <name> <record type> <value> [mx_priority]
46 |
47 | }
48 |
49 | * \`\` is the domain name
50 | * \`\` is the subdomain that will be prefixed to \`\` (value \`@\` refers to a domain without any prefix)
51 | * \`\` contains one of the supported record types shown above
52 | * \`\` indicates the value for the record (like an IP address or a hostname)
53 | * \`[mx_priority]\` sets the priority of a certain MX record and can therefore only be used in conjunction with this record type
54 |
55 |
56 | **Examples**
57 |
58 | ${
59 |
60 | now dns add zeit.rocks ext A 127.0.0.1
61 |
62 | }
63 |
64 | Creates an A record that makes the subdomain \`ext.zeit.rocks\` resolve to the server located at the IP address \`127.0.0.1.\`
65 |
66 | ${
67 |
68 | now dns add zeit.rocks @ MX mail.awesome-now.us 10
69 |
70 | }
71 |
72 | Creates an MX record which makes the mail server located at \`mail.awesome-now.us\` responsible for handling emails sent to an address suffixed with \`@zeit.rocks\`.
73 |
74 | ${
75 |
76 | now dns add zeit.rocks @ CAA '0 issue "comodo.com"'
77 |
78 | }
79 |
80 | Creates a [CAA record](https://letsencrypt.org/docs/caa/) that allows to issue certificates using [Comodo](https://ssl.comodo.com/) for \`zeit.rocks\` and any sub domain under it.
81 |
82 | > In this case, you'll be in charge of certificate management for your domain.
83 | > Most probably, you'll need to use \`CAA\` records to:
84 | > 1. use a custom certificate for your ${} deployment with ${`now certs replace`}
85 | > 2. run an app outside of ${} with TLS for a sub domain
86 |
87 | ### now dns rm <ID>
88 |
89 | Removes a record by ID, which is shown in the \`now dns ls\` listing. Note that it may take a couple of hours before the change is fully propagated across our infrastructure.
90 |
91 | ## The API Endpoint
92 |
93 | As of [now-client](https://github.com/zeit/now-client) version **0.7.0**, it comes with API wrappers for managing the DNS records within your own application.
94 |
95 | The endpoint is called \`/domains/:domain/records\` and is available in our ${REST API}.
96 |
97 | `)
98 |
--------------------------------------------------------------------------------
/pages/docs/features/certs.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { leo } from '../../../lib/data/team'
5 | import Now from '../../../components/now/now'
6 | import { InternalLink } from '../../../components/text/link'
7 | import { TerminalInput } from '../../../components/text/terminal'
8 |
9 | // prettier-ignore
10 | export default withDoc({
11 | title: 'Managing SSL Certificates',
12 | date: '15 Mar 2017',
13 | authors: [leo],
14 | editUrl: 'pages/docs/features/certs.js',
15 | })(markdown(components)`
16 |
17 | Each time you create a new deployment, you will get a new unique subdomain. For this address (just like for the custom domains you've added using \`now alias\` or \`now alias\`), we're automatically provisioning an SSL certificate for you.
18 |
19 | Our platform seamlessly communicates with [Let's Encrypt](https://letsencrypt.org/) to provide your deployment's domain with a [X.509](https://en.wikipedia.org/wiki/X.509) certificate without any costs. All of this happens in the background, seamlessly.
20 |
21 | You can read more about how exactly the certificate provisioning works [here](https://letsencrypt.org/how-it-works/). If you're interested in knowing which browsers the certificates are compatible with, [this](https://letsencrypt.org/docs/certificate-compatibility/) might also be of interest for you. At last, [this document](https://letsencrypt.org/certificates/) describes how the certificates work per se.
22 |
23 | ## Using the CLI
24 |
25 | Let's take a look at how you can use ${}'s command line interface to manage your existing certificates and even upload new ones. In the following examples, \`zeit.rocks\` represents the domain you'd like to modify.
26 |
27 | ### now certs ls
28 |
29 | Lists all certificates owned and created by the user. All certificate entries ever created will remain there in the list, as long as the user still owns the domain associated with the certificate. The actual certificates may however change over time. For example, we periodically renew all the certificates created with the API.
30 |
31 | ### now certs create zeit.rocks
32 |
33 | Allows you to create a new certificate for any domain you have access to and have registered with now. There shouldn't be much real use for this command and it's mainly provided for symmetry, though you may want to use it for creating a certificate entry for a subdomain in advance, before creating an alias using the domain.
34 |
35 | ### now certs renew zeit.rocks
36 |
37 | Can be used for renewing an existing certificate issued with now. This command can't used for renewing a custom certificate provided by the user.
38 |
39 | ### now certs replace
40 |
41 | The command can be used to upload a certificate issued by a 3rd party Certificate Authority. It requires you to already have an alias with an automatic certificate in place. You can use it like this:
42 |
43 | ${
44 |
45 | now certs replace
46 | {' '}
47 | --crt domain.crt --key domain.key --ca ca_chain.crt zeit.rocks
48 |
49 | }
50 |
51 | **Keep in mind**: \`--ca ca_chain.crt\` is optional but needed if your certificate provider is not considered as a root Certificate Authority by web browsers and operating systems (which is usually the case). This file is usually provided by the Certificate Authority you're using.
52 |
53 | ## The API Endpoint
54 |
55 | Finally, version **0.6.0** of [now-client](https://github.com/zeit/now-client) comes with API wrappers for managing the certificates bound to aliases using a custom domain.
56 |
57 | Normally, when a user created an alias with ${} command line utility, we automatically issued a certificate for it (like previously described in ${this post}). So technically, the API endpoint was already there. But until recently, it only supported issuing new certificates. By now, it also supports renewal, removal and replacement.
58 |
59 | The endpoint is called \`/now/certs\` and available in our ${REST API}.
60 | `)
61 |
--------------------------------------------------------------------------------
/components/api/sections/changelog/version2.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import markdown from 'markdown-in-js'
3 | import Section, { components } from '../../section'
4 | import { Code } from '../../../text/code'
5 | import { GenericLink } from '../../../text/link'
6 | import Deprecated from '../../deprecated'
7 | import pure from '../../../../lib/pure-component'
8 |
9 | const H2 = components.h2
10 |
11 | function V2(props) {
12 | const TOKEN = props.testingToken ? props.testingToken.token : '$TOKEN'
13 |
14 | return (
15 | {
22 | markdown(components)`
23 | ${Version 2.0}
24 | ${RELEASED 31, OCTOBER 2017}
25 | ${Create a new deployment}
26 | `}
27 | ],
28 | [
29 | {
30 | markdown(components)`
31 | This endpoint has been deprecated. Use ${v2 endpoint} instead.
32 |
33 | Create a new deployment on the fly by supplying an **:id** in the URL and the necessary file data in the body.
34 |
35 | The body contains a special key \`package\` that has the \`package.json\` JSON structure. Other keys will represent a file path, with their respective values containing the file contents.
36 |
37 | > **NOTE:** The code and logs under the OSS plan will be public.
38 |
39 | `},
40 | markdown(components)`
41 | Endpoint:
42 |
43 | ${POST /now/deployments}
44 |
45 | Example request:
46 |
47 | ${{`curl -X POST https://api.zeit.co/now/deployments \\
48 | -H 'Authorization: Bearer ${TOKEN}' \\
49 | -H 'Content-Type: application/json' \\
50 | -d '{
51 | "package": {
52 | "name": "my-instant-deployment",
53 | "dependencies": {
54 | "sign-bunny": "1.0.0"
55 | },
56 | "scripts": {
57 | "start": "node index"
58 | }
59 | },
60 | "server/index.js": "require(\\"http\\").Server((req, res) => {\nres.setHeader(\\"Content-Type\\", \\"text/plain; charset=utf-8\\");\nres.end(require(\\"sign-bunny\\")(\\"Hi there!\\"));\n}).listen();"
61 | }'
62 | `}}
63 |
64 | Example request with a successful (**200**) response:
65 |
66 | ${{`{
67 | "uid": "ChbZiZe84CKtod6rmCIRRvYR",
68 | "host": "my-instant-deployment-rrucptrbft.now.sh",
69 | "state": "BOOTED"
70 | }`}}
71 | `
72 | ]
73 | ]}
74 | />
75 | )
76 | }
77 |
78 | export default pure(V2)
79 |
80 | class Container extends React.PureComponent {
81 | render() {
82 | return (
83 |
84 |
85 | {this.props.children}
86 |
96 |
97 | )
98 | }
99 | }
100 |
101 | class Heading extends React.PureComponent {
102 | render() {
103 | return (
104 |
105 |
40 | Key
41 | Required
42 | Description
43 |
44 | }>
45 |
46 | client_id
47 | Yes
48 | ID of your application.
49 |
50 |
51 | redirect_uri
52 | No
53 | URL to redirect back.
54 |
55 |
56 | state
57 | No
58 | Random string to be passed back upon completion. It is used to protect against CSRF attacks.
59 |
60 |
}
61 |
62 | If the user grants your request, we redirects back to your site with a \`code\` paremeter and with a \`state\` parameter if you provided one in previous step.
63 |
64 | The process should be aborted if the states don't match.
65 | `,
66 | markdown(components)`
67 | Example request url:
68 |
69 | ${https://zeit.co/oauth/authorize?client_id=oac_s4cllbR9Ao8307IDSkluOQBS}
70 |
71 | Example successful redirect url:
72 |
73 | ${https://example.com/oauth/callback?code=jMIukZ1DBCKXHje3X14BCkU0&state=t2eh4KHwNyGbo5g65VNvoFhl}
74 | `
75 | ],
76 | [
77 | markdown(components)`
78 | ## Exchanging code for an access token
79 | `
80 | ],
81 | [
82 | markdown(components)`
83 | If all goes well, exchange the authorization code for an access token using the following API.
84 |
85 | ${POST https://api.zeit.co/v2/oauth/access_token}
86 |
87 | You will pass the following values to request body in the form of \`application/x-www-form-urlencoded\`.
88 |
89 | ${
91 | Key
92 | Required
93 | Description
94 |
95 | }>
96 |
97 | client_id
98 | Yes
99 | ID of your application.
100 |
101 |
102 | client_secret
103 | Yes
104 | Secret of your application.
105 |
106 |
107 | code
108 | Yes
109 | The code you received.
110 |
111 |
}
112 |
113 | You'll receive a JSON response containing an \`access_token\`.
114 | `,
115 | markdown(components)`
116 | Example access token exchange request.
117 |
118 | ${{`POST https://api.zeit.co/v2/oauth/access_token
119 |
120 | client_id=oac_s4cllbR9Ao8307IDSkluOQBS&client_secret=EOBPvZuBYAtb3SbYo8H1iWFP&code=jMIukZ1DBCKXHje3X14BCkU0
121 | `}}
122 |
123 | Example successful (**200**) response:
124 |
125 | ${{`{
126 | access_token: 'xEbuzM1ZAJ46afITQlYqH605'
127 | }`}}
128 | `
129 | ],
130 | [
131 | markdown(components)`
132 | ## Using access token
133 |
134 | The access token allows you to make requests to the API on a behalf of a user,
135 | by ${providing the token in the Authorization header}.
136 | `
137 | ],
138 | ]
139 | }
140 | />
141 | )
142 | }
143 |
144 | export default immutable(OAuth2)
145 |
--------------------------------------------------------------------------------
/pages/docs/examples/static.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 | import asset from 'next/asset'
4 |
5 | import { leo } from '../../../lib/data/team'
6 | import Now from '../../../components/now/now'
7 | import { InternalLink } from '../../../components/text/link'
8 | import Image from '../../../components/image'
9 | import { Code } from '../../../components/text/code'
10 | import { TerminalInput } from '../../../components/text/terminal'
11 |
12 | // prettier-ignore
13 | export default withDoc({
14 | title: 'Building a Static Website',
15 | date: '23 Feb 2017',
16 | authors: [leo],
17 | editUrl: 'pages/docs/examples/static.js',
18 | })(markdown(components)`
19 |
20 | With just a single command, even complex Node applications or Docker containers can be deployed with now.
21 |
22 | But in some cases, there isn't the need for running code on the server. Sometimes you just want to share files or make a static website accessible for other people.
23 |
24 | Thankfully, our tools make deploying such a project just as easy as it is with a full-blown application.
25 |
26 | ## Setup
27 |
28 | Because basic static websites don't require any special tools in order to work, there's not much you need to do in order to prepare your own one. For the beginning, just create a directory and switch to it by running these commands in your terminal:
29 |
30 | ${{`mkdir static-site\ncd static-site`}}
31 |
32 | Inside that directory, use your favorite editor to create a \`index.html\` file with this content:
33 |
34 | ${
35 |
36 | {`
37 |
38 | `}
53 |
54 | }
55 |
56 | The code basically loads ZEIT's logo from our content delivery network and shows it to the user. In addition, I sprinkled some cute CSS styles on top to position the image in the exact center of the page.
57 |
58 | This is how it will look in the browser when opening the file:
59 |
60 | ${
61 |
66 | }
67 |
68 | ## Testing across Devices
69 |
70 | When developing a static project, you should always make sure that it works on various devices, not just on your own one. This can be solved by simply skipping to ${Deploying}, sending the link to somewhere else and then testing it from there.
71 |
72 | This is a very good idea when working with people across the whole globe and having them try out your project for you. But if you only want to open it on a different device in your own home network, there's a specialized solution: [serve](https://github.com/zeit/serve).
73 |
74 | Want to see what it does exactly? Easy! Simply start with installing it:
75 |
76 | ${npm install -g serve}
77 |
78 | Afterwards, move into the directory containing your static site:
79 |
80 | ${cd static-site}
81 |
82 | And then, finally, run it using this command:
83 |
84 | ${serve}
85 |
86 | Now you'll see a message containing two addresses:
87 |
88 | * **"Local"**: The URL which you can open in the browser on the device where serve is running.
89 | * **"On Your Network"**: That's the address that you can open on different devices on the same network to see your project.
90 |
91 | That easy! Now you can test the site on other platforms (like your phone) as well.
92 |
93 | You can stop \`serve\` by hitting \`CTRL + C\`.
94 |
95 | ## Deploying the Site
96 |
97 | Once the static website works on all devices, we can deploy it by running this command:
98 |
99 | ${now}
100 |
101 | Once ${} has finished uploading the files, you'll see a URL that points to your freshly created website. This means that you can already share the URL with other people across the globe and have them enjoy your site.
102 |
103 | But in the case of a real website (not used for testing purposes), you would now have to ${assign an alias} to it.
104 | `)
105 |
--------------------------------------------------------------------------------
/lib/data/docs.js:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | name: 'Getting Started',
4 | posts: [
5 | {
6 | name: 'Five Minute Guide',
7 | href: '/docs/getting-started/five-minute-guide-to-now',
8 | aliases: ['/docs']
9 | },
10 | {
11 | name: 'Deployment',
12 | href: '/docs/getting-started/deployment'
13 | },
14 | {
15 | name: 'Assign a Domain Name',
16 | href: '/docs/getting-started/assign-a-domain-name'
17 | },
18 | {
19 | name: 'Logs',
20 | href: '/docs/getting-started/logs'
21 | },
22 | {
23 | name: 'Environment Variables',
24 | href: '/docs/getting-started/environment-variables'
25 | },
26 | {
27 | name: 'Secrets',
28 | href: '/docs/getting-started/secrets'
29 | },
30 | {
31 | name: 'Scaling',
32 | href: '/docs/getting-started/scaling'
33 | },
34 | {
35 | name: "What's Next",
36 | href: '/docs/getting-started/whats-next'
37 | }
38 | ]
39 | },
40 |
41 | {
42 | name: 'Features',
43 | posts: [
44 | {
45 | name: 'Now CLI',
46 | href: '/docs/features/now-cli'
47 | },
48 | {
49 | name: 'Deployment Types',
50 | posts: [
51 | {
52 | name: 'Static',
53 | href: '/docs/deployment-types/static'
54 | },
55 | {
56 | name: 'Node.js',
57 | href: '/docs/deployment-types/node'
58 | },
59 | {
60 | name: 'Docker',
61 | href: '/docs/deployment-types/docker'
62 | }
63 | ]
64 | },
65 | {
66 | name: 'Aliases and Domains',
67 | href: '/docs/features/aliases'
68 | },
69 | {
70 | name: 'DNS Management',
71 | href: '/docs/features/dns'
72 | },
73 | {
74 | name: 'Env and Secrets',
75 | href: '/docs/features/env-and-secrets'
76 | },
77 | {
78 | name: 'Configuration',
79 | href: '/docs/features/configuration'
80 | },
81 | {
82 | name: 'SSL Certificates',
83 | href: '/docs/features/certs'
84 | },
85 | {
86 | name: 'Private NPM',
87 | href: '/docs/features/private-npm'
88 | },
89 | {
90 | name: 'GIT Repositories',
91 | href: '/docs/features/repositories'
92 | },
93 | {
94 | name: 'Path Aliases',
95 | href: '/docs/features/path-aliases'
96 | }
97 | ]
98 | },
99 |
100 | {
101 | name: 'Guides',
102 | posts: [
103 | {
104 | name: 'App Lifecycle & Scalability',
105 | href: '/docs/guides/app-lifecycle-and-scalability'
106 | },
107 | {
108 | name: 'Migrate Your App',
109 | href: '/docs/guides/migrate-your-app'
110 | },
111 | {
112 | name: 'How to Use Cloudflare',
113 | href: '/docs/guides/how-to-use-cloudflare'
114 | },
115 | {
116 | name: 'Updating Now CLI',
117 | href: '/docs/guides/updating-now-cli'
118 | },
119 | {
120 | name: 'Redirect',
121 | href: '/docs/examples/redirect'
122 | }
123 | ]
124 | },
125 |
126 | {
127 | name: 'Examples',
128 | posts: [
129 | {
130 | name: 'JSON API',
131 | href: '/docs/examples/json-api'
132 | },
133 | {
134 | name: 'Static Website',
135 | href: '/docs/examples/static'
136 | },
137 | {
138 | name: 'Next.js App',
139 | href: '/docs/examples/next'
140 | },
141 | {
142 | name: 'Slash Command for Slack',
143 | href: '/docs/examples/slack-slash'
144 | },
145 | {
146 | name: 'Realtime Chat',
147 | href: '/docs/examples/chat'
148 | },
149 | {
150 | name: 'GraphQL App',
151 | href: '/docs/examples/graphql'
152 | },
153 | {
154 | name: 'Create React App',
155 | href: '/docs/examples/create-react-app'
156 | },
157 | {
158 | name: 'Travis CI',
159 | href: '/docs/examples/travis'
160 | }
161 | ]
162 | },
163 |
164 | {
165 | name: 'Other',
166 | posts: [
167 | {
168 | name: 'Support Channels',
169 | href: '/docs/other/support-channels'
170 | },
171 | {
172 | name: 'Billing',
173 | href: '/docs/other/billing'
174 | },
175 | {
176 | name: 'FAQ',
177 | href: '/docs/other/faq'
178 | }
179 | ]
180 | }
181 | ]
182 |
--------------------------------------------------------------------------------
/pages/docs/guides/app-lifecycle-and-scalability.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import asset from 'next/asset'
3 | import withDoc, { components } from '../../../lib/with-doc'
4 |
5 | import { rase, rauchg, jamo } from '../../../lib/data/team'
6 | import Now from '../../../components/now/now'
7 | import Image from '../../../components/image'
8 | import { TerminalInput } from '../../../components/text/terminal'
9 |
10 | // prettier-ignore
11 | export default withDoc({
12 | title: 'App Lifecycle and Scalability',
13 | date: '09 March 2017',
14 | authors: [rase, rauchg, jamo],
15 | editUrl: 'pages/docs/guides/app-lifecycle-and-scalability.js',
16 | })(markdown(components)`
17 |
18 | In this guide, we are going to have a look at how ${} deploy and manage your app inside it's infrastructure.
19 |
20 | ## App Lifecycle
21 |
22 | ${
23 |
28 | }
29 |
30 | Your app's deployments flow through a certain set of states throughout their lifecycle.
31 |
32 | * **DEPLOYING**: Files an deployment metadata is collected to boot it up.
33 | * **BOOTED**: When a deployment is first created, it's running environment is prepared and started. After this is completed, the state is set to \`BOOTED\`.
34 | * **BUILDING**: After the deployment infrastructure is up and running, the deployment is built. For \`docker\` based deployments, this means \`docker build\` and persisting the resulting docker image.
35 | For \`npm\` based deployments it means running \`npm install\` and \`npm run build\`. Static deployments currently don't have a build step and jump directly to \`READY\`.
36 | * **READY** or **BUILD_ERROR**: If the build as successful, the deployment will start and move to the \`READY\` state, which means it's ready to receive and serve traffic. For \`npm\` deployments it means \`npm start\`, and for \`docker\` deployments \`docker run\`.
37 |
38 | If, however, the build is unsuccessful, the deployment ends up in a \`BUILD_ERROR\` state, and logs can be inspected to see what went wrong. In this case the deployment will not be retried.
39 |
40 | In addition to the state flow of new deployments, there is a somewhat separate flow of states that the deployment transitions to after it has been successfully deployed.
41 |
42 | A deployment can be frozen if its minimum instance count is set to 0 (the default), if it doesn't get much traffic. When it's accessed later, it will transition back to \`READY\` state from a snapshot.
43 |
44 | The deployment can also permanently move to a \`DEPLOYMENT_ERROR\` state, if it starts to crash time and time again quickly after it's started.
45 |
46 | ## Instances & Scaling
47 |
48 | A deployment by default runs between zero to one instance, meaning it either runs one copy of the application, or is frozen due to lack of traffic. This amount of instances can be decided manually using the \`now scale\` command.
49 |
50 | If the minimum and maximum amount of instances are not the same, the deployment will be automatically scaled between those values depending on the amount of traffic and its throughput. For example, if an application has been scaled with the following command:
51 |
52 | ${{'now scale https://my-app-tnhnoahecha.now.sh 3 10'}}
53 |
54 | Then at any given time, the application will have 3-10 active instances depending on how much it is receiving traffic, and the process of deciding the right amount of copies is automated.
55 |
56 | Automatic scaling depends on the performance of the deployment, incoming bandwidth and overall instance throughput. Every time we make an automated scaling decision, or now scale affects the deployment's scale, it can be seen in events.
57 |
58 | The minimum and the maximum can be equal, which means the application will never be scaled up or down until requested. The application never sleeps if minimum instances is set to a value larger than zero. For example, the following command will result in an application that always runs exactly one copy.
59 |
60 | ${{'now scale https://my-app-tnhnoahecha.now.sh 1'}}
61 |
62 | Instances are reported as unique instance identifiers and their corresponding instance specific access URLs. An instance id is tied to a specific occurrence of the deployment, so if you scale an application up and down, the instance the removed and added instances will have different instance ids. Similarly, if an instance restarts due to for example, an error, the instance id will remain the same.
63 |
64 | When an instance restarts for any reason (or exit code), we automatically restart the instance, so supervisor-like wrappers are not necessary. For example \`forever\`, \`nodemon\` or \`pm\` are not necessary for an application to always stay running.
65 | `)
66 |
--------------------------------------------------------------------------------
/pages/docs/examples/create-react-app.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { sergio } from '../../../lib/data/team'
5 | import Now from '../../../components/now/now'
6 | import { InternalLink } from '../../../components/text/link'
7 | import { Code } from '../../../components/text/code'
8 | import { TerminalInput } from '../../../components/text/terminal'
9 |
10 | // prettier-ignore
11 | export default withDoc({
12 | title: 'Building a Single Page Application with Create React App',
13 | date: '23 Feb 2017',
14 | authors: [sergio],
15 | editUrl: 'pages/docs/examples/create-react-app.js',
16 | })(markdown(components)`
17 |
18 | [Create React App](https://github.com/facebookincubator/create-react-app) is a boilerplate tool used to create Single Page Applications with React.js without build configuration. Facebook created CRA and made it the official way to start a new React application.
19 |
20 | In this page we're going to focus on how to deploy a Single Page Application made with Create React App to ${}. If you want to learn how to use this boilerplate tool we recommend you to read their [repository's README](https://github.com/facebookincubator/create-react-app/blob/master/README.md).
21 |
22 | ## Type of deployment
23 |
24 | ${} let us deploy a simple ${static site} without any configuration, and even if a Single Page Application could be considered a static site (since we don't need server side code) is not exactly one and has one special requirement, the routing is handled client side. That means every URL which doesn't resolve to a static file should return the \`index.html\` file so the application can decide if it's a handled URL or not.
25 |
26 | Because of this special requirement we can't just do a ${static deployment} and we need to rely into the ${Node.js} or ${Docker} deployment. In this case we're going to use a Node.js one.
27 |
28 | ## Setup
29 |
30 | We're going to need a HTTP server for our application, there are many possible ones including Apache, NGINX, express-static, etc. But in our case we're going to use [serve](https://github.com/zeit/serve) and install it as a dependency in our project.
31 |
32 | ${npm install --save serve}
33 |
34 | Then we need to add a script to run this server, because Create React App use \`start\` to run the development server we can decide between changing the default \`start\` script to \`dev\` and run **serve** using \`start\` or we can define a new script called \`now-start\`.
35 |
36 | This new script is going to be used by ${} to run our Node.js application instead of the usual \`start\` script, that way we can continue with the usual workflow of Create React App. And our \`now-start\` script can run the following line.
37 |
38 | ${serve --single ./build}
39 |
40 | The \`--single\` (or just \`-s\`) option is going to tell **serve** to run the HTTP server to support a Single Page Application, this means every request which can't be resolved to a static file is going to resolve with the \`index.html\` so we can handle routing client side.
41 |
42 | The \`./build\` path is going to define which directory we want our HTTP server to actually serve.
43 |
44 | After this the \`package.json\` must looks like this (for a default Create React App project):
45 |
46 | ${
47 | {`{
48 | "name": "project-name",
49 | "version": "0.1.0",
50 | "private": true,
51 | "dependencies": {
52 | "react": "^15.6.1",
53 | "react-dom": "^15.6.1",
54 | "react-scripts": "1.0.13",
55 | "serve": "^6.0.6"
56 | },
57 | "scripts": {
58 | "start": "react-scripts start",
59 | "now-start": "serve --single ./build",
60 | "build": "react-scripts build",
61 | "test": "react-scripts test --env=jsdom",
62 | "eject": "react-scripts eject"
63 | }
64 | }`}
65 | }
66 |
67 | ## Deploying the application
68 | Once we did that we can deploy our application with the following command:
69 |
70 | ${now}
71 |
72 | Once ${} has finished uploading the files, you'll see a URL that points to your freshly created Single Page Application then is going to run \`npm run build\` to build our application code (_we don't need to do build in our local machine_) and after that start our HTTP server with \`npm run now-start\`.
73 |
74 | But in the case of a real application (not used for testing purposes), you would now have to ${assign an alias} to it.
75 | `)
76 |
--------------------------------------------------------------------------------
/pages/docs/getting-started/deployment.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import asset from 'next/asset'
3 | import withDoc, { components } from '../../../lib/with-doc'
4 |
5 | import { arunoda } from '../../../lib/data/team'
6 | import { TerminalInput } from '../../../components/text/terminal'
7 | import Image from '../../../components/image'
8 | import { Code } from '../../../components/text/code'
9 | import { InternalLink } from '../../../components/text/link'
10 | import Now from '../../../components/now/now'
11 |
12 | // prettier-ignore
13 | export default withDoc({
14 | title: 'Deployment',
15 | date: '1 August 2017',
16 | authors: [arunoda],
17 | editUrl: 'pages/docs/getting-started/deployment.js',
18 | })(markdown(components)`
19 |
20 | With ${}, you can deploy any kind of web app by using a single command. ${} supports three types of deployments:
21 |
22 | * ${Static} - for static web apps
23 | * ${Node.js} - for Node.js apps
24 | * ${Docker} - for all other apps
25 |
26 | We have special categories for static and Node.js deployments because they are the most common among the deployments we handle. But you can also use Docker to deploy static and Node.js apps.
27 |
28 | Here is how each of these deployments work:
29 |
30 | ## Static Deployment
31 |
32 | With static deployment, you can deploy a static web app or a set of assets to ${}. Visit the directory you want to deploy and run this command:
33 |
34 | ${now}
35 |
36 | If that directory contains an \`index.html\` file, that file will be served. Otherwise, ${} will show all the files in that directory.
37 |
38 | ${
39 |
45 | }
46 |
47 | > For all static deployments, you will be charged only for the bandwidth. You [do not pay](https://zeit.co/blog/unlimited-static) for computing resources and storage.
48 |
49 | To learn more about static deployments, read ${this guide}.
50 |
51 | ## Node.js Deployment
52 |
53 | If you have a \`package.json\` file in your app directory, "${}" considers that a valid Node.js deployment. Here is a simple Node.js deployment with the help of [micro](https://github.com/zeit/micro).
54 |
55 | We have two files in our app directory. They are:
56 |
57 | ### index.js
58 |
59 | ${
60 | {`module.exports = () => ({
61 | date: new Date
62 | })`}
63 | }
64 |
65 | ### package.json
66 |
67 | ${
68 | {`{
69 | "name": "get-started-node",
70 | "version": "0.1.0",
71 | "dependencies": {
72 | "micro": "latest"
73 | },
74 | "scripts": {
75 | "start": "micro"
76 | }
77 | }`}
78 | }
79 |
80 | To deploy this app, visit the app directory and run this command:
81 |
82 | ${now}
83 |
84 | ${} will install dependencies and run the \`start\` NPM script, as mentioned in the above \`package.json\` file.
85 |
86 | You can also specify a separate build command, select the Node.js runtime and control dependency installation, and do more. To learn about those, read ${this guide}.
87 |
88 | ## Docker Deployment
89 |
90 | If your app directory contains a \`Dockerfile\`, ${} considers that a valid [Docker](https://www.docker.com/) deployment. It will build a docker image based on the \`Dockerfile\` and start container(s) based on that.
91 |
92 | To deploy a simple [Go](https://golang.org/) HTTP server, create a directory and add these two files:
93 |
94 | ### hello.go
95 |
96 | ${
97 | {`package main
98 |
99 | import (
100 | "io"
101 | "net/http"
102 | )
103 |
104 | func main() {
105 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
106 | io.WriteString(w, "Hello world!")
107 | })
108 |
109 | err := http.ListenAndServe(":8000", nil)
110 | if err != nil {
111 | panic(err)
112 | }
113 | }`}
114 | }
115 |
116 | ### Dockerfile
117 |
118 | ${
119 | {`FROM golang:alpine
120 | ADD . /go/src/zeit/hello
121 | RUN go install zeit/hello
122 | CMD ["/go/bin/hello"]
123 | EXPOSE 8000`}
124 | }
125 |
126 | Now run this command inside that directory:
127 |
128 | ${now}
129 |
130 | That's it. You'll get a URL like this:
131 |
132 | To learn more about Docker deployments on ${}, read ${this guide}.
133 | `)
134 |
--------------------------------------------------------------------------------
/pages/docs/deployment-types/docker.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import withDoc, { components } from '../../../lib/with-doc'
3 |
4 | import { leo } from '../../../lib/data/team'
5 | import Now from '../../../components/now/now'
6 | import { Code } from '../../../components/text/code'
7 |
8 | // prettier-ignore
9 | export default withDoc({
10 | title: 'Deploying Docker Apps',
11 | date: '09 March 2017',
12 | authors: [leo],
13 | editUrl: 'pages/docs/deployment-types/docker.js',
14 | })(markdown(components)`
15 |
16 | If your project contains a \`Dockerfile\` file, it will always be treated as a [Docker](https://www.docker.com/) deployment.
17 |
18 | This means that - when running \`now\` inside your terminal - your project will be launched into a secure Docker container on our platform, completely isolated from other customers and even your other containers.
19 |
20 | In this document, you'll learn the exact specifications and behaviour of Docker deployments running on now.
21 |
22 | ## Built in the Cloud
23 |
24 | ${}'s Dockerfile support represents a significant departure from traditional virtualization solution offered by mainstream cloud providers. Here's why:
25 |
26 | The biggest departure is immediately obvious to the user. The entire deployment consisted of a single command. You spend no time with complicated, slow and proprietary (locked-in) workflows.
27 |
28 | The underlying reason this process is so fast and simple is that you spend no time at all worrying about local tooling, images, registries and caches. As a consequence of that, we're freeing you from the limitations of your local environment and network. The build process belongs in the cloud.
29 |
30 | To illustrate this point, pulling, extracting and building the container above took me 3 minutes on a cutting-edge Macbook. Pushing the resulting **200mb** image from an office connection in San Francisco, California to Google® Cloud took another 3 minutes.
31 |
32 | In the equivalent amount of time, I would be able to push and build the same image to ${} **18 times**. Time that's not spent building is spent on iterating on your product and sharing it with the world.
33 |
34 | Over the next few months we'll be rolling out significant enhancements to deepen this vision. While your laptop is constrained by a fixed number of cores, memory, CPU time and bandwidth, the cloud can give you an exponential advantage to you and your business.
35 |
36 | ## Accelerating Builds
37 |
38 | By default, ${} will build an image of your project by itself. If you want to speed up this process, you can publish a pre-built image on the public [Docker Hub](https://hub.docker.com/). At the moment, we don't support private images. However, it's on our roadmap!
39 |
40 | You can select an image by specifying it inside \`Dockerfile\`:
41 |
42 | ${{'FROM /:'}}
43 |
44 | Once the container is built, the snapshot will be used when the deployment is scaled or rebooted.
45 |
46 | ## File System Specifications
47 |
48 | There are no limitations inside Docker deployments when it comes to the file system. It's always writable and readable.
49 |
50 | ## Port Selection
51 |
52 | ${} deployment instances always listen on port \`443\` (HTTPS) of their given url. Your server code can expose a HTTP service on **any port** of your choice (not multiple ones). ${} will then route requests received on port \`443\` to your HTTP service port and its response we be returned by the deployment instance.
53 |
54 | The port that listens for incoming HTTP traffic needs to be defined either in the \`Dockerfile\` that's being used inside the deployment, or the \`Dockerfile\` it's "inheriting" from.
55 |
56 | Aditionally visitors will be redirected from \`http\` to \`https\` automatically.
57 |
58 | ## Deployment Inactivity
59 |
60 | Old deployments always stay around forever if you don't remove them using \`now remove\`.
61 |
62 | However, if your deployment doesn't receive any HTTP(S) requests for a long time, it will most likely be added to the list of deployments that will fall into a light sleep if the platform experiences a lot of load.
63 |
64 | There's no definite answer to how long it will take until such a deployment goes to sleep, because the time will automatically be calculated based on the platform's load and the amount of deployments on it. But if your deployment is linked to an alias, it's less likely to ever fall into a sleep when not being accessed.
65 |
66 | All in all, sleeping deployments are here to reduce the effort the system has to push into keeping those running that aren't being accessed at all (which usually means they're inactive and not needed anymore).
67 |
68 | Sleeping deployments will wake up in a matter of seconds once a request comes in. The visitor won't experience any errors, because the request will be kept alive until the deployment has woken up.
69 |
70 | Eventually, we'll be working on adding support for non-sleeping deployments!
71 | `)
72 |
--------------------------------------------------------------------------------
/pages/docs/getting-started/scaling.js:
--------------------------------------------------------------------------------
1 | import markdown from 'markdown-in-js'
2 | import asset from 'next/asset'
3 | import withDoc, { components } from '../../../lib/with-doc'
4 |
5 | import { arunoda } from '../../../lib/data/team'
6 | import { TerminalInput } from '../../../components/text/terminal'
7 | import { InternalLink } from '../../../components/text/link'
8 | import Image from '../../../components/image'
9 | import Now from '../../../components/now/now'
10 |
11 | // prettier-ignore
12 | export default withDoc({
13 | title: 'Scaling',
14 | date: '10 August 2017',
15 | authors: [arunoda],
16 | editUrl: 'pages/docs/getting-started/scaling.js',
17 | })(markdown(components)`
18 |
19 | Deploying an app is just the start. We need to scale our app as our user base grows. It could be a linear growth or random spikes in certain times.
20 |
21 | Either way, we need to make sure our app is running smoothly as the traffic increases. All the ${} deployments are backed by "auto scaling ready" infrastructure. So, you are in good hands.
22 |
23 | ## Basics
24 |
25 | Each of your ${} deployment consists of zero or few instances. An instance is a running version of your deployment. ${} can clone and run new instances as needed and kill them if they are not needed.
26 |
27 | Each deployment has a minimum and maximum amount of instances it can have. Based on that we can scale our app as needed.
28 |
29 | ## Default Scaling
30 |
31 | By default, all of the deployments are configured like this:
32 |
33 | * min: 0
34 | * max: 1
35 |
36 | This means, when your deployment receives some traffic ${} will start an instance. If your deployment doesn't receive any traffic for a while, ${} will kill that instance.
37 |
38 | There's a fixed number of concurrent instances you can have based on the [plan](https://zeit.co/account/plan) you've chosen. But with this configuration, you can have as many as deployments you want.
39 |
40 | _Having older deployments which are **not active** cost you nothing._
41 |
42 | ## Fixed Scaling
43 |
44 | As your user base grows, your app could be slower to respond. Because it tries to serve more requests than it could do.
45 |
46 | To resolve this issue, you can scale your app to run a fixed number of instances and they'll run forever.
47 |
48 | Here's how you can do that:
49 |
50 | ${now scale hello-node-lwbxweoqjo.now.sh 3}
51 |
52 | In this case, ${} will set the \`min\` and \`max\` instance settings to 3.
53 |
54 | ${
55 |
61 | }
62 |
63 | ### With "now alias"
64 |
65 | Here, \`hello-node-lwbxweoqjo.now.sh\` is one of our deployment URL. Instead, you can scale a "domain name" you mapped with \`now alias\`.
66 |
67 | For an example:
68 |
69 | ${now scale hnode.now.sh 3}
70 |
71 | Then it'll scale the deployment behind the alias. (in this case, the alias is \`hnode.now.sh\`).
72 |
73 | If you run \`now alias\` again, it'll scale the new deployment accordingly and scale down the old deployment to the ${default scaling setup}.
74 |
75 | ${
76 |
82 | }
83 |
84 | ## Auto Scaling
85 |
86 | Sometimes, your app may receive sudden traffic spikes and it's pretty hard to predict the pattern. Then you need to scale your app based on the traffic. To do that, you can turn on “auto scaling” by using different \`min\` and \`max\` instance values.
87 |
88 | > You need to have [the "Pro" plan or a higher plan](https://zeit.co/pricing) to do "auto scaling"
89 |
90 | Here's how to auto scale an app with the URL \`hnode.now.sh\`
91 |
92 | ${now scale hnode.now.sh 2 15}
93 |
94 | Now the deployment behind \`hnode.now.sh\` runs with minimum of 2 instances and it can scale up to 15 instance as the traffic increases.
95 |
96 | ${} will automatically start and kill instances based on the traffic \`hnode.now.sh\` receives.
97 |
98 | ${
99 |
105 | }
106 |
107 | ## Static Deployments
108 |
109 | All the static deployments are infinitely scalable and they are auto scaled by default on all plans.
110 | So, you don't need to invoke \`now scale\` for static deployments.
111 |
112 | `)
113 |
--------------------------------------------------------------------------------
/components/api/sections/changelog/version3.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import markdown from 'markdown-in-js'
3 | import Section, { components } from '../../section'
4 | import { Code, InlineCode } from '../../../text/code'
5 | import { GenericLink } from '../../../text/link'
6 | import Deprecated from '../../deprecated'
7 | import pure from '../../../../lib/pure-component'
8 |
9 | const H2 = components.h2
10 |
11 | function V3(props) {
12 | const TOKEN = props.testingToken ? props.testingToken.token : '$TOKEN'
13 |
14 | return (
15 | {
22 | markdown(components)`
23 | ${Version 3.0}
24 | ${RELEASED 14, FEBRUARY 2018}
25 | ${Create a new deployment}
26 | `}
27 | ],
28 | [
29 | {
30 | markdown(components)`
31 | This endpoint has been deprecated. Use ${v3 endpoint} instead.
32 |
33 | Starting with this release, the ${public} property in
34 | the POST request for creating the deployment needs to be
35 | set to ${true} for all deployments
36 | made on the OSS plan.
37 |
38 | For higher plans, the value can be either:
39 |
40 | - ${true} for making the
41 | deployment's code publicly accessible under the ${/_src} path.
42 | - ${false} for protecting
43 | the deployment's code from public access (${/_src} results in a 403 error).
44 |
45 | **If the property is not set and the plan is
46 | OSS, ${an error} will be thrown.** This opportunity
47 | can be used for showing a confirmation message to the user (asking
48 | them if they really want to deploy):
49 |
50 | As an example, Now CLI and Now Desktop firstly send ${public: false} (even
51 | on the OSS plan). Then, once the API responds with the error, the confirmation
52 | prompt gets shown. If the user agrees to the prompt, another request
53 | will be sent with ${public: true}.
54 |
55 | `},
56 | markdown(components)`
57 | Endpoint:
58 |
59 | ${POST /now/deployments}
60 |
61 | Example request **(user is on the OSS plan)**:
62 |
63 | ${{`curl -X POST https://api.zeit.co/now/deployments \\
64 | -H 'Authorization: Bearer ${TOKEN}' \\
65 | -H 'Content-Type: application/json' \\
66 | -d '{
67 | "package": {
68 | "name": "my-instant-deployment",
69 | "dependencies": {
70 | "sign-bunny": "1.0.0"
71 | },
72 | "scripts": {
73 | "start": "node index"
74 | }
75 | },
76 | "server/index.js": "require(\\"http\\").Server((req, res) => {\nres.setHeader(\\"Content-Type\\", \\"text/plain; charset=utf-8\\");\nres.end(require(\\"sign-bunny\\")(\\"Hi there!\\"));\n}).listen();"
77 | }'
78 | `}}
79 |
80 | Error response (because ${public} is not set):
81 |
82 | ${{`{
83 | "error": {
84 | "code": "plan_requires_public",
85 | "message": "Your plan (OSS) requires the deployment to be marked as public."
86 | }
87 | }`}}
88 | `
89 | ]
90 | ]}
91 | />
92 | )
93 | }
94 |
95 | export default pure(V3)
96 |
97 | class Container extends React.PureComponent {
98 | render() {
99 | return (
100 |
101 |
102 | {this.props.children}
103 |
113 |
114 | )
115 | }
116 | }
117 |
118 | class Heading extends React.PureComponent {
119 | render() {
120 | return (
121 |
122 |