Architect.io Docs

Best Practices

Follow these best practices to help you get the most out of Architect.

Component names

A component name is used in the architect.yml component file that defines services, tasks, interfaces, and secrets. A component name can include lowercase letters, numbers, underscores, and dashes. Component names can't start or end with a dash or underscore. The maximum length is 32 characters.

Examples:

my-component
my-component-2
my_third_component

Example usage:

# architect.yml
...
name: my-component
...

Component versions

An architect component version, or tag, is created when a component is registered with the Architect Cloud. The --tag or -t flag of the architect register command can be used to specify the name of the version. Architect components can have multiple versions similar to any package manager. Component versions can contain alphanumeric characters, periods, dashes, and underscores. The maximum length of a component version is 128 characters.

Examples:

0.0.1
second-version
third_component_version

Example usage:

architect register architect.yml --tag=0.0.1

or

architect register architect.yml -t 0.0.1

Parameterizing services

Secrets should be used frequently in the architect.yml component file for configurable values between local or remote deployments. This ensures that applications maintain portability.

Examples include:

  • An environment variable that needs to change between dev and prod
  • A value for the desired number of replicas for a service
  • An API key for a third-party service that helps to power your application

Secrets help avoid hardcoded values for things that may change between local development and production, such as an API address or a database username/password.

Similarly, services defined in the component configuration file shouldn't have hardcoded values when referencing one another. This is because Architect will dynamically detect connections between services and dependencies and generate them at deployment time. This applies to both service and dependency references.

Volumes

Volumes are important in local and production-grade deployments to persist data between container lifecycles. Local deployments can also leverage volumes used in the component config's debug block to support hot reloading.

Local volumes

Hot reloading

Hot reloading allows users to make changes to their application or component without the need to redeploy. Code is shared between the host machine and the container running the application. This feature is only needed for local deployments, so a volume is configured through a debug block within the architect.yml file.

Below is an example using a volume in the debug block:

# architect.yml
...
services:
my-service:
debug:
volumes:
src:
mount_path: /usr/src/app/src # The location of the code within the Docker container
host_path: ./api/src # The location of the code relative to the architect.yml file on the host machine
...

Note that the application running in the container should be configured to support hot reloading. This will vary depending on your framework. For example, node applications would need to utilize the nodemon package for hot reloading.

Debug volumes

Data persistence should also be considered when running local deployments with architect. Using volumes, data can be shared between the container and the host machine so that even as the local stack spins up and down, the data being used to debug won't disappear. This is especially useful in cases where it's important to retain data from a database. An example is below:

# architect.yml
...
services:
api-db:
image: postgres:14
interfaces:
postgres:
port: 5432
protocol: postgresql
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: api_database
debug:
volumes:
data:
mount_path: /var/lib/api/postgres
...

Setting only the mount_path of a debug volume will automatically provision a Docker volume on the host machine. In order to store the data directly on the host machine instead of inside of a Docker volume, include a host_path as well.

When changing the service name, the volume name, or the architect dev environment name (via architect dev -e <env-name>), a new volume will be provisioned if mount_path is used in the volume config without a host_path.

Remote volumes

Any data stored directly on the filesystem of a Kubernetes pod shouldn't be expected to be persistent. For that reason, important data should be stored in a volume and added to the service similar to the following:

# architect.yml
...
services:
my-service:
volumes:
my-volume:
mount_path: /usr/app/images
key: my-persistent-volume-claim
...

Service dependencies

When using a service that depends on another service to be fully operational first, a depends_on block can be added to the service definition of the dependent service. An example of this is an API requiring a database service to run before the API can start up. The depends_on block ensures that services are deployed sequentially.

Take a simple web service named my-service which will fail to start if it cannot connect to the database service. A depends_on block can be added to my-service, which will ensure that the database has been spun up before trying to start my-service.

Below is a snippet of an Architect component file to demonstrate what this would look like.

# architect.yml
...
services:
my-service:
depends_on:
- database
...
database:
interfaces:
postgres:
port: 5432
...

Using Third-party or Cloud Services

Host overrides are used to replace Architect services with third-party services, such as databases. Check out an example configuration.

Ensuring service health

The Architect service configuration includes a liveness_probe block to configure a check that ensures service health. It can let a container environment know when to restart a service if for some reason the container becomes unhealthy. When configuring the command for the liveness probe, ensure that the command used (ex. curl) is installed in the Docker image for the service.

No results found for query ""