-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
70 changed files
with
9,175 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
docs/versioned_docs/* linguist-vendored | ||
docs/versioned_sidebars/* linguist-vendored |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
--- | ||
title: Deployment | ||
--- | ||
|
||
import DocCard from '@theme/DocCard'; | ||
|
||
The section explains the steps involved when it comes to deploying a Marten project. It also gives useful tips in order to secure Marten web applications in production. | ||
|
||
## Guides | ||
|
||
<div className="row"> | ||
<article key="introduction" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./deployment/introduction", label: "Introduction", docId: "deployment/introduction" }} /> | ||
</article> | ||
</div> |
118 changes: 118 additions & 0 deletions
118
docs/versioned_docs/version-0.1/deployment/introduction.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
--- | ||
title: Deploying Marten projects | ||
description: Learn about the things to consider when deploying Marten web applications. | ||
sidebar_label: Introduction | ||
--- | ||
|
||
This section describes what's involved when it comes to deploying a Marten web application and highlights some important things to consider before performing deploys. | ||
|
||
## Overview | ||
|
||
Each deployment pipeline is unique and will vary from one project to another. That being said, a few things and requirements will be commonly encountered when it comes to deploying a Marten projects: | ||
|
||
1. installing your project's dependencies | ||
2. compiling your project's server and [management CLI](../development/management-commands) | ||
3. collecting your project's [assets](../files/asset-handling) | ||
4. applying any pending migrations to your database | ||
5. starting the compiled server | ||
|
||
Where, when, and how these steps are performed will vary from one project to another. Each of these steps is highlighted below along with some recommendations. | ||
|
||
### Installing dependencies | ||
|
||
One of the first things you need to do when deploying a Marten project is to ensure that the dependencies of the projects are available. In this light, you can leverage the `shards install` command in order to install your project's Crystal dependencies (assuming that Crystal is installed on your destination machine). Obviously your project may require the installation of other types of dependencies (such as Node.js dependencies for example), which you have to take care as well. | ||
|
||
### Compiling your project | ||
|
||
Your project server and [management CLI](../development/management-commands) need to be compiled in order to run your project's server and to execute additional deployment-related management commands (eg. in order to [collect assets](#collecting-assets) or [apply migrations](#applying-migrations)). | ||
|
||
When it comes to your project server, you will usually need to compile the `src/server.cr` file (which is automatically created when generating new projects via the [`new`](../development/reference/management-commands#new) management command). This can be achieved with the following command: | ||
|
||
```bash | ||
crystal build src/server.cr -o bin/server --release | ||
``` | ||
|
||
:::tip | ||
In the above example, the server binary is compiled using the `-o bin/server` option, which ensures that the compiled binary will be named `server` and stored under the related `bin` folder. You should obviously adapt this to your production environment. | ||
::: | ||
|
||
The [management CLI](../development/management-commands) is provided by the `manage.cr` file located at the root of your project. As usual, this file is also automatically generated for you when creating Marten projects through the use of the [`new`](../development/reference/management-commands#new) management command. Compiling this binary can be done with the following command: | ||
|
||
```bash | ||
crystal build manage.cr -o bin/manage --release | ||
``` | ||
|
||
:::info | ||
The above compilation commands make use of the `--release` flag, which enables compiler optimizations. As a result, the compilation of the final binaries may take quite some time depending on your project. You can also avoid using `--release` if needed but technically performances could be impacted. See [Release builds](https://crystal-lang.org/reference/man/crystal/index.html#release-builds) for more details on this subject. | ||
::: | ||
|
||
### Collecting assets | ||
|
||
You need to ensure that your project and applications assets (eg. JavaScripts, CSS files, etc) are "collected" at deploy time so that they are placed at the final destination from which they will be served: this operation is made available through the use of the [`collectassets`](../development/reference/management-commands#collectassets) management command. This "destination" depends on your deployment strategy and your configured [assets settings](../development/reference/settings#assets-settings): it can be as simple as moving all these assets to a dedicated folder in your server (so that they can be served by your web server), or it can involve uploading these assets to an S3 or GCS bucket for example. | ||
|
||
In order to collect assets at deploy time, you will want to use the compiled `manage` binary and run the [`collectassets`](../development/reference/management-commands#collectassets) management command (as mentioned previously) with the `--no-input` flag set in order to disable user prompts: | ||
|
||
```bash | ||
bin/manage collectassets --no-input | ||
``` | ||
|
||
:::info | ||
The assets handling documentation also provides a few [guidelines](../files/asset-handling#serving-assets-in-production) on how to serve asset files in production that may be worth reading. | ||
::: | ||
|
||
### Applying migrations | ||
|
||
You projects will likely make use of models, which means that you will need to ensure that those are properly created at your configured database level by running the associated migrations. | ||
|
||
To do so, you can use the compiled `manage` binary and run the [`migrate`](../development/reference/management-commands#migrate) management command: | ||
|
||
```bash | ||
bin/manage migrate | ||
``` | ||
|
||
Please refer to [Migrations](../models-and-databases/migrations) to learn more about model migrations. | ||
|
||
### Running the server | ||
|
||
You can run the compiled Marten server using the following command (obviously the location of the binary depends on [how the compilation was actually performed](#compiling-your-project)): | ||
|
||
```bash | ||
bin/server | ||
``` | ||
|
||
It's important to note that the Marten server is intended to be used behind a reverse proxy such as [Nginx](https://www.nginx.com/) or [Apache](https://httpd.apache.org/): you will usually want to configure such reverse proxy so that it targets your configured Marten server host and port. In this light, you should ensure that your Marten server is not using the HTTP port 80 (instead it could use something like 8080 or 8000 for example). | ||
|
||
Depending on your use cases, a reverse proxy will also allow you to easily serve other contents such as [assets](../files/asset-handling) or [uploaded files](../files/managing-files), and to use SSL/TLS. | ||
|
||
:::tip | ||
It is possible to run multiple processes of the same server behind a reverse proxy such as Nginx. Indeed, each compiled server can accept optional parameters in order to override the host and / or port being used. These parameter are respectively `--bind` (or `-b`) and `--port` (or `-p`). For example: | ||
|
||
```bash | ||
bin/server -b 127.0.0.1 | ||
bin/server -p 8080 | ||
``` | ||
::: | ||
|
||
## Additional tips | ||
|
||
This section lists a few additional things to consider when deploying Marten projects. | ||
|
||
### Secure critical setting values | ||
|
||
You should pay attention to the value of some of your settings in production environments. | ||
|
||
#### Debug mode | ||
|
||
You should ensure that the [`debug`](../development/reference/settings#debug) setting is always set to `false` in production environments. Indeed, the debug mode can help for development purposes because it outputs useful tracebacks and site-related information. But there is a risk that all this information leaks somewhere if you enable this mode in production. | ||
|
||
#### Secret key | ||
|
||
You should ensure that the value of the [`secret_key`](../development/reference/settings#secret_key) setting is not hardcoded in your [config files](../development/settings). Indeed, this setting value must be kept secret and you should ensure that it's loaded dynamically instead. For example, this setting's value could be set in a dedicated environment variable (or dotenv file) and loaded as follows: | ||
|
||
```crystal | ||
Marten.configure do |config| | ||
config.secret_key = ENV.fetch("MARTEN_SECRET_KEY") { raise "Missing MARTEN_SECRET_KEY env variable" } | ||
# [...] | ||
end | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
--- | ||
title: Development | ||
--- | ||
|
||
import DocCard from '@theme/DocCard'; | ||
|
||
Marten provides various tools and mechanisms that you can leverage in order to develop, structure, and test projects and applications. | ||
|
||
## Guides | ||
|
||
<div className="row"> | ||
<article key="settings" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./development/settings", label: "Settings", docId: "development/settings" }} /> | ||
</article> | ||
<article key="applications" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./development/applications", label: "Applications", docId: "development/applications" }} /> | ||
</article> | ||
<article key="management-commands" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./development/management-commands", label: "Management commands", docId: "development/management-commands" }} /> | ||
</article> | ||
<article key="testing" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./development/testing", label: "Testing", docId: "development/testing" }} /> | ||
</article> | ||
</div> | ||
|
||
## How-to's | ||
|
||
<div className="row"> | ||
<article key="create-custom-commands" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./development/how-to/create-custom-commands", label: "Create custom commands", docId: "development/how-to/create-custom-commands" }} /> | ||
</article> | ||
</div> | ||
|
||
## Reference | ||
|
||
<div className="row"> | ||
<article key="settings" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./development/reference/settings", label: "Settings", docId: "development/reference/settings" }} /> | ||
</article> | ||
<article key="management-commands" className="col col--6"> | ||
<DocCard item={{type: "link", href: "./development/reference/management-commands", label: "Management commands", docId: "development/reference/management-commands" }} /> | ||
</article> | ||
</div> |
119 changes: 119 additions & 0 deletions
119
docs/versioned_docs/version-0.1/development/applications.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
--- | ||
title: Applications | ||
description: Learn how to leverage applications to structure your projects. | ||
sidebar_label: Applications | ||
--- | ||
|
||
Marten projects can be organized into logical and reusable components called "applications". These applications can contribute specific behaviors and abstractions to a project, including [models](../models-and-databases), [handlers](../handlers-and-http), and [templates](../templates). They can be packaged and reused across various projects as well. | ||
|
||
## Overview | ||
|
||
A Marten **application** is a set of abstractions (defined under a dedicated and unique folder) that provides some set of features. These abstractions can correspond to [models](../models-and-databases), [handlers](../handlers-and-http), [templates](../templates), [schemas](../schemas/), etc. | ||
|
||
Marten projects always use one or many applications. Indeed, each Marten project comes with a default [main application](#the-main-application) that corresponds to the standard `src` folder: models, migrations, or other classes defined in this folder are associated with the main application by default (unless they are part of another _explicitly defined_ application). As projects grow in size and scope, it is generally encouraged to start thinking in terms of applications and how to split models, handlers, or features accross multiple apps depending on their intended responsibilities. | ||
|
||
Another benefit of applications is that they can be packaged and reused across multiple projects. This allows third-party libraries and shards to easily contribute models, migrations, handlers, or templates to other projects. | ||
|
||
## Using applications | ||
|
||
The use of application must be manually enabled within projects: this is done through the use of the [`installed_apps`](./reference/settings#installedapps) setting. | ||
|
||
This setting corresponds to an array of installed app classes. Indeed, each Marten application must define a subclass of [`Marten::App`](pathname:///api/Marten/App.html) in order to specify a few things such as the application label (see [Creating applications](#creating-applications) for more information about this). When those subclasses are specified in the `installed_apps` setting, the applications' models, migrations, assets, and templates will be made available to the considered project. | ||
|
||
For example: | ||
|
||
```crystal | ||
Marten.configure do |config| | ||
config.installed_apps = [ | ||
FooApp, | ||
BarApp, | ||
] | ||
end | ||
``` | ||
|
||
Adding an application class inside this array will have the following impact on the considered project: | ||
|
||
* the models of this application and the associated migrations will be used | ||
* the templates of the application will be made available to the templates engine | ||
* the assets of the application will be made available to the assets engine | ||
* the management commands defined by the application will be made available to the Marten CLI | ||
|
||
### The main application | ||
|
||
The "main" application is a default application that is always implicitly used by Marten projects (which means that it does not appear in the [`installed_apps`](./reference/settings#installedapps) setting). This application is associated with the standard `src` folder: this means that models, migrations, assets, or templates defined in this folder will be associated with the main application by default. For example, models defined under a `src/models` folder would be associated with the main application. | ||
|
||
:::info | ||
The main application is associated with the `main` label. This means that models of the main application that do not define an explicit table name will have table names starting with `main_`. | ||
::: | ||
|
||
It should be noted that it is possible to create _explicitly defined_ applications whose structures live under the `src` folder as well: the abstractions (eg. models, migrations, etc) of these applications will be associated with them and _not_ with the main application. This is because abstractions are always associated with the closest application in the files and folders structure. | ||
|
||
In the end, the main application provides a convenient way for starting projects and prototyping without requiring to spec out how projects will be organized in terms of applications upfront. That being said, as projects grow in size and scope, it is really encouraged to start thinking in terms of applications and how to split abstractions and features accross multiple apps depending on their intended responsibilities. | ||
|
||
### Order of installed applications | ||
|
||
You should note that the order in which installed applications are defined in the [`installed_apps`](./reference/settings#installedapps) setting can actually matter. | ||
|
||
For example, a "foo" app might define a `test.html` template, and a similar template with the exact same name might be defined by a "bar" app. If the "foo" app appears before the "bar" app in the array of installed app, then requesting and rendering the `test.html` template will actually involve the "foo" app's template only. This is because template loaders associated with app directories iterate over applications in the order in which they are defined in the installed apps array. | ||
|
||
This is why it is always important to _namespace_ abstractions, assets, templates, and locales when creating applications. Failing to do so exposes apps to conflicts with other applications' code. As such, in the previous example the "foo" app should've defined a `foo/test.html` template while the "bar" app should've defined a `bar/test.html` template to avoid possible conflicts. | ||
|
||
## Creating applications | ||
|
||
Creating applications can be done very easily through the use of the [`new`](./reference/management-commands#new) management command. For example: | ||
|
||
```bash | ||
marten new app blog src/blog | ||
``` | ||
|
||
Running such command will usually create the following directory structure: | ||
|
||
``` | ||
src/blog | ||
├── handlers | ||
├── migrations | ||
├── models | ||
├── schemas | ||
├── templates | ||
├── app.cr | ||
└── cli.cr | ||
``` | ||
|
||
These files and folders are described below: | ||
|
||
| Path | Description | | ||
| ----------- | ----------- | | ||
| handlers/ | Empty directory where the request handlers of the application will be defined. | | ||
| migrations/ | Empty directory that will store the migrations that will be generated for the models of the application. | | ||
| models/ | Empty directory where the models of the application will be defined. | | ||
| schemas/ | Empty directory where the schemas of the application will be defined. | | ||
| templates/ | Empty directory where the templates of the application will be defined. | | ||
| app.cr | Definition of the application configuration abstraction; this is also where application files requirements should be defined. | | ||
| cli.cr | Requirements of CLI-related files, such as migrations for example. | | ||
|
||
The most important file of an application is the `app.cr` one. This file usually includes all the app requirements and defines the application configuration class itself, which must be a subclass of the [`Marten::App`](pathname:///api/Marten/App.html) abstract class. This class allows mainly to define the "label" identifier of the application (through the use of the [`#label`](pathname:///api/Marten/Apps/Config.html#label(label%3AString|Symbol)-class-method) class method): this identifier must be unique across all the installed applications of a project and is used to generate things like model table names or migration classes. | ||
|
||
Here is an example `app.cr` file content for an hypothetic "blog" app: | ||
|
||
```crystal | ||
require "./handlers/**" | ||
require "./models/**" | ||
require "./schemas/**" | ||
module Blog | ||
class App < Marten::App | ||
label "blog" | ||
end | ||
end | ||
``` | ||
|
||
:::info | ||
_Where_ the `app.cr` file is located is important: the directory where this file is defined is also the directory where key folders like `models`, `migrations`, `templates`, etc, must be present. This is necessary to ensure that these files and abstractions are associated with the considered app. | ||
::: | ||
|
||
Another very important file is the `cli.cr` one: this file is there to define all the CLI-related requirements and will usually be required directly by your project's `manage.cr` file. _A minima_ the `cli.cr` file should require model migrations, but it could also require the management commands provided by the application. For example: | ||
|
||
```crystal | ||
require "./cli/**" | ||
require "./migrations/**" | ||
``` |
Oops, something went wrong.