Skip to content

Commit 554cc6b

Browse files
authored
Merge pull request #1 from penumbra-zone/nix-env
ci: add nix env and starter gha workflows
2 parents 2e7a6c3 + ee0bde9 commit 554cc6b

File tree

12 files changed

+10912
-22
lines changed

12 files changed

+10912
-22
lines changed

.dockerignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# ignore everything by default
2+
**
3+
4+
# allow js files
5+
!*.json
6+
!*.yaml
7+
!*.js
8+
!*.ts
9+
10+
# allow project source code
11+
!backend/
12+
!app/
13+
!public/

.envrc.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
use flake

.github/workflows/container.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
name: Create and publish container image
3+
on:
4+
# Build on merge to main, or any tag push.
5+
push:
6+
branches:
7+
- main
8+
tags:
9+
- '**[0-9]+.[0-9]+.[0-9]+*'
10+
# Also support ad-hoc calls for workflow.
11+
workflow_call:
12+
workflow_dispatch:
13+
jobs:
14+
penumbra:
15+
runs-on: buildjet-16vcpu-ubuntu-2204
16+
permissions:
17+
contents: read
18+
packages: write
19+
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
with:
24+
lfs: true
25+
26+
- name: Log in to the Docker Hub container registry (for pulls)
27+
uses: docker/login-action@v3
28+
with:
29+
username: ${{ secrets.DOCKERHUB_USERNAME }}
30+
password: ${{ secrets.DOCKERHUB_TOKEN }}
31+
32+
- name: Log in to the GitHub container registry (for pushes)
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ghcr.io
36+
username: ${{ github.actor }}
37+
password: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- name: Set up Docker Buildx
40+
uses: docker/setup-buildx-action@v2
41+
42+
- name: Extract metadata (tags, labels) for Docker
43+
id: meta
44+
uses: docker/metadata-action@v5
45+
with:
46+
images: ghcr.io/penumbra-zone/p3numb3rs
47+
48+
- name: Build and push Docker image
49+
uses: docker/build-push-action@v5
50+
with:
51+
context: .
52+
platforms: linux/amd64
53+
file: Containerfile
54+
push: true
55+
tags: ${{ steps.meta.outputs.tags }}
56+
labels: ${{ steps.meta.outputs.labels }}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@ node_modules
33
/.cache
44
/build
55
.env
6+
.envrc
7+
.direnv/
8+
9+
# optional db certs
10+
*.pem

Containerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Provide specific arg for setting the version of nodejs to use.
2+
# Should match what's in .nvmrc for development.
3+
ARG NODE_MAJOR_VERSION=18.20
4+
FROM docker.io/node:${NODE_MAJOR_VERSION}-alpine AS base
5+
# Install dependencies only when needed
6+
FROM base AS deps
7+
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
8+
RUN apk add --no-cache libc6-compat
9+
WORKDIR /app
10+
11+
# Install dependencies
12+
COPY package.json package-lock.json pnpm-lock.yaml* ./
13+
RUN corepack enable pnpm && pnpm install --frozen-lockfile
14+
15+
# Rebuild the source code only when needed
16+
FROM base AS builder
17+
WORKDIR /app
18+
COPY --from=deps /app/node_modules ./node_modules
19+
COPY . .
20+
21+
# Build the website as standalone output.
22+
RUN npm --version && node --version
23+
RUN npm run build
24+
25+
# Production image, copy all the files and run next
26+
FROM base AS runner
27+
LABEL maintainer="team@penumbralabs.xyz"
28+
WORKDIR /app
29+
30+
ENV NODE_ENV production
31+
32+
# Create normal user for app
33+
RUN addgroup --system --gid 1001 nodejs
34+
RUN adduser --system --uid 1001 nodejs
35+
36+
COPY --from=builder --chown=nodejs:nodejs /app /app
37+
38+
USER nodejs
39+
EXPOSE 3000
40+
ENV PORT 3000
41+
42+
CMD HOSTNAME="0.0.0.0" npm start

README.md

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,61 @@
1-
# Welcome to Remix!
1+
# p3numb3rs
22

