Skip to content

Commit 128b316

Browse files
authored
Merge pull request #3760 from platformsh/upsun-migrate-languages
[Upsun migration] languages section
2 parents 8a98119 + f04ad3f commit 128b316

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+5363
-2190
lines changed

sites/friday/config/_default/config.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ module:
109109
# - "integrations/*"
110110
- "integrations/activity/reference.md"
111111

112-
# - "languages/*"
113-
- "languages/java/frameworks.md"
112+
- "languages/*"
113+
#- "languages/java/frameworks.md"
114114

115115
- "learn/*"
116116

sites/friday/src/languages/_index.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
title: "Languages"
3+
weight: -90
4+
description: We sure do support a lot of runtimes.
5+
---

sites/friday/src/languages/dotnet.md

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
title: "C#/.NET Core"
3+
description: |
4+
{{% vendor/name %}} supports deploying .NET applications by allowing developers to define a build process and pass its variables to the .NET Core build environment.
5+
---
6+
7+
{{% description %}}
8+
9+
## Supported versions
10+
11+
{{% major-minor-versions-note configMinor="true" %}}
12+
13+
{{< image-versions image="dotnet" status="supported" environment="grid" >}}
14+
15+
{{% language-specification type="dotnet" display_name=".Net Core" %}}
16+
17+
```yaml {configFile="app"}
18+
applications:
19+
# The app's name, which must be unique within the project.
20+
<APP_NAME>:
21+
type: 'dotnet:<VERSION_NUMBER>'
22+
```
23+
24+
For example:
25+
26+
```yaml {configFile="app"}
27+
applications:
28+
# The app's name, which must be unique within the project.
29+
app:
30+
type: 'dotnet:{{% latest "dotnet" %}}'
31+
```
32+
33+
## Building the application
34+
35+
To build basic applications in .NET containers, it's enough to use the [`dotnet publish` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish)
36+
with the default [framework-dependent deployment](https://docs.microsoft.com/en-us/dotnet/core/deploying/#publish-framework-dependent):
37+
38+
```yaml {configFile="app"}
39+
applications:
40+
app:
41+
type: 'dotnet:{{% latest "dotnet" %}}'
42+
hooks:
43+
build: |
44+
set -xe
45+
dotnet publish --output "$PLATFORM_OUTPUT_DIR" \
46+
-p:UseRazorBuildServer=false \
47+
-p:UseSharedCompilation=false
48+
```
49+
50+
where `PLATFORM_OUTPUT_DIR` is the output directory for compiled languages available at build time.
51+
52+
Typically, .NET Core builds start a collection of build servers, which are helpful for repeated builds.
53+
On {{% vendor/name %}}, however, if this process isn't disabled,
54+
the build process doesn't finish until the idle timeout is reached.
55+
56+
As a result, you should include `-p` toggles that disable the Razor compiler for dynamic CSHTML pages (`UseRazorBuildServer`)
57+
and the .NET MSBuild compiler (`UseSharedCompilation`).
58+
59+
If you want multiple builds for your application,
60+
make sure to call `dotnet build-server shutdown` at the end of your build hook.
61+
62+
## Running the application
63+
64+
.NET Core applications should be started using the `web.commands.start` directive in `{{< vendor/configfile "app" >}}`.
65+
This ensures that the command starts at the right moment and stops gracefully when a redeployment needs to be executed.
66+
Also, should the program terminate for any reason, it's automatically restarted.
67+
Note that the start command _must_ run in the foreground.
68+
69+
Incoming requests are passed to the application using either a TCP (default) or Unix socket.
70+
The application must use the [appropriate environment variable](../create-apps/app-reference.md#where-to-listen) to determine the URI to listen on.
71+
For a TCP socket ([recommended](https://go.microsoft.com/fwlink/?linkid=874850)), the application must listen on `http://127.0.0.1`,
72+
using the `PORT` environment variable.
73+
74+
There is an Nginx server sitting in front of your application.
75+
Serving static content via Nginx is recommended, as this allows you to control headers (including cache headers)
76+
and also has marginal performance benefits.
77+
78+
Note that HTTPS is also terminated at the Nginx proxy,
79+
so the `app.UseHttpsRedirection();` line in `Startup.cs` should be removed.
80+
To force HTTPS-only, refer to the [routes documentation](../define-routes/https.md#enable-https).
81+
82+
The following example configures an environment to serve the static content folders commonly found in [ASP.NET MVC](https://dotnet.microsoft.com/apps/aspnet/mvc) templates using Nginx,
83+
while routing other traffic to the .NET application.
84+
85+
```yaml {configFile="app"}
86+
applications:
87+
app:
88+
type: 'dotnet:{{% latest "dotnet" %}}'
89+
web:
90+
locations:
91+
"/":
92+
root: "wwwroot"
93+
allow: true
94+
passthru: true
95+
rules:
96+
# Serve these common asset types with customs cache headers.
97+
\.(jpe?g|png|gif|svgz?|css|js|map|ico|bmp|eot|woff2?|otf|ttf)$:
98+
allow: true
99+
expires: 300s
100+
commands:
101+
start: "dotnet WebApplication1.dll"
102+
```
103+
104+
You can also route all requests to the application unconditionally:
105+
106+
```yaml {configFile="app"}
107+
applications:
108+
app:
109+
type: 'dotnet:{{% latest "dotnet" %}}'
110+
web:
111+
locations:
112+
"/":
113+
allow: false
114+
passthru: true
115+
116+
commands:
117+
start: "dotnet WebApplication1.dll"
118+
```
119+
120+
{{< repolist lang="dotnet" displayName=".NET Core" >}}

sites/friday/src/languages/elixir.md

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: "Elixir"
3+
description: "{{% vendor/name %}} supports building and deploying applications written in Elixir. There is no default flavor for the build phase, but you can define it explicitly in your build hook. {{% vendor/name %}} Elixir images support both committed dependencies and download-on-demand. The underlying Erlang version is 22.0.7."
4+
---
5+
6+
{{% description %}}
7+
8+
## Supported versions
9+
10+
{{% major-minor-versions-note configMinor="true" %}}
11+
12+
{{< image-versions image="elixir" status="supported" environment="grid" >}}
13+
14+
15+
{{% language-specification type="elixir" display_name="Elixir" %}}
16+
17+
```yaml {configFile="app"}
18+
applications:
19+
# The app's name, which must be unique within the project.
20+
<APP_NAME>:
21+
type: 'elixir:<VERSION_NUMBER>'
22+
```
23+
24+
For example:
25+
26+
```yaml {configFile="app"}
27+
applications:
28+
# The app's name, which must be unique within the project.
29+
app:
30+
type: 'elixir:{{% latest "elixir" %}}'
31+
```
32+
33+
## Built-in variables
34+
35+
{{% vendor/name %}} exposes relationships and other configuration as [environment variables](../development/variables/_index.md).
36+
Most notably, it allows a program to determine at runtime what HTTP port it should listen on
37+
and what the credentials are to access [other services](../add-services/_index.md).
38+
39+
To get the `PORT` environment variable (the port on which your web application is supposed to listen) you would:
40+
41+
```elixir
42+
String.to_integer(System.get_env("PORT") || "8888")
43+
```
44+
45+
Some of the environment variables are in JSON format and are base64 encoded. You would need to import a JSON parsing library such as [JSON](https://hexdocs.pm/json/readme.html) or [Poison](https://hexdocs.pm/poison/api-reference.html) to read those. (There is an example for doing this to decode the `PLATFORM_RELATIONSHIPS` environment variable in the section [below](#accessing-services-manually).)
46+
47+
{{< note title="Tip">}}
48+
Remember `config/prod.exs` is evaluated at **build time** and has no access to runtime configuration. Use `config/releases.exs` to configure your runtime environment.
49+
{{< /note >}}
50+
51+
## Building and running the application
52+
53+
If you are using Hex to manage your dependencies, you need to specify the `MIX_ENV` environment variable:
54+
55+
```yaml {configFile="app"}
56+
applications:
57+
app:
58+
type: 'elixir:{{% latest "elixir" %}}'
59+
variables:
60+
env:
61+
MIX_ENV: 'prod'
62+
```
63+
The `SECRET_KEY_BASE` variable is generated automatically based on the [`PLATFORM_PROJECT_ENTROPY` variable](../development/variables/use-variables.md#use-provided-variables).
64+
You can change it.
65+
66+
Include in your build hook the steps to retrieve a local Hex and `rebar`, and then run `mix do deps.get, deps.compile, compile` on your application to build a binary.
67+
68+
```yaml {configFile="app"}
69+
applications:
70+
app:
71+
type: 'elixir:{{% latest "elixir" %}}'
72+
hooks:
73+
build: |
74+
mix local.hex --force
75+
mix local.rebar --force
76+
mix do deps.get --only prod, deps.compile, compile
77+
```
78+
79+
{{< note >}}
80+
81+
That build hook works for most cases and assumes that your `mix.exs` file is located at [your app root](../create-apps/app-reference.md#root-directory).
82+
83+
{{< /note >}}
84+
85+
Assuming `mix.exs` is present at your app root and your build hook matches the above,
86+
you can then start it from the `web.commands.start` directive.
87+
88+
The following basic app configuration is sufficient to run most Elixir applications.
89+
90+
91+
```yaml {configFile="app"}
92+
applications:
93+
app:
94+
type: 'elixir:{{% latest "elixir" %}}'
95+
96+
variables:
97+
env:
98+
MIX_ENV: 'prod'
99+
100+
hooks:
101+
build: |
102+
mix local.hex --force
103+
mix local.rebar --force
104+
mix do deps.get --only prod, deps.compile, compile
105+
106+
web:
107+
commands:
108+
start: mix phx.server
109+
locations:
110+
/:
111+
allow: false
112+
passthru: true
113+
```
114+
115+
Note that there is still an Nginx proxy server sitting in front of your application. If desired, certain paths may be served directly by Nginx without hitting your application (for static files, primarily) or you may route all requests to the Elixir application unconditionally, as in the example above.
116+
117+
## Dependencies
118+
119+
The recommended way to handle Elixir dependencies on {{% vendor/name %}} is using Hex.
120+
You can commit a `mix.exs` file in your repository and the system downloads the dependencies in your `deps` section using the build hook above.
121+
122+
```elixir
123+
defp deps do
124+
[
125+
{:platformshconfig, "~> 0.1.0"}
126+
]
127+
end
128+
```
129+
130+
## Accessing Services
131+
132+
{{% access-services version="2" %}}
133+
134+
### Accessing Services Manually
135+
136+
The services configuration is available in the environment variable `PLATFORM_RELATIONSHIPS`.
137+
138+
Given a relationship defined in `{{< vendor/configfile "app" >}}`:
139+
140+
```yaml {configFile="app"}
141+
applications:
142+
app:
143+
type: 'elixir:{{% latest "elixir" %}}'
144+
...
145+
relationships:
146+
postgresdatabase: "dbpostgres:postgresql"
147+
```
148+
149+
Assuming you have in `mix.exs` the Poison library to parse JSON:
150+
151+
```elixir
152+
defp deps do
153+
[
154+
{:poison, "~> 3.0"}
155+
]
156+
end
157+
```
158+
159+
And assuming you use `ecto` you could put in `config/config.exs`:
160+
161+
```elixir
162+
relationships = Poison.decode!(Base.decode64!(System.get_env("PLATFORM_RELATIONSHIPS")))
163+
[postgresql_config | _tail] = relationships["postgresdatabase"]
164+
165+
config :my_app, Repo,
166+
database: postgresql_config["path"],
167+
username: postgresql_config["username"],
168+
password: postgresql_config["password"],
169+
hostname: postgresql_config["host"]
170+
```
171+
172+
and setup Ecto during the deploy hook:
173+
174+
```yaml
175+
deploy: |
176+
mix do ecto.setup
177+
```

0 commit comments

Comments
 (0)