mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-05 09:21:54 +02:00
commit
5e4c44a444
27 changed files with 951 additions and 15 deletions
30
docs/architecture/decisions/0007-python-buildpack.md
Normal file
30
docs/architecture/decisions/0007-python-buildpack.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# 7. Python Buildpack
|
||||
|
||||
Date: 2022-08-12
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
We had previously drafted ADRs to use Docker to build images for containerized deployment. The motivation was to reduce dependency on Cloud.gov. These ADRs were rejected, mainly owing to the necessity of having an image repository to hold the built images. The team had concerns about an overreliance on GitHub with their GitHub Packages service and about the overall maintenance burden of any image repository.
|
||||
|
||||
Cloud.gov uses Cloud Foundry which provides several “buildpacks”. These are automated environments which will take a code repository of a certain language and do the usual setup steps to prepare a deployment of that code. In the case of Python, this means automated detection of Pipfile and installation of packages.
|
||||
|
||||
We do not anticipate needing a custom buildpack, because our current use case falls completely within the Python buildpack's purview.
|
||||
|
||||
## Decision
|
||||
|
||||
To use Cloud Foundry’s Python buildpack.
|
||||
|
||||
## Consequences
|
||||
|
||||
There will be a small amount of future work if the code is migrated off of Cloud.gov, but only a small amount. Proportionate to the overall effort of migration, it is inconsequential.
|
||||
|
||||
Cloud.gov provides [documentation around the trade-offs](https://cloud.gov/docs/deployment/docker/):
|
||||
|
||||
| | Supported buildpack | Docker container |
|
||||
|---|---|---|
|
||||
|Pros|It “just works”. Automatic and constant security updates. All you need to do is write code.|Can build container images and run containers on local workstation. Fine-grained control over compilation and root filesystem.|
|
||||
|Cons|Difficult to recreate the execution environment locally. Testing compilation and the result of staging is harder.|Added responsibility for all security updates and bug fixes. More compliance responsibility means more work.|
|
25
docs/architecture/decisions/0008-server-side-rendering.md
Normal file
25
docs/architecture/decisions/0008-server-side-rendering.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# 8. Server Side Rendering
|
||||
|
||||
Date: 2022-08-16
|
||||
|
||||
## Status
|
||||
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
In deciding how content would be delivered to the end user, we held a meeting with Engineering and Design ~and the mayor of Igorville~ [^1] and consulted the [18F Engineering Practices Guide](https://engineering.18f.gov/web-architecture/).
|
||||
|
||||
The two major options considered were 1) a single page application, developed with a JavaScript framework such as React, perhaps served from its own Node-based server or a static file host such as Federalist; or 2) traditional server rendered HTML pages, delivered by Django, accompanied by a small amount of JavaScript and CSS.
|
||||
|
||||
## Decision
|
||||
|
||||
To use server-side rendering performed by Django.
|
||||
|
||||
## Consequences
|
||||
|
||||
The positive aspects of this include: easier state management, fewer bugs caused by stale cache data, easier 508 compliance for disabled users, better maintainability for future developers due to fewer dependencies and a shallower learning curve, and better cross browser compatibility.
|
||||
|
||||
The risks to this approach are given by the frontend lead on a sister 18F project: a less well-developed API since this approach does not require an API upfront, users/stakeholders attempting to request ever increasing levels of interactivity, and familiarity with vanilla.js has waned over the years.
|
||||
|
||||
[^1]: Inside joke. To obtain access to the registrant flow, a member of our team signed up for .gov using the fictitious town of Igorville.
|
41
docs/architecture/diagrams/request.dot
Normal file
41
docs/architecture/diagrams/request.dot
Normal file
|
@ -0,0 +1,41 @@
|
|||
digraph sequenceDiagram {
|
||||
# Install graphviz and run `fdp -Tpng request.dot -o request_diagram.png`
|
||||
subgraph cluster_1 {
|
||||
label="Request and Response";
|
||||
browserHead [ label="{Browser|user makes request}" pos="0.1,4.75!" shape="record" ];
|
||||
browserPoint0 [ pos="0.1,4!" shape="point" width="0" ]
|
||||
browserPoint5 [ pos="0.1,0.75!" shape="point" width="0" ]
|
||||
browserFoot [ label="Browser" pos="0,0!" shape="record" ];
|
||||
|
||||
viewHead [ label="{Django Views|business logic applied}" pos="2.5,4.75!" shape="record" ];
|
||||
viewPoint0 [ pos="2.5,4!" shape="point" width="0" ]
|
||||
viewPoint1 [ pos="2.5,3.75!" shape="point" width="0" ]
|
||||
viewPoint2 [ pos="2.5,3.5!" shape="point" width="0" ]
|
||||
viewPoint3 [ pos="2.5,1.25!" shape="point" width="0" ]
|
||||
viewPoint4 [ pos="2.5,1!" shape="point" width="0" ]
|
||||
viewPoint5 [ pos="2.5,0.75!" shape="point" width="0" ]
|
||||
viewFoot [ label="Django view" pos="2.5,0!" shape="record" ];
|
||||
|
||||
databaseHead [ label="{Django ORM|database consulted}" pos="5,4.75!" shape="record" ];
|
||||
databasePoint1 [ pos="5,3.75!" shape="point" width="0" ]
|
||||
databasePoint2 [ pos="5,3.5!" shape="point" width="0" ]
|
||||
databaseFoot [ label="Django ORM" pos="5,2.5!" shape="record" ];
|
||||
|
||||
templateHead [ label="{Django Templates|html response prepared}" pos="5,2.25!" shape="record" ];
|
||||
templatePoint3 [ pos="5,1.25!" shape="point" width="0" ]
|
||||
templatePoint4 [ pos="5,1!" shape="point" width="0" ]
|
||||
templateFoot [ label="Django Templates" pos="5,0!" shape="record" ];
|
||||
|
||||
browserHead -> browserPoint0 -> browserFoot [ dir="none" style="dashed" ]
|
||||
viewHead -> viewPoint0 -> viewFoot [ dir="none" style="dashed" ]
|
||||
databaseHead -> databasePoint1 -> databaseFoot [ dir="none" style="dashed" ]
|
||||
templateHead -> templatePoint3 -> templateFoot [ dir="none" style="dashed" ]
|
||||
|
||||
browserPoint0 -> viewPoint0 [ style="solid" ]
|
||||
viewPoint1 -> databasePoint1 [ style="solid" ]
|
||||
databasePoint2 -> viewPoint2 [ style="solid" ]
|
||||
viewPoint3 -> templatePoint3 [ style="solid" ]
|
||||
templatePoint4 -> viewPoint4 [ style="solid" ]
|
||||
viewPoint5 -> browserPoint5 [ style="solid" ]
|
||||
}
|
||||
}
|
BIN
docs/architecture/diagrams/request_diagram.png
Normal file
BIN
docs/architecture/diagrams/request_diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
22
docs/architecture/diagrams/system.dot
Normal file
22
docs/architecture/diagrams/system.dot
Normal file
|
@ -0,0 +1,22 @@
|
|||
digraph systemDiagram {
|
||||
# Install graphviz and run `fdp -Tpng system.dot -o system_diagram.png`
|
||||
subgraph cluster_0 {
|
||||
label="System Diagram";
|
||||
node [shape=record];
|
||||
registrant [label="Registrant"];
|
||||
subgraph cluster_cloud {
|
||||
label="cloud.gov";
|
||||
node [shape=record];
|
||||
postgres [label="Postgres Database"];
|
||||
subgraph cluster_django {
|
||||
label="Django MVC";
|
||||
node [shape=record];
|
||||
models [pos="0,1!" label="Database ORM"];
|
||||
views [pos="1,.5!" label="Views"];
|
||||
templates [pos="1,0!" label="Templates"];
|
||||
}
|
||||
}
|
||||
registrant -> views [dir=both];
|
||||
models -> postgres [dir=both];
|
||||
}
|
||||
}
|
BIN
docs/architecture/diagrams/system_diagram.png
Normal file
BIN
docs/architecture/diagrams/system_diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
59
docs/ops/README.md
Normal file
59
docs/ops/README.md
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Operations
|
||||
========================
|
||||
|
||||
## Authenticating
|
||||
|
||||
You'll need the [Cloud Foundry CLI](https://docs.cloud.gov/getting-started/setup/).
|
||||
|
||||
We use the V7 Cloud Foundry CLI.
|
||||
|
||||
```shell
|
||||
cf login -a api.fr.cloud.gov --sso
|
||||
```
|
||||
|
||||
After authenticating, make sure you are targeting the correct org and space!
|
||||
|
||||
```bash
|
||||
cf spaces
|
||||
cf target -o <ORG> -s <SPACE>
|
||||
```
|
||||
|
||||
## Rotating Environment Secrets
|
||||
|
||||
Secrets were originally created with:
|
||||
|
||||
```sh
|
||||
cf cups getgov-credentials -p credentials-<ENVIRONMENT>.json
|
||||
```
|
||||
|
||||
Where `credentials-<ENVIRONMENT>.json` looks like:
|
||||
|
||||
```json
|
||||
{
|
||||
"DJANGO_SECRET_KEY": "EXAMPLE",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You can see the current environment with `cf env <APP>`, for example `cf env getgov-unstable`.
|
||||
|
||||
The command `cups` stands for [create user provided service](https://docs.cloudfoundry.org/devguide/services/user-provided.html). User provided services are the way currently recommended by Cloud.gov for deploying secrets. The user provided service is bound to the application in `manifest-<ENVIRONMENT>.json`.
|
||||
|
||||
To rotate secrets, create a new `credentials-<ENVIRONMENT>.json` file, upload it, then restage the app.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
cf uups getgov-credentials -p credentials-unstable.json
|
||||
cf restage getgov-unstable --strategy rolling
|
||||
```
|
||||
|
||||
Non-secret environment variables can be declared in `manifest-<ENVIRONMENT>.json` directly.
|
||||
|
||||
## Database
|
||||
|
||||
In sandbox, created with `cf create-service aws-rds micro-psql getgov-database`.
|
||||
|
||||
Binding the database in `manifest-<ENVIRONMENT>.json` automatically inserts the connection string into the environment as `DATABASE_URL`.
|
||||
|
||||
[Cloud.gov RDS documentation](https://cloud.gov/docs/services/relational-database/).
|
Loading…
Add table
Add a link
Reference in a new issue