3-
- 📖 [Remix docs](https://remix.run/docs)
3+
The `penumbers` code leverages [pindexer] to display user metrics
4+
about [Penumbra] network activity.
45

5-
## Development
6+
## Getting Started
67

7-
Run the dev server:
8+
The application is written in [Remix], and uses [pnpm] for package management.
9+
The fastest way to get started on the development environment is to use [Nix]:
810

9-
```shellscript
10-
npm run dev
11+
```shell
12+
sh <(curl -L https://nixos.org/nix/install)
13+
nix develop
14+
just dev
1115
```
1216

13-
## Deployment
17+
However, you still need a database to connect to.
18+
19+
## Connecting to a database
1420

15-
First, build your app for production:
21+
The p3numb3rs application requires a PostgreSQL database containing ABCI event information
22+
as written by [pindexer].
23+
You can set up a local devnet by following the [Penumbra devnet quickstart guide](https://guide.penumbra.zone/dev/devnet-quickstart),
24+
or plug in credentials for an already running database via environment variables:
1625

17-
```sh
18-
npm run build
26+
```
27+
# add these to e.g. `.envrc`:
28+
export PENUMBRA_INDEXER_ENDPOINT="postgresql://<PGUSER>:<PGPASS>@<PGHOST>:<PGPORT>/<PGDATABASE>?sslmode=require""
29+
# optional: if you see "self-signed certificate in certificate chain" errors,
30+
# you'll likely need to export a `ca-cert.pem` file for the DB TLS.
31+
# export PENUMBRA_INDEXER_CA_CERT="$(cat ca-cert.pem)"
1932
```
2033

21-
Then run the app in production mode:
34+
If you see an error `self-signed certificate in certificate chain`, then you'll need to:
2235

23-
```sh
24-
npm start
25-
```
36+
1. obtain the CA certificate file for the backend database you're connecting to, and export it as `PENUMBRA_INDEXER_CA_CERT`.
37+
2. _remove_ the `sslmode=require` string on the `PENUMBRA_INDEXER_ENDPOINT` var.
2638

27-
Now you'll need to pick a host to deploy it to.
39+
See context in https://github.com/penumbra-zone/dex-explorer/issues/55. After configuring that information, run `just dev` again in the nix shell, and you should have events visible.
2840

29-
### DIY
3041

31-
If you're familiar with deploying Node applications, the built-in Remix app server is production-ready.
42+
## Deployment
43+
44+
Merges to main will automatically build a container, hosted at `ghcr.io/penumbra-zone/p3numb3rs`.
45+
In order to run the application, you'll need to [deploy a Penumbra fullnode](https://guide.penumbra.zone/node/pd/running-node),
46+
with [ABCI event indexing enabled](https://guide.penumbra.zone/node/pd/indexing-events).
47+
Furthermore, you'll need to run [`pindexer`] and provide read-only access to that database to the application.
48+
The relevant environment variables you'll want to set are:
3249

33-
Make sure to deploy the output of `npm run build`
50+
* `PENUMBRA_INDEXER_ENDPOINT`: the URL to a Postgres database, managed by [pindexer]
51+
* `PENUMBRA_INDEXER_CA_CERT`: optional; if set, the database connection will use the provided certificate authority when validating TLS
3452

35-
- `build/server`
36-
- `build/client`
3753

3854
## Styling
3955

4056
This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever css framework you prefer. See the [Vite docs on css](https://vitejs.dev/guide/features.html#css) for more information.
57+
58+
[Nix]: https://nixos.org/download/
59+
[Penumbra]: https://github.com/penumbra-zone/penumbra
60+
[Remix]: https://remix.run/docs
61+
[pindexer]: https://guide.penumbra.zone/node/pd/indexing-events#using-pindexer

backend/database/index.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
import pkg from "pg";
22
const { Pool, types } = pkg;
3+
import fs from 'fs';
34
import { Kysely, PostgresDialect } from "kysely";
45
import { Schema } from "./schema";
56

7+
const ca = process.env.PENUMBRA_INDEXER_CA_CERT;
8+
const connectionString = process.env.PENUMBRA_INDEXER_ENDPOINT;
9+
const dbConfig = {
10+
connectionString: connectionString,
11+
...(ca && {
12+
ssl: {
13+
rejectUnauthorized: true,
14+
ca: ca.startsWith('-----BEGIN CERTIFICATE-----')
15+
? ca
16+
: fs.readFileSync(ca, 'utf-8'),
17+
},
18+
}),
19+
};
620
const dialect = new PostgresDialect({
7-
pool: new Pool({ connectionString: process.env["DB_URL"] }),
21+
pool: new Pool(dbConfig),
822
});
923

1024
export type Database = Kysely<Schema>;

flake.lock

Lines changed: 61 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
description = "Dev shell for Penumbra insights dashboard web application";
3+
# inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
4+
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
5+
inputs.flake-utils.url = "github:numtide/flake-utils";
6+
7+
outputs = { self, nixpkgs, flake-utils }:
8+
flake-utils.lib.eachDefaultSystem (system:
9+
let pkgs = nixpkgs.legacyPackages.${system}; in
10+
{
11+
devShells.default = pkgs.mkShell {
12+
name = "devShell";
13+
nativeBuildInputs = [ pkgs.bashInteractive ];
14+
buildInputs = with pkgs; [
15+
fd
16+
file
17+
jq
18+
just
19+
pnpm
20+
postgresql
21+
];
22+
};
23+
});
24+
}

justfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# A justfile for dex-explorer development.
2+
# Documents common tasks for local dev.
3+
4+
# run the app locally with live reload, via pnpm
5+
dev:
6+
pnpm install
7+
pnpm dev
8+
9+
# build container image
10+
container:
11+
podman build -f Containerfile -t p3numb3rs .
12+
13+
# run container
14+
run-container:
15+
just container
16+
podman run -e PENUMBRA_INDEXER_ENDPOINT -e PENUMBRA_INDEXER_CA_CERT -p 3000:3000 -it p3numb3rs

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"type": "module",
66
"scripts": {
77
"build": "remix vite:build",
8-
"dev": "remix vite:dev",
8+
"dev": "remix vite:dev --host",
99
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
1010
"start": "remix-serve ./build/server/index.js",
1111
"typecheck": "tsc"
@@ -20,6 +20,7 @@
2020
"@remix-run/serve": "^2.12.1",
2121
"isbot": "^4.1.0",
2222
"kysely": "^0.27.4",
23+
"p3numb3rs": "link:",
2324
"pg": "^8.13.0",
2425
"react": "^18.2.0",
2526
"react-dom": "^18.2.0",

0 commit comments

Comments
 (0)