Skip to content

Instantly share code, notes, and snippets.

@chadwcarlson
Created June 25, 2020 16:23
Show Gist options
  • Save chadwcarlson/b8fbffa82e642692659a233fb56f7af5 to your computer and use it in GitHub Desktop.
Save chadwcarlson/b8fbffa82e642692659a233fb56f7af5 to your computer and use it in GitHub Desktop.
{
"site": "website",
"source": "secondary",
"rank": 3,
"documentId": "1f80afed50618a7f5be17adaaf31af33",
"title": "Web",
"description": "",
"text": " The web key defines a single web instance container running a single web server process (currently Nginx), behind which runs your application. The web key configures the web server, including what requests should be served directly (such as static files) and which should be passed to your application. The server is extremely flexible, which means that some configurations will be more involved than others. Additionally, defaults may vary somewhat between different language base images (specified by the type key of .platform.app.yaml). The first section on this page explains the various options the file supports. If you prefer, the later sections include various example configurations to demonstrate common patterns and configurations. You can also examine the .platform.app.yaml files of the provided project templates for various common Free Software applications. See the various language pages for an index of available examples. The web key defines how the application is exposed to the web (in HTTP). Here we tell the web application how to serve content, including static files, front-controller scripts, index files, index scripts, and so on. We support any directory structure, so the static files can be in a subdirectory and the index.php file can be further down. Commands The commands key defines the command to launch the application. For now there is only a single command, start, but more will be added in the future. The start key specifies the command to use to launch your application. That could be running a uwsgi command for a Python application or a unicorn command for a Ruby application, or simply running your compiled Go application. If the command specified by the start key terminates it will be restarted automatically. web:commands:start:\u0026#39;uwsgi --ini conf/server.ini\u0026#39; Note: Never “background” a start process using \u0026amp;. That will be interpreted as the command terminating and the supervisor process will start a second copy, creating an infinite loop until the container crashes. Just run it as normal and allow the Platform.sh supervisor to manage it. On PHP containers this value is optional and will default to starting PHP-FPM (i.e. /usr/sbin/php-fpm7.0 on PHP7 and /usr/sbin/php5-fpm on PHP5). On all other containers it should be treated as required. It can also be set explicitly on a PHP container in order to run a dedicated process such as React PHP or Amp . Upstream upstream specifies how the front server will connect to your application (the process started by commands.start above). It has two keys: socket_family: Default: tcp. Describes whether your application will listen on a Unix socket (unix) or a TCP socket (tcp). protocol: Specifies whether your application is going to receive incoming requests over HTTP (http) or FastCGI (fastcgi). The default varies depending on which application runtime you’re using. Other values will be supported in the future. On a PHP container with FPM there is almost never a reason to set the upstream explicitly, as the defaults are already configured properly for PHP-FPM. On all other containers the default is tcp and http. web:upstream:socket_family:tcpprotocol:httpThe above configuration (which is the default on non-PHP containers) will forward connections to the process started by commands.start as a raw HTTP request to a TCP port, as though the process were listening to the incoming request directly. Socket family If the socket_family is set to tcp, then your application should listen on the port specified by the PORT environment variable. (In practice it is almost always 8888, but checking the variable is preferred.) If the socket_family is set to unix, then your application should open the unix socket file specified by the SOCKET environment variable. If your application isn’t listening at the same place that the runtime is sending requests, you’ll see 502 Bad Gateway errors when you try to connect to your web site. Locations The locations block is the most powerful, and potentially most involved, section of the .platform.app.yaml file. It allows you to control how the application container responds to incoming requests at a very fine-grained level. Common patterns also vary between language containers due to the way PHP-FPM handles incoming requests. Each entry of the locations block is an absolute URI path (with leading /) and its value includes the configuration directives for how the web server should handle matching requests. That is, if your domain is example.com then \u0026#39;/\u0026#39; means “requests for example.com/”, while \u0026#39;/admin\u0026#39; means “requests for example.com/admin”. If multiple blocks could match an incoming request then the most-specific will apply. web:locations:\u0026#39;/\u0026#39;:# Rules for all requests that don\u0026#39;t otherwise match....\u0026#39;/sites/default/files\u0026#39;:# Rules for any requests that begin with /sites/default/files....The simplest possible locations configuration is one that simply passes all requests on to your application unconditionally: web:locations:\u0026#39;/\u0026#39;:passthru:trueThat is, all requests to /* should be forwarded to the process started by web.commands.start above. Note that for PHP containers the passthru key must specify what PHP file the request should be forwarded to, and must also specify a docroot under which the file lives. For example: web:locations:\u0026#39;/\u0026#39;:root:\u0026#39;web\u0026#39;passthru:\u0026#39;/app.php\u0026#39;This block will serve requests to / from the web directory in the application, and if a file doesn’t exist on disk then the request will be forwarded to the /app.php script. A full list of the possible subkeys for locations is below. root: The folder from which to serve static assets for this location relative to the application root. The application root is the directory in which the .platform.app.yaml file is located. Typical values for this property include public or web. Setting it to \u0026#39;\u0026#39; is not recommended, and its behavior may vary depending on the type of application. Absolute paths are not supported. passthru: Whether to forward disallowed and missing resources from this location to the application and can be true, false or an absolute URI path (with leading /). The default value is false. For non-PHP applications it will generally be just true or false. In a PHP application this will typically be the front controller such as /index.php or /app.php. This entry works similar to mod_rewrite under Apache. Note: If the value of passthru does not begin with the same value as the location key it is under, the passthru may evaluate to another entry. That may be useful when you want different cache settings for different paths, for instance, but want missing files in all of them to map back to the same front controller. See the example block below. index: The files to consider when serving a request for a directory: an array of file names or null. (typically [\u0026#39;index.html\u0026#39;]). Note that in order for this to work, access to the static files named must be allowed by the allow or rules keys for this location. expires: How long to allow static assets from this location to be cached (this enables the Cache-Control and Expires headers) and can be a time or -1 for no caching (default). Times can be suffixed with “ms” (milliseconds), “s” (seconds), “m” (minutes), “h” (hours), “d” (days), “w” (weeks), “M” (months, 30d) or “y” (years, 365d). scripts: Whether to allow loading scripts in that location (true or false). This directive is only meaningful on PHP. allow: Whether to allow serving files which don’t match a rule (true or false, default: true). headers: Any additional headers to apply to static assets. This section is a mapping of header names to header values. Responses from the application aren’t affected, to avoid overlap with the application’s own ability to include custom headers in the response. rules: Specific overrides for a specific location. The key is a PCRE (regular expression) that is matched against the full request path. request_buffering: Most application servers do not support chunked requests (e.g. fpm, uwsgi), so Platform.sh enables request_buffering by default to handle them. That default configuration would look like this if it was present in .platform.app.yaml: web:locations:\u0026#39;/\u0026#39;:passthru:truerequest_buffering:enabled:truemax_request_size:250mIf the application server can already efficiently handle chunked requests, the request_buffering subkey can be modified to disable it entirely (enabled: false). Additionally, applications that frequently deal with uploads greater than 250MB in size can update the max_request_size key to the application’s needs. Note that modifications to request_buffering will need to be specified at each location where it is desired. Rules The rules block warrants its own discussion as it allows overriding most other keys according to a regular expression. The key of each item under the rules block is a regular expression matching paths more specifically than the locations block entries. If an incoming request matches the rule, then its handling will be overridden by the properties under the rule. Note that it will override the entire rule in the case of a compound rule like headers. (See example below.) For example, the following file will serve dynamic requests from index.php in the public directory and disallow requests for static files anywhere. Then it sets a rule to explicitly allow common image file formats, and sets a cache lifetime for them of 5 minutes. web:locations:\u0026#39;/\u0026#39;:root:\u0026#39;public\u0026#39;passthru:\u0026#39;/index.php\u0026#39;allow:falserules:# Allow common image files you can imagine the locations and rules blocks can be used to create highly involved and powerful configurations, but obeys Parker’s Law. (With great power comes great responsibility.) The examples below demonstrate various common configurations and recommended defaults. How do I setup a basic PHP application with front-controller? The following web block is a reasonable starting point for a custom PHP application. It sets the directory public as the docroot, and any missing files will get mapped to the /index.php file. mp4 files are forbidden entirely. Image files from the images URL (which will be served from the /public/images directory) will have an expiration time set, but non-image files will be disallowed. web:locations:\u0026#39;/\u0026#39;:root:\u0026#39;public\u0026#39;passthru:\u0026#39;/index.php\u0026#39;index:- index.php# No caching for static files.# (Dynamic pages use whatever cache headers are generated by the program.)expires:-1scripts:trueallow:truerules:# Disallow .mp4 files Set a 5 min expiration time for static files here; a missing URL# will passthru to the \u0026#39;/\u0026#39; location above and hit the application# front-controller.\u0026#39;/images\u0026#39;:expires:300passthru:trueallow:falserules:# Only allow static image files from the images can I serve a static-only site? Although most websites today have some dynamic component, static site generators are a valid way to build a site. This documentation is built using a tool called Hugo, and served by Platform.sh as a static site. You can see the entire repository on GitHub. The .platform.app.yaml file it uses is listed below. Note in particular the web.commands.start directive. There needs to be some background process so it’s set to the sleep shell command, which will simply block forever (or some really long time, as computers don’t know about forever) and restart if needed. The file also runs the Hugo build process, and then specifies the files that are allowed to serve. # .platform.app.yaml# The name of this application, which must be unique within a project.name:\u0026#39;docs\u0026#39;# The type key specifies the language and version for your application.type:\u0026#39;nodejs:12\u0026#39;# The hooks that will be triggered when the package is deployed.hooks:# Build hooks can modify the application files on disk but not access any services like databases.build:!includetype:stringpath:build.shdeploy:| cp data/templates.yaml public/scripts/xss/dist/config/templates.yamlcppublic/index.jsonpublic/scripts/xss/dist/config/index.json# The configuration of the application when it is exposed to the web.web:commands:# Run a no-op process that uses no CPU resources, since this is a static site.start:sleepinfinitylocations:\u0026#39;/\u0026#39;:# The public directory of the application relative to its How can I control the headers sent with my files? There are many use cases for setting custom headers on static content, such as custom content type headers, limiting cross-origin usage, etc. Consider the following example: web:locations: / :root: public passthru: /index.php index:- the headers directive sets the X-Frame-Options header to SAMEORIGIN for all static files. That directive is then overriden by the two rules blocks. For *.mp4 files, two custom headers will be sent: X-Frame-Options and Content-Type. The repeated X-Frame-Options is necessary as the headers directive in the rule overrides the parent, rather than extending it. Therefore, the rule for *.mp3 files will add only an X-Specialness header, and no X-Frame-Options header. This example also demonstrates an effective way to set custom Content-Type headers for unusual file types using rules. Note that the headers directive applies only to static content. Headers for responses generated by your application are unaffected. If custom headers for certain file types or frame control are needed, set them from within the application. How can I rewrite an incoming request without a redirect? Rules blocks support regular expression capture groups that can be referenced in a passthru command. For example, the following configuration will result in requests to /project/123 being seen by the application as a request to /index.php?projectid=123 without causing an HTTP redirect. Note that query parameters present in the request are unaffected and will, unconditionally, appear in the request as seen by the application. web:locations:\u0026#39;/\u0026#39;:root:\u0026#39;public\u0026#39;passthru:\u0026#39;/index.php\u0026#39;index:- index.phpscripts:trueallow:truerules:\u0026#39;^/project/(?\u0026lt;projectid\u0026gt;.*)$\u0026#39;:passthru:\u0026#39;/index.php?projectid=$projectid\u0026#39;How can I serve directories at different paths than in my application? Although it’s common for the directories on disk to be served directly by the web server, that’s not actually a requirement. If desired it is quite possible to create a web URL structure that does not map 1:1 to the structure on disk. Consider the following example. The git repository is structured like so: .platform/ services.yaml routes.yaml .platform.app.yaml application/ conf/ server.ini application.py gitbook-src/ old-docs/ The application directory contains a Python application. The gitbook-src directory contains a GitBook project that is the public documentation for the application. The old-docs directory contains a static HTML backup of legacy documentation for an older version of the application that is still needed. Assume that the GitBook source is compiled by the build process into the _book directory, as in the example above. The following web block will: Start your Python application using uwsgi. Route all requests to ‘/’ to the Python application unconditionally, unless one of the following two rules apply. Route requests to the /docs path to the _book directory, which contains our generated documentation, with a short cache lifetime. Route requests to the /docs/legacy path to the old-docs directory, which contains plain old HTML, with a very long cache lifetime since those files should never change. web:commands:start:\u0026#39;uwsgi --ini application/conf/server.ini\u0026#39;locations:\u0026#39;/\u0026#39;:passthru:true\u0026#39;/docs\u0026#39;:root:\u0026#39;_book\u0026#39;index:- index.html expires:300sscripts:falseallow:true\u0026#39;/docs/legacy\u0026#39;:root:\u0026#39;old-docs\u0026#39;index:- index.html expires:4wscripts:falseallow:trueEven though the URL structure doesn’t match the directory names or hierarchy on disk, that’s no issue. It also means the application can safely coexist with static files as if it were a single site hierarchy without the need to mix the static pages in with your Python code.",
"section": "Configure your application",
"subsections": " Commands Upstream Socket family Locations Rules How do I setup a basic PHP application with front-controller? How can I serve a static-only site? How can I control the headers sent with my files? How can I rewrite an incoming request without a redirect? How can I serve directories at different paths than in my application? ",
"image": "",
"url": "/configuration/app/web.html",
"relurl": ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment