diff --git a/nomad_jobs/services/penpot/penpot.nomad.hcl b/nomad_jobs/services/penpot/penpot.nomad.hcl new file mode 100644 index 0000000..47bfbd4 --- /dev/null +++ b/nomad_jobs/services/penpot/penpot.nomad.hcl @@ -0,0 +1,240 @@ +# Listening Domain +locals { + TRAEFIK_DOMAIN = "penpot.example.local" +} + +# Application routing environment variables +locals { + PENPOT_PUBLIC_URI = "https://${local.TRAEFIK_DOMAIN}" + PENPOT_BACKEND_URI = "http://127.0.0.1:6060" + PENPOT_EXPORTER_URI = "http://127.0.0.1:6061" + PENPOT_FLAGS = "enable-smtp enable-registration enable-login-with-password enable-prepl-server enable-demo-users" + PENPOT_SECRET_KEY = "op://InfraSecrets/7hbsxng22unjqc4wkj62qniu2u/credential" # Try running `openssl rand -hex 32` to generate a random secret key + PENPOT_DATABASE_URI = "postgresql://127.0.0.1:5432/penpot" + PENPOT_DATABASE_USERNAME = "op://InfraSecrets/Postgres - Penpot User/username" + PENPOT_DATABASE_PASSWORD = "op://InfraSecrets/Postgres - Penpot User/password" + PENPOT_REDIS_URI = "redis://127.0.0.1:6379/0" + PENPOT_TELEMERY_ENABLED = "false" +} + +# Assets storage environment variables (fs or s3) +locals { + // PENPOT_ASSETS_STORAGE_BACKEND = "assets-fs" + PENPOT_STORAGE_ASSETS_FS_DIRECTORY = "/opt/data/assets" + + PENPOT_ASSETS_STORAGE_BACKEND = "assets-s3" + AWS_ACCESS_KEY_ID = "op://InfraSecrets/Penpot S3 Key/username" + AWS_SECRET_ACCESS_KEY = "op://InfraSecrets/Penpot S3 Key/credential" + PENPOT_STORAGE_ASSETS_S3_ENDPOINT = "http://127.0.0.1:9000" + PENPOT_STORAGE_ASSETS_S3_BUCKET = "penpot" +} + +# SMTP environment variables +locals { + PENPOT_SMTP_DEFAULT_FROM = "no-reply+penpot@example.local" + PENPOT_SMTP_DEFAULT_REPLY_TO = "no-reply+penpot@example.local" + PENPOT_SMTP_HOST = "127.0.0.1" + PENPOT_SMTP_PORT = "1025" + PENPOT_SMTP_USERNAME = "" + PENPOT_SMTP_PASSWORD = "" + PENPOT_SMTP_TLS = "false" + PENPOT_SMTP_SSL = "false" +} + +job "penpot" { + datacenters = ["dc1"] + + group "frontend" { + count = 1 + + network { + mode = "bridge" + port "ingress" { + to = 80 + } + } + + # Expose frontend to internet through traefik + service { + name = "penpot" + port = "ingress" + + tags = [ + "traefik.enable=true", + "traefik.http.routers.penpot.tls=true", + "traefik.http.routers.penpot.entrypoints=websecure", + "traefik.http.routers.penpot.rule=Host(`${local.TRAEFIK_DOMAIN}`)", + ] + + connect { + sidecar_service { + proxy { + upstreams { + destination_name = "penpot-backend" + local_bind_address = "127.0.0.1" + local_bind_port = 6060 + } + upstreams { + destination_name = "penpot-exporter" + local_bind_address = "127.0.0.1" + local_bind_port = 6061 + } + } + tags = ["traefik.enable=false"] # Hide service from traefik + } + } + + check { + type = "http" + path = "/" + interval = "10s" + timeout = "2s" + } + } + + task "frontend" { + driver = "docker" + + config { + image = "penpotapp/frontend:1.19.3" + ports = ["ingress"] + } + + env { + PENPOT_PUBLIC_URI = local.PENPOT_PUBLIC_URI + PENPOT_BACKEND_URI = local.PENPOT_BACKEND_URI + PENPOT_EXPORTER_URI = local.PENPOT_EXPORTER_URI + + PENPOT_FLAGS = local.PENPOT_FLAGS + } + } + } + + group "backend" { + + network { + mode = "bridge" + port "ingress" { + to = 6060 + } + } + + service { + # Make available to other services by the 'penpot-backend' name + name = "penpot-backend" + port = "6060" + tags = ["traefik.enable=false"] # Hide redis from traefik + + # Make available through the consul service mesh + connect { + sidecar_service { + proxy { + upstreams { + destination_name = "postgres" + local_bind_address = "127.0.0.1" + local_bind_port = 5432 + } + upstreams { + destination_name = "redis-cache" + local_bind_address = "127.0.0.1" + local_bind_port = 6379 + } + upstreams { + destination_name = "minio" + local_bind_address = "127.0.0.1" + local_bind_port = 9000 + } + upstreams { + destination_name = "fake-smtp" + local_bind_address = "127.0.0.1" + local_bind_port = 1025 + } + } + tags = ["traefik.enable=false"] # Hide penpot-backend envoy from traefik + } + } + } + + task "backend" { + driver = "docker" + config { + image = "penpotapp/backend:1.19.3" + ports = ["ingress"] + } + + env { + PENPOT_PUBLIC_URI = local.PENPOT_PUBLIC_URI + PENPOT_SECRET_KEY = local.PENPOT_SECRET_KEY + PENPOT_DATABASE_URI = local.PENPOT_DATABASE_URI + PENPOT_DATABASE_USERNAME = local.PENPOT_DATABASE_USERNAME + PENPOT_DATABASE_PASSWORD = local.PENPOT_DATABASE_PASSWORD + PENPOT_REDIS_URI = local.PENPOT_REDIS_URI + PENPOT_FLAGS = local.PENPOT_FLAGS + PENPOT_TELEMERY_ENABLED = local.PENPOT_TELEMERY_ENABLED + + PENPOT_ASSETS_STORAGE_BACKEND = local.PENPOT_ASSETS_STORAGE_BACKEND + PENPOT_STORAGE_ASSETS_FS_DIRECTORY = local.PENPOT_STORAGE_ASSETS_FS_DIRECTORY + AWS_ACCESS_KEY_ID = local.AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY = local.AWS_SECRET_ACCESS_KEY + PENPOT_STORAGE_ASSETS_S3_ENDPOINT = local.PENPOT_STORAGE_ASSETS_S3_ENDPOINT + PENPOT_STORAGE_ASSETS_S3_BUCKET = local.PENPOT_STORAGE_ASSETS_S3_BUCKET + + PENPOT_SMTP_DEFAULT_FROM = local.PENPOT_SMTP_DEFAULT_FROM + PENPOT_SMTP_DEFAULT_REPLY_TO = local.PENPOT_SMTP_DEFAULT_REPLY_TO + PENPOT_SMTP_HOST = local.PENPOT_SMTP_HOST + PENPOT_SMTP_PORT = local.PENPOT_SMTP_PORT + PENPOT_SMTP_USERNAME = local.PENPOT_SMTP_USERNAME + PENPOT_SMTP_PASSWORD = local.PENPOT_SMTP_PASSWORD + PENPOT_SMTP_TLS = local.PENPOT_SMTP_TLS + PENPOT_SMTP_SSL = local.PENPOT_SMTP_SSL + } + + resources { + cpu = 8000 + memory = 1024 + memory_max = 2048 + } + } + } + + group "exporter" { + + network { + mode = "bridge" + port "ingress" { + to = 6061 + } + } + + task "exporter" { + driver = "docker" + config { + image = "penpotapp/exporter:1.19.3" + } + + env { + PENPOT_PUBLIC_URI = local.PENPOT_PUBLIC_URI + PENPOT_REDIS_URI = local.PENPOT_REDIS_URI + } + } + + service { + name = "penpot-exporter" + port = "ingress" + tags = ["traefik.enable=false"] # Hide envoy from traefik + + connect { + sidecar_service { + proxy { + upstreams { + destination_name = "redis-cache" + local_bind_address = "127.0.0.1" + local_bind_port = 6379 + } + } + tags = ["traefik.enable=false"] # Hide envoy from traefik + } + } + } + } +} \ No newline at end of file diff --git a/nomad_jobs/services/penpot/readme.md b/nomad_jobs/services/penpot/readme.md new file mode 100644 index 0000000..70354b1 --- /dev/null +++ b/nomad_jobs/services/penpot/readme.md @@ -0,0 +1,21 @@ +# Penpot +Penpot is the Open-Source Design & Prototyping Tool for Product Teams. It is a great alternative to Figma or Adobe XD that you can host yourself. Learn all about it on their [website](https://penpot.app/). + +## Nomad Job for Penpot +Penpot already hosts documentation related to their architecture and how to deploy it; therefore, this will not duplicate documentation that can be found on their website such as available flags that can be applied. The nomad spec available in this repository defined the frontend, backend, and exporter services. It is expected that you already have the service dependencies running and available to the Penpot service as well as valid postgres credentials. + +If you need help making those credentials, take a look at the [postgres readme](../postgres/readme.md#make-a-new-database). + +## Service Dependencies +- A Valid [Host Volume](../../../host_init/README.md#storage-and-zfs) or an S3 storage provider like [Minio](../minio/readme.md) +- [Postgres](../postgres/readme.md) +- [Redis Cache](../redis/readme.md) +- *optional* - An SMTP server like [mailcatcher](../mailcatcher/readme.md) or a legitimate mail server + +## Configuring Penpot +Provided you do not need to make adjustments to the services exposed via the consul sidecar, the only edits needed are lines 1-42. The 'locals' blocks are referenced in other sections of the spec and as such we can do all of our configuration in one place. Some notable items are as follows: + +- TRAEFIK_DOMAIN - The domain you will be registering with traefik for access to the application +- PENPOT_FLAGS - remove 'enable_smtp' if you are not going to give SMTP configuration +- PENPOT_STORAGE_BACKEND - The configurations are given for both file system and minio storage. It doesn't affect anything if you include environment variables for both but you must make sure that you have the storage backend set to either 'assests-fs' or 'assets-s3' to inform Penpot which you intend to use. If you are using a filesystem and wish to persist data, you will need to make sure that your host volumes are properly configured. +