github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/docs/04-configuration.md (about)

     1  ---
     2  title: Configuration
     3  ---
     4  
     5  Configuration for your app lives in the `up.json` within your project's directory. This section details each of the options available.
     6  
     7  ## Name
     8  
     9  The name of the application, which is used to name resources such as the Lambda function or API Gateway.
    10  
    11  ```json
    12  {
    13    "name": "api"
    14  }
    15  ```
    16  
    17  ## Profile
    18  
    19  The `profile` property is equivalent to setting `AWS_PROFILE` for referencing AWS credentials in the `~/.aws` directory. Use of this property is preferred as it prevents accidents with environment variables.
    20  
    21  ```json
    22  {
    23    "profile": "someapp"
    24  }
    25  ```
    26  
    27  ## Regions
    28  
    29  You may specify one or more target regions for deployment using the `regions` array. Glob style patterns may be used to match region ids. By default "us-west-2" is used unless the `AWS_REGION` environment variable is defined.
    30  
    31  Note: Currently only a single region is supported until the issue https://github.com/apex/up/issues/134 is closed.
    32  
    33  A single region:
    34  
    35  ```json
    36  {
    37    "regions": ["us-west-2"]
    38  }
    39  ```
    40  
    41  Several regions:
    42  
    43  ```json
    44  {
    45    "regions": ["us-west-2", "us-east-1", "ca-central-1"]
    46  }
    47  ```
    48  
    49  USA and Canada only:
    50  
    51  ```json
    52  {
    53    "regions": ["us-*", "ca-*"]
    54  }
    55  ```
    56  
    57  Western USA only:
    58  
    59  ```json
    60  {
    61    "regions": ["us-west-*"]
    62  }
    63  ```
    64  
    65  All regions like a boss:
    66  
    67  ```json
    68  {
    69    "regions": ["*"]
    70  }
    71  ```
    72  
    73  Currently Lambda supports the following regions:
    74  
    75  - **us-east-2** – US East (Ohio)
    76  - **us-east-1** – US East (N. Virginia)
    77  - **us-west-1** – US West (N. California)
    78  - **us-west-2** – US West (Oregon)
    79  - **ap-northeast-2** – Asia Pacific (Seoul)
    80  - **ap-south-1** – Asia Pacific (Mumbai)
    81  - **ap-southeast-1** – Asia Pacific (Singapore)
    82  - **ap-southeast-2** – Asia Pacific (Sydney)
    83  - **ap-northeast-1** – Asia Pacific (Tokyo)
    84  - **ca-central-1** – Canada (Central)
    85  - **eu-central-1** – EU (Frankfurt)
    86  - **eu-west-1** – EU (Ireland)
    87  - **eu-west-2** – EU (London)
    88  - **eu-west-3** – EU (Paris)
    89  - **sa-east-1** – South America (São Paulo)
    90  
    91  ## Lambda Settings
    92  
    93  The following Lambda-specific settings are available:
    94  
    95  - `role` – IAM role ARN, defaulting to the one Up creates for you
    96  - `memory` – Function memory in mb (Default `512`, Min `128`, Max `3008`)
    97  - `policy` – IAM function policy statement(s)
    98  - `vpc` - VPC subnets and security groups
    99  - `accelerate` – Enable [S3 Transfer Acceleration](https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html) (Default `false`)
   100  
   101  For example:
   102  
   103  ```json
   104  {
   105    "name": "api",
   106    "lambda": {
   107      "memory": 512,
   108      "vpc": {
   109        "subnets": [
   110          "subnet-aaaaaaa",
   111          "subnet-bbbbbbb",
   112          "subnet-ccccccc",
   113        ],
   114        "security_groups": [
   115          "sg-xxxxxxx"
   116        ]
   117      }
   118    }
   119  }
   120  ```
   121  
   122  The Lambda `memory` setting also scales the CPU, if your app is slow, or for cases such as larger Node applications with many `require()`s you may need to increase this value. View the [Lambda Pricing](https://aws.amazon.com/lambda/pricing/) page for more information regarding the `memory` setting.
   123  
   124  When a VPC is used make sure to use private subnets only, and ensure that you have a NAT for internet access, which will be required to access most AWS APIs.
   125  
   126  Note: Changes to Lambda configuration do not require a `up stack apply`, just deploy and these changes are picked up!
   127  
   128  ### IAM Policy
   129  
   130  Up uses IAM policies to grant access to resources within your AWS account such as DynamoDB or S3.
   131  
   132  To add additional permissions add one or more IAM policy statements to the `policy` array, in the following example we permit DynamoDB item reading, updating, and deleting.
   133  
   134  ```json
   135  {
   136    "name": "myapp",
   137    "lambda": {
   138      "memory": 1024,
   139      "policy": [
   140        {
   141          "Effect": "Allow",
   142          "Resource": "*",
   143          "Action": [
   144            "dynamodb:Get*",
   145            "dynamodb:List*",
   146            "dynamodb:PutItem",
   147            "dynamodb:DeleteItem"
   148          ]
   149        }
   150      ]
   151    }
   152  }
   153  ```
   154  
   155  Deploy to update the IAM function role permissions.
   156  
   157  ### Active Warming
   158  
   159  [Up Pro](#guides.subscribing_to_up_pro) supports active warming to mitigate cold starts. A "cold start" occurs in AWS Lambda when there are no idle containers available to serve a request—Lambda must fetch your code and create a new container, after this it is "warm" and remains in the Lambda cluster to serve subsequent requests for roughly an hour.
   160  
   161  If a container does not receive any traffic within the hour, it is removed from the AWS Lambda cluster, and thus a new request may incur a cold start. Up Pro's "active warming" feature mitigates this by periodically requesting against your app, at the specified concurrency. It tries to maintain at least `warm_count` idle containers.
   162  
   163  For example when a user visits your web application, a cold start may occur for each resource, say you have one JavaScript file, CSS file, and the HTML itself, then this will be 3 concurrent containers. By default Up will warm `15` containers, however you may want to adjust `warm_count` this for your use-case.
   164  
   165  Note that if your application receives steady traffic this may not be an issue at all in practice, as containers will already be warm and re-used.
   166  
   167  - `warm` – Enable active warming (Default: false)
   168  - `warm_count` – Number of concurrent containers to warm (Default: `15`)
   169  - `warm_rate` – Rate at which to perform the warming (Default: `"15m"`)
   170  
   171  Here's a example specifying `50` idle containers, for all remote stages (staging, production, and custom):
   172  
   173  ```json
   174  {
   175    "name": "app",
   176    "lambda": {
   177      "warm": true,
   178      "warm_count": 50,
   179      "warm_rate": "30m"
   180    }
   181  }
   182  ```
   183  
   184  Run `up stack plan` and `up stack apply` to make the changes to your stack! You may apply stage level changes as well, or enable warming for a specific stage only if desired, as shown here:
   185  
   186  ```json
   187  {
   188    "name": "app",
   189    "stages": {
   190      "production": {
   191        "lambda": {
   192          "warm": true,
   193          "warm_count": 50
   194        }
   195      }
   196    }
   197  }
   198  ```
   199  
   200  Another way to mitigate cold starts is to use an uptime monitoring tool, such as [Apex Ping](https://apex.sh/ping/) which also monitors global performance, so it's a win-win! Use the "up" coupon for 15% off your first year.
   201  
   202  [![Uptime Monitoring Tool](https://apex-software.imgix.net/ping/marketing/overview.png?compress=auto)](https://apex.sh/ping)
   203  
   204  ## Hook Scripts
   205  
   206  Up provides "hooks" which are commands invoked at certain points within the deployment workflow for automating builds, linting and so on. The following hooks are available:
   207  
   208  - `prebuild` – Run before building
   209  - `build` – Run before building. Overrides inferred build command(s)
   210  - `postbuild` – Run after building
   211  - `predeploy` – Run before deploying
   212  - `postdeploy` – Run after deploying
   213  - `clean` – Run after a deploy to clean up artifacts. Overrides inferred clean command(s)
   214  
   215  Here's an example using Browserify to bundle a Node application. Use the `-v` verbose log flag to see how long each hook takes.
   216  
   217  ```json
   218  {
   219    "name": "app",
   220    "hooks": {
   221      "build": "browserify --node app.js > server.js",
   222      "clean": "rm server.js"
   223    }
   224  }
   225  ```
   226  
   227  Up performs runtime inference to discover what kind of application you're using, and does its best to provide helpful defaults – see the [Runtimes](#runtimes) section.
   228  
   229  Multiple commands are provided by using arrays, and are run in separate shells:
   230  
   231  ```json
   232  {
   233    "name": "app",
   234    "hooks": {
   235      "build": [
   236        "mkdir -p build",
   237        "cp -fr static build",
   238        "browserify --node index.js > build/client.js"
   239      ],
   240      "clean": "rm -fr build"
   241    }
   242  }
   243  ```
   244  
   245  To get a better idea of when hooks run, and how long the command(s) take, you may want to deploy with `-v` for verbose debug logs.
   246  
   247  ## Static File Serving
   248  
   249  Up ships with a robust static file server, to enable it specify the app `type` as `"static"`.
   250  
   251  ```json
   252  {
   253    "type": "static"
   254  }
   255  ```
   256  
   257  By default the current directory (`.`) is served, however you can change this using the `dir` setting. The following configuration restricts only serving of files in `./public/*`, any attempts to read files from outside of this root directory will fail.
   258  
   259  ```json
   260  {
   261    "name": "app",
   262    "type": "static",
   263    "static": {
   264      "dir": "public"
   265    }
   266  }
   267  ```
   268  
   269  Note that `static.dir` only tells Up which directory to serve – it does not exclude other files from the deployment – see [Ignoring Files](#configuration.ignoring_files). For example you may want an `.upignore` containing:
   270  
   271  ```
   272  *
   273  !public/**
   274  ```
   275  
   276  ### Dynamic Apps
   277  
   278  If your project is not strictly static, for example a Node.js web app, you may omit `type` and add static file serving simply by defining `static` as shown below. With this setup Up will serve the file if it exists, before passing control to your application.
   279  
   280  ```json
   281  {
   282    "name": "app",
   283    "static": {
   284      "dir": "public"
   285    }
   286  }
   287  ```
   288  
   289  By default there is no prefix, so `GET /index.css` will resolve to `./public/index.css`, however, you may specify a prefix such as "/static/" for `GET /static/index.css` to ensure static files never conflict with your app's routes:
   290  
   291  ```json
   292  {
   293    "name": "app",
   294    "static": {
   295      "dir": "public",
   296      "prefix": "/static/"
   297    }
   298  }
   299  ```
   300  
   301  Note: Static file serving for dynamic apps does not automatically resolve `index.html` files. The presence of a file is checked before passing control to your application.
   302  
   303  ## Environment Variables
   304  
   305  The `environment` object may be used for plain-text environment variables. Note that these are not encrypted, and are stored in up.json which is typically committed to GIT, so do not store secrets here.
   306  
   307  ```json
   308  {
   309    "name": "api",
   310    "environment": {
   311      "API_FEATURE_FOO": "1",
   312      "API_FEATURE_BAR": "0"
   313    }
   314  }
   315  ```
   316  
   317  These become available to you via `process.env.API_FEATURES_FOO`, `os.Getenv("API_FEATURES_FOO")` or similar in your language of choice.
   318  
   319  The following environment variables are provided by Up:
   320  
   321  - `PORT` – port number such as "3000"
   322  - `UP_STAGE` – stage name such as "staging" or "production"
   323  
   324  [Up Pro](#guides.subscribing_to_up_pro) offers encrypted environment variables via the [up env](#commands.env) sub-command which supports per-stage environment variable mapping.
   325  
   326  ## Header Injection
   327  
   328  The `headers` object allows you to map HTTP header fields to paths. The most specific pattern takes precedence.
   329  
   330  Here's an example of two header fields specified for `/*` and `/*.css`:
   331  
   332  ```json
   333  {
   334    "name": "app",
   335    "type": "static",
   336    "headers": {
   337      "/*": {
   338        "X-Something": "I am applied to everything"
   339      },
   340      "/*.css": {
   341        "X-Something-Else": "I am applied to styles"
   342      }
   343    }
   344  }
   345  ```
   346  
   347  Requesting `GET /` will match the first pattern, injecting `X-Something`:
   348  
   349  ```
   350  HTTP/1.1 200 OK
   351  Accept-Ranges: bytes
   352  Content-Length: 200
   353  Content-Type: text/html; charset=utf-8
   354  Last-Modified: Fri, 21 Jul 2017 20:42:51 GMT
   355  X-Powered-By: up
   356  X-Something: I am applied to everything
   357  Date: Mon, 31 Jul 2017 20:49:33 GMT
   358  ```
   359  
   360  Requesting `GET /style.css` will match the second, more specific pattern, injecting `X-Something-Else`:
   361  
   362  ```json
   363  HTTP/1.1 200 OK
   364  Accept-Ranges: bytes
   365  Content-Length: 50
   366  Content-Type: text/css; charset=utf-8
   367  Last-Modified: Fri, 21 Jul 2017 20:42:51 GMT
   368  X-Powered-By: up
   369  X-Something-Else: I am applied to styles
   370  Date: Mon, 31 Jul 2017 20:49:35 GMT
   371  ```
   372  
   373  ## Error Pages
   374  
   375  By default Up will serve a minimalistic error page for requests accepting `text/html`. The following settings are available:
   376  
   377  - `disable` — remove the error page feature and default pages
   378  - `dir` — the directory where the error pages are located
   379  - `variables` — vars available to the pages
   380  
   381  The default template's `color` and optionally provide a `support_email` to allow customers to contact your support team, for example:
   382  
   383  ```json
   384  {
   385    "name": "site",
   386    "type": "static",
   387    "error_pages": {
   388      "variables": {
   389        "support_email": "support@apex.sh",
   390        "color": "#228ae6"
   391      }
   392    }
   393  }
   394  ```
   395  
   396  If you'd like to provide custom templates you may create one or more of the following files. The most specific file takes precedence.
   397  
   398  - `error.html` – Matches any 4xx or 5xx
   399  - `5xx.html` – Matches any 5xx error
   400  - `4xx.html` – Matches any 4xx error
   401  - `CODE.html` – Matches a specific code such as 404.html
   402  
   403  Variables specified via `variables`, as well as `.StatusText` and `.StatusCode` may be used in the template.
   404  
   405  ```html
   406  <!DOCTYPE html>
   407  <html>
   408    <head>
   409      <meta charset="utf-8">
   410      <title>{{.StatusText}} - {{.StatusCode}}</title>
   411      <link rel="stylesheet" href="/css/style.css">
   412    </head>
   413    <body>
   414      <h1>{{.StatusText}}</h1>
   415      {{with .Variables.support_email}}
   416        <span class="message">Please try your request again or <a href="mailto:{{.}}">contact support</a>.</span>
   417      {{else}}
   418        <span class="message">Please try your request again or contact support.</span>
   419      {{end}}
   420    </body>
   421  </html>
   422  ```
   423  
   424  ## Script Injection
   425  
   426  Scripts, styles, and other tags may be injected to HTML pages before the closing `</head>` tag or closing `</body>` tag.
   427  
   428  In the following example the `<link rel="/style.css">` is injected to the head, as well as the inlining the `scripts/config.js` file. A `<script src="/app.js"></script>` is then injected into the body.
   429  
   430  
   431  ```json
   432  {
   433    "name": "site",
   434    "type": "static",
   435    "inject": {
   436      "head": [
   437        {
   438          "type": "style",
   439          "value": "/style.css"
   440        },
   441        {
   442          "type": "inline script",
   443          "file": "scripts/config.js"
   444        }
   445      ],
   446      "body": [
   447        {
   448          "type": "script",
   449          "value": "/app.js"
   450        }
   451      ]
   452    }
   453  }
   454  ```
   455  
   456  Currently you may specify the following types:
   457  
   458  - `literal` – A literal string
   459  - `comment` – An html comment
   460  - `style` – A style `href`
   461  - `script` – A script `src`
   462  - `inline style` – An inline style
   463  - `inline script` – An inline script
   464  - `google analytics` – Google Analytics snippet with API key
   465  - `segment` – Segment snippet with API key
   466  
   467  All of these require a `value`, which sets the `src`, `href`, or inline content. Optionally you can populate `value` via a `file` path to a local file on disk, this is typically more convenient for inline scripts or styles. For example:
   468  
   469  - `{ "type": "literal", "value": "<meta name=...>" }`
   470  - `{ "type": "comment", "value": "Just a boring comment" }`
   471  - `{ "type": "script", "value": "/feedback.js" }`
   472  - `{ "type": "style", "value": "/feedback.css" }`
   473  - `{ "type": "inline script", "file": "/feedback.js" }`
   474  - `{ "type": "inline style", "file": "/feedback.css" }`
   475  - `{ "type": "script", "value": "var config = {};" }`
   476  - `{ "type": "google analytics", "value": "API_KEY" }`
   477  - `{ "type": "segment", "value": "API_KEY" }`
   478  
   479  ## Redirects and Rewrites
   480  
   481  Up supports redirects and URL rewriting via the `redirects` object, which maps path patterns to a new location. If `status` is omitted (or 200) then it is a rewrite, otherwise it is a redirect.
   482  
   483  ```json
   484  {
   485    "name": "app",
   486    "type": "static",
   487    "redirects": {
   488      "/blog": {
   489        "location": "https://blog.apex.sh/",
   490        "status": 301
   491      },
   492      "/docs/:section/guides/:guide": {
   493        "location": "/help/:section/:guide",
   494        "status": 302
   495      },
   496      "/store/*": {
   497        "location": "/shop/:splat"
   498      }
   499    }
   500  }
   501  ```
   502  
   503  In the previous example `/blog` will redirect to a different site, while `/docs/ping/guides/alerting` will redirect to `/help/ping/alerting`. Finally `/store/ferrets` and nested paths such as `/store/ferrets/tobi` will redirect to `/shop/ferrets/tobi` and so on.
   504  
   505  A common use-case for rewrites is for SPAs or Single Page Apps, where you want to serve the `index.html` file regardless of the path. The other common requirement for SPAs is that you of course can serve scripts and styles, so by default if a file is found, it will not be rewritten to `location`.
   506  
   507  ```json
   508  {
   509    "name": "app",
   510    "type": "static",
   511    "redirects": {
   512      "/*": {
   513        "location": "/",
   514        "status": 200
   515      }
   516    }
   517  }
   518  ```
   519  
   520  If you wish to force the rewrite regardless of a file existing, set `force` to `true` as shown here:
   521  
   522  ```json
   523  {
   524    "name": "app",
   525    "type": "static",
   526    "redirects": {
   527      "/*": {
   528        "location": "/",
   529        "status": 200,
   530        "force": true
   531      }
   532    }
   533  }
   534  ```
   535  
   536  More specific target paths take precedence over those which are less specific, for example `/blog` will win over and `/*`.
   537  
   538  ## Cross-Origin Resource Sharing
   539  
   540  CORS is a mechanism which allows requests originating from a different host to make requests to your API. Several options are available to restrict this access, if the defaults are appropriate simply enable it as shown below.
   541  
   542  ```json
   543  {
   544    "cors": {
   545      "enable": true
   546    }
   547  }
   548  ```
   549  
   550  Suppose you have `https://api.myapp.com`, you may want to customize `cors` to permit access only from `https://myapp.com` so that other sites cannot call your API directly.
   551  
   552  ```json
   553  {
   554    "cors": {
   555      "allowed_origins": ["https://myapp.com"],
   556      "allowed_methods": ["HEAD", "GET", "POST", "PUT", "PATCH", "DELETE"],
   557      "allowed_headers": ["*"],
   558      "allow_credentials": true
   559    }
   560  }
   561  ```
   562  
   563  - `allowed_origins` – A list of origins a cross-domain request can be executed from. Use `*` to allow any origin, or a wildcard such as `http://*.domain.com` (Default: `["*"]`)
   564  - `allowed_methods` – A list of methods the client is allowed to use with cross-domain requests. (Default: `["HEAD", "GET", "POST"]`)
   565  - `allowed_headers` – A list of headers the client is allowed to use with cross-domain requests. If the special `*` value is present in the list, all headers will be allowed. (Default: `["Origin", "Accept", "Content-Type", "X-Requested-With"]`)
   566  - `exposed_headers` – A list of headers which are safe to expose to the API of a CORS response.
   567  - `max_age` – A number indicating how long (in seconds) the results of a preflight request can be cached.
   568  - `allow_credentials` – A boolean indicating whether the request can include user credentials such as cookies, HTTP authentication or client side SSL certificates. (Default: `true`)
   569  - `debug` - A boolean which will output debug logs (Default: `false`)
   570  
   571  Here's an example performing a GraphQL query with `fetch()`, note that `Accept` is set to accept only JSON:
   572  
   573  ```js
   574  const body = JSON.stringify({
   575    query: `query {
   576      pet(id: 2) {
   577        name
   578      }
   579    }`
   580  })
   581  
   582  const res = await fetch('https://myapp.com', {
   583    headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
   584    method: 'POST',
   585    body
   586  })
   587  ```
   588  
   589  Note: You do not need to run `up stack plan` for CORS settings, simply redeploy the stage.
   590  
   591  ## Reverse Proxy
   592  
   593  Up acts as a reverse proxy in front of your server, this is how CORS, redirection, script injection and other middleware style features are provided.
   594  
   595  The following settings are available:
   596  
   597  - `command` – Command run through the shell to start your server (Default `./server`)
   598    - When `package.json` is detected `npm start` is used
   599    - When `app.js` is detected `node app.js` is used
   600    - When `app.py` is detected `python app.py` is used
   601  - `timeout` – Timeout in seconds per request (Default `15`, Max `25`)
   602  - `listen_timeout` – Timeout in seconds Up will wait for your app to boot and listen on `PORT` (Default `15`, Max `25`)
   603  
   604  ```json
   605  {
   606    "proxy": {
   607      "command": "node app.js",
   608      "timeout": 10,
   609      "listen_timeout": 5
   610    }
   611  }
   612  ```
   613  
   614  Lambda's function timeout is implied from the `.proxy.timeout` setting.
   615  
   616  ### Crash Recovery
   617  
   618  Another benefit of using Up as a reverse proxy is performing crash recovery. Up will attempt to restart your application if the process crashes to continue serving subsequent requests.
   619  
   620  ## DNS Zones & Records
   621  
   622  Up allows you to configure DNS zones and records. One or more zones may be provided as keys in the `dns` object ("myapp.com" here), with a number of records defined within it.
   623  
   624  ```json
   625  {
   626    "name": "gh-polls",
   627    "dns": {
   628      "gh-polls.com": [
   629        {
   630          "name": "app.gh-polls.com",
   631          "type": "CNAME",
   632          "value": ["gh-polls.netlify.com"]
   633        }
   634      ]
   635    }
   636  }
   637  ```
   638  
   639  The record `type` must be one of:
   640  
   641  - A
   642  - AAAA
   643  - CNAME
   644  - MX
   645  - NAPTR
   646  - NS
   647  - PTR
   648  - SOA
   649  - SPF
   650  - SRV
   651  - TXT
   652  
   653  ## Stages
   654  
   655  Up supports the concept of "stages" for configuration, such as mapping of custom domains, or tuning the size of Lambda function to use.
   656  
   657  By default the following stages are defined:
   658  
   659  - `development` — local development environment
   660  - `staging` — remote environment for staging new features or releases
   661  - `production` — remote environment for production
   662  
   663  To create a new stage, first add it to your configuration, in this case we'll call it "beta":
   664  
   665  ```json
   666  {
   667    "name": "app",
   668    "lambda": {
   669      "memory": 128
   670    },
   671    "stages": {
   672      "beta": {
   673  
   674      }
   675    }
   676  }
   677  ```
   678  
   679  Now you'll need to plan your stack changes, which will set up a new API Gateway and permissions:
   680  
   681  
   682  ```
   683  $ up stack plan
   684  
   685  Add api deployment
   686    id: ApiDeploymentBeta
   687  
   688  Add lambda permission
   689    id: ApiLambdaPermissionBeta
   690  ```
   691  
   692  Apply those changes:
   693  
   694  ```
   695  $ up stack apply
   696  ```
   697  
   698  Now you can deploy to your new stage by passing the name `beta` and open the end-point in the browser:
   699  
   700  ```
   701  $ up beta
   702  $ up url -o beta
   703  ```
   704  
   705  To delete a stage, simply remove it from the `up.json` configuration and run `up stack plan` again, and `up stack apply` after reviewing the changes.
   706  
   707  You may of course assign a custom domain to these stages as well, let's take a look at that next!
   708  
   709  ## Stages & Custom Domains
   710  
   711  By defining a stage and its `domain`, Up knows it will need to create a free SSL certificate—`gh-polls.com` in the following example—setup the DNS records, and map the domain to API Gateway. SSL certificates are managed via [AWS ACM](https://aws.amazon.com/certificate-manager/) which automatically renew for you, there's no additional work or cost associated with them.
   712  
   713  ```json
   714  {
   715    "stages": {
   716      "production": {
   717        "domain": "gh-polls.com"
   718      }
   719    }
   720  }
   721  ```
   722  
   723   Here's another example mapping each stage to a domain, note that the domains do not need to be related, you could use `stage-gh-polls.com` for example.
   724  
   725  
   726  ```json
   727  {
   728    "stages": {
   729      "production": {
   730        "domain": "gh-polls.com"
   731      },
   732      "staging": {
   733        "domain": "stage.gh-polls.com"
   734      }
   735    }
   736  }
   737  ```
   738  
   739  You may also provide an optional base path, for example to prefix your API with `/v1`. Note that currently your application will still receive "/v1" in its request path, for example Node's `req.url` will be  "/v1/users" instead of "/users".
   740  
   741  ```json
   742  {
   743    "stages": {
   744      "production": {
   745        "domain": "api.gh-polls.com",
   746        "path": "/v1"
   747      }
   748    }
   749  }
   750  ```
   751  
   752  Plan the changes via `up stack plan` and `up stack apply` to perform the changes. You may [purchase domains](#guides.development_to_production_workflow.purchasing_a_domain) from the command-line, or map custom domains from other registrars. Up uses Route53 to purchase domains using your AWS account credit card. See `up help domains`.
   753  
   754  Note: CloudFront can take up to ~40 minutes to distribute this configuration the first time, so grab a coffee while these changes are applied. Also note that ACM certificates are always created in the Virginia (us-east-1) region due to how API Gateway interoperates with CloudFront.
   755  
   756  ### DNS Zones
   757  
   758  By default when you specify a stage `domain` — such as "api.example.com" — a DNS zone is created in Route53 for the top level domain "example.com", and an ALIAS record "api.example.com" is added to this zone.
   759  
   760  If you're using external DNS and wish to omit the zone entirely you can disable it with the `zone` property:
   761  
   762  ```json
   763  {
   764    "stages": {
   765      "production": {
   766        "domain": "gh-polls.com",
   767        "zone": false
   768      }
   769    }
   770  }
   771  ```
   772  
   773  You may also explicitly specify the zone by providing a string. In the following example an "api.gh-polls.com" zone will be created, instead of putting the record in "gh-polls.com".
   774  
   775  ```json
   776  {
   777    "stages": {
   778      "production": {
   779        "domain": "api.gh-polls.com",
   780        "zone": "api.gh-polls.com"
   781      }
   782    }
   783  }
   784  ```
   785  
   786  ## Stage Overrides
   787  
   788  Up allows some configuration properties to be overridden at the stage level. The following example illustrates how you can tune lambda memory and hooks per-stage.
   789  
   790  ```json
   791  {
   792    "name": "app",
   793    "hooks": {
   794      "build": "parcel index.html --no-minify -o build",
   795      "clean": "rm -fr build"
   796    },
   797    "stages": {
   798      "production": {
   799        "hooks": {
   800          "build": "parcel index.html -o build"
   801        },
   802        "lambda": {
   803          "memory": 1024
   804        }
   805      }
   806    }
   807  }
   808  ```
   809  
   810  Currently the following properties may be specified at the stage level:
   811  
   812  - `hooks`
   813  - `lambda`
   814  - `proxy.command`
   815  
   816  For example you may want to override `proxy.command` for development, which is the env `up start` uses. In the following example [gin](https://github.com/codegangsta/gin) is used for hot reloading of Go programs:
   817  
   818  ```json
   819  {
   820    "name": "app",
   821    "stages": {
   822      "development": {
   823        "proxy": {
   824          "command": "gin --port $PORT"
   825        }
   826      }
   827    }
   828  }
   829  ```
   830  
   831  ## Logs
   832  
   833  By default Up treats stdout as `info` level logs, and stderr as `error` level. If your logger uses stderr, such as Node's `debug()` module and you'd like to change this behaviour you may override these levels:
   834  
   835  ```json
   836  {
   837    "name": "app",
   838    "environment": {
   839      "DEBUG": "myapp"
   840    },
   841    "logs": {
   842      "stdout": "info",
   843      "stderr": "info"
   844    }
   845  }
   846  ```
   847  
   848  ## Ignoring Files
   849  
   850  Up supports gitignore style pattern matching for omitting files from deployment via the `.upignore` file.
   851  
   852  An example `.upignore` to omit markdown and `.go` source files might look like this:
   853  
   854  ```
   855  *.md
   856  *.go
   857  ```
   858  
   859  ### Negation
   860  
   861  By default dotfiles are ignored, if you wish to include them, you may use `!` to negate a pattern in `.upignore`:
   862  
   863  ```
   864  !.myfile
   865  ```
   866  
   867  Another use-case for negation is to ignore everything and explicitly include a number of files instead, to be more specific:
   868  
   869  ```
   870  *
   871  !app.js
   872  !package.json
   873  !node_modules/**
   874  !src/**
   875  ```
   876  
   877  ### Inspecting
   878  
   879  To get a better idea of which files are being filtered or added, use `up -v` when deploying, and you may also find it useful to `grep` in some cases:
   880  
   881  ```
   882  $ up -v 2>&1 | grep filtered
   883  DEBU filtered .babelrc – 25
   884  DEBU filtered .git – 408
   885  DEBU filtered .gitignore – 13
   886  DEBU filtered node_modules/ansi-regex/readme.md – 1749
   887  DEBU filtered node_modules/ansi-styles/readme.md – 1448
   888  DEBU filtered node_modules/binary-extensions/readme.md – 751
   889  DEBU filtered node_modules/chalk/readme.md – 6136
   890  ```
   891  
   892  You may also wish to use `up build --size` to view the largest files within the zip.
   893  
   894  ### Pattern matching
   895  
   896  Note that patterns are matched much like `.gitignore`, so if you have the following `.upignore` contents even `node_modules/debug/src/index.js` will be ignored since it contains `src`.
   897  
   898  ```
   899  src
   900  ```
   901  
   902  You can be more specific with a leading `./`:
   903  
   904  ```
   905  ./src
   906  ```
   907  
   908  Files can be matched recursively using `**`, for example ignoring everything except the files in `dist`:
   909  
   910  ```
   911  *
   912  !dist/**
   913  ```
   914  
   915  ## Alerting
   916  
   917  [Up Pro](#guides.subscribing_to_up_pro) supports defining alerts which can notify your team when your service is failing, responding slowly, or receiving traffic spikes.
   918  
   919  ```json
   920  {
   921    "name": "app",
   922    "actions": [
   923      {
   924        "name": "email.backend",
   925        "type": "email",
   926        "emails": ["tj@apex.sh"]
   927      },
   928      {
   929        "name": "text.backend",
   930        "type": "sms",
   931        "numbers": ["+12508183100"]
   932      }
   933    ],
   934    "alerts": [
   935      {
   936        "metric": "http.count",
   937        "statistic": "sum",
   938        "threshold": 100,
   939        "action": "email.backend"
   940      },
   941      {
   942        "metric": "http.5xx",
   943        "statistic": "sum",
   944        "threshold": 1,
   945        "period": "1m",
   946        "action": "email.backend"
   947      },
   948      {
   949        "metric": "http.4xx",
   950        "statistic": "sum",
   951        "threshold": 50,
   952        "period": "5m",
   953        "action": "email.backend"
   954      },
   955      {
   956        "metric": "http.latency",
   957        "statistic": "avg",
   958        "threshold": 1000,
   959        "period": "5m",
   960        "action": "email.backend",
   961        "description": "Large traffic spike"
   962      }
   963    ]
   964  }
   965  ```
   966  
   967  ### Defining Actions
   968  
   969  An action must be defined in order to notify your team of triggered and resolved  alerts. The action requires a `name`, which can be any string such as `backend`, `frontend_team`, `email.backend`, `email backend` – whichever you prefer.
   970  
   971  #### Email
   972  
   973  The email action notifies your team via email.
   974  
   975  ```json
   976  {
   977    "name": "email.backend",
   978    "type": "email",
   979    "emails": ["tj@apex.sh"]
   980  }
   981  ```
   982  
   983  #### SMS
   984  
   985  The sms action notifies your team via sms text message.
   986  
   987  ```json
   988  {
   989    "name": "text.backend",
   990    "type": "sms",
   991    "numbers": ["+12508183100"]
   992  }
   993  ```
   994  
   995  #### Slack
   996  
   997  The slack action notifies your team via Slack message.
   998  
   999  ```json
  1000  {
  1001    "name": "slack.backend",
  1002    "type": "slack",
  1003    "url": "https://hooks.slack.com/services/T0YS6H6S5/..."
  1004  }
  1005  ```
  1006  
  1007  Optionally `gifs` can be enabled and a `channel` can be specified instead of using the default for the `url`.
  1008  
  1009  ```json
  1010  {
  1011    "name": "slack.backend",
  1012    "type": "slack",
  1013    "url": "https://hooks.slack.com/services/T0YS6H6S5/...",
  1014    "channel": "alerts",
  1015    "gifs": true
  1016  }
  1017  ```
  1018  
  1019  ### Defining Alerts
  1020  
  1021  An alert requires a `metric` such as request count or latency, statistic such as sum or svg, threshold, and an action to perform when the alert is triggered. Here's a simple example emailing the backend team when we encounter a spike of over 1000 requests.
  1022  
  1023  ```json
  1024  {
  1025    "metric": "http.count",
  1026    "statistic": "sum",
  1027    "threshold": 1000,
  1028    "action": "email.backend"
  1029  }
  1030  ```
  1031  
  1032  #### Required settings
  1033  
  1034  - `metric` – Metric to alert against
  1035    - `http.count` – Request count
  1036    - `http.latency` – Request latency in milliseconds
  1037    - `http.4xx` – HTTP 4xx client errors
  1038    - `http.5xx` – HTTP 5xx server errors
  1039  - `statistic` – Statistic name ("sum", "min", "max", "avg", "count")
  1040  - `threshold` – Threshold which is compared to `operator`
  1041  - `action` – Name of the action to perform
  1042  
  1043  #### Optional settings
  1044  
  1045  - `period` – Period is the alert query time-span (default: `1m`)
  1046  - `evaluation_periods` – Number of periods to evaluate over (default: `1`)
  1047  - `operator` – Operator is the comparison operator (default `>`)
  1048  - `namespace` – Metric namespace (example: "AWS/ApiGateway")
  1049  - `missing`– How to treat missing data (default: `notBreaching`)
  1050  - `disable` – Disable or mute the alert
  1051  - `description` – Description of the alert