From cf9fcbd1eef13c35aa860c7fdba46efa7c0bf9ba Mon Sep 17 00:00:00 2001 From: KONFeature Date: Wed, 29 May 2024 10:54:04 +0200 Subject: [PATCH] Test w/ prebuilt binary + switch to raw node for docker --- Dockerfile | 31 +++++++++------ Dockerfile.prebuilt | 7 ---- DockerfileBun | 33 +++++++++++++++ sst.config.ts | 97 ++++++++++++++++++++++++++------------------- 4 files changed, 108 insertions(+), 60 deletions(-) delete mode 100644 Dockerfile.prebuilt create mode 100644 DockerfileBun diff --git a/Dockerfile b/Dockerfile index 3651a95..4933119 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,10 @@ # use the official Bun image # see all versions at https://hub.docker.com/r/oven/bun/tags -FROM oven/bun:1-debian as base -WORKDIR /usr/src/app -COPY . . +FROM node:22 as base + +# Set env to production +ARG NODE_ENV=production +ENV NODE_ENV $NODE_ENV # install dependencies into temp directory # this will cache them and speed up future builds @@ -12,21 +14,24 @@ RUN apt-get update RUN apt-get install -y \ python3 \ build-essential -# Install dependencies -RUN mkdir -p /temp/dev -COPY package.json bun.lockb /temp/dev/ -RUN cd /temp/dev && bun install --frozen-lockfile --ignore-scripts -# install with --production (exclude devDependencies) +# Install dependencies RUN mkdir -p /temp/prod -COPY package.json bun.lockb /temp/prod/ -RUN cd /temp/prod && bun install --frozen-lockfile --production --ignore-scripts +COPY package.json /temp/prod/ +RUN cd /temp/prod && npm i -# copy production dependencies and source code into final image FROM base AS release + +# Copy files as a non-root user. The `node` user is built in the Node image. +WORKDIR /usr/src/app +RUN chown node:node ./ +USER node + +# copy production dependencies and source code into final image +COPY . . COPY --from=install /temp/prod/node_modules node_modules # run the app -USER bun +USER node EXPOSE 42069/tcp -ENTRYPOINT [ "bun", "run", "start" ] \ No newline at end of file +ENTRYPOINT [ "npm", "run", "start" ] \ No newline at end of file diff --git a/Dockerfile.prebuilt b/Dockerfile.prebuilt deleted file mode 100644 index 09154bd..0000000 --- a/Dockerfile.prebuilt +++ /dev/null @@ -1,7 +0,0 @@ -# Prebuilt docker file from the CI worklow -FROM 262732185023.dkr.ecr.eu-west-1.amazonaws.com/indexer-cache:latest - -# run the app -USER bun -EXPOSE 42069/tcp -ENTRYPOINT [ "bun", "run", "start" ] \ No newline at end of file diff --git a/DockerfileBun b/DockerfileBun new file mode 100644 index 0000000..fe0287d --- /dev/null +++ b/DockerfileBun @@ -0,0 +1,33 @@ +# use the official Bun image +# see all versions at https://hub.docker.com/r/oven/bun/tags +FROM oven/bun:1-debian as base +WORKDIR /usr/src/app +COPY . . + +# install dependencies into temp directory +# this will cache them and speed up future builds +FROM base AS install +# install python and all the stuff required to build sqlite3 +RUN apt-get update +RUN apt-get install -y \ + python3 \ + build-essential +# Install dependencies +RUN mkdir -p /temp/dev +COPY package.json bun.lockb /temp/dev/ +# TODO: This is failing cause of better-sqlite3 dependency RAAAGH +RUN cd /temp/dev && bun install --frozen-lockfile + +# install with --production (exclude devDependencies) +RUN mkdir -p /temp/prod +COPY package.json bun.lockb /temp/prod/ +RUN cd /temp/prod && bun install --frozen-lockfile --production + +# copy production dependencies and source code into final image +FROM base AS release +COPY --from=install /temp/prod/node_modules node_modules + +# run the app +USER bun +EXPOSE 42069/tcp +ENTRYPOINT [ "bun", "run", "start" ] \ No newline at end of file diff --git a/sst.config.ts b/sst.config.ts index e5628cf..a5a13b4 100644 --- a/sst.config.ts +++ b/sst.config.ts @@ -1,8 +1,9 @@ import { Port, SecurityGroup } from "aws-cdk-lib/aws-ec2"; -import { Secret } from "aws-cdk-lib/aws-ecs"; +import { Repository } from "aws-cdk-lib/aws-ecr"; +import { ContainerImage, Secret } from "aws-cdk-lib/aws-ecs"; import { StringParameter } from "aws-cdk-lib/aws-ssm"; import type { SSTConfig } from "sst"; -import { Config, Service, type StackContext } from "sst/constructs"; +import { Config, Service, type Stack, type StackContext } from "sst/constructs"; export default { config(_input) { @@ -38,7 +39,7 @@ export default { * @param stack * @constructor */ -function IndexerStack({ stack }: StackContext) { +function IndexerStack({ app, stack }: StackContext) { // All the secrets env variable we will be using (in local you can just use a .env file) const secrets = [ // Db url @@ -52,6 +53,20 @@ function IndexerStack({ stack }: StackContext) { new Config.Secret(stack, "PONDER_RPC_URL_ARB_SEPOLIA"), ]; + // Get our CDK secrets map + const cdkSecretsMap = buildSecretsMap(stack, secrets); + + // Get the container props of our prebuilt binaries + const containerRegistry = Repository.fromRepositoryName( + stack, + "IndexerEcr", + `${app.account}.dkr.ecr.eu-west-1.amazonaws.com/indexer-cache` + ); + const indexerImage = ContainerImage.fromEcrRepository( + containerRegistry, + "latest" + ); + // The service itself const indexerService = new Service(stack, "IndexerService", { path: "./", @@ -86,13 +101,20 @@ function IndexerStack({ stack }: StackContext) { PONDER_LOG_LEVEL: "debug", PONDER_TELEMETRY_DISABLED: "true", }, + cdk: { + // Directly specify the image position in the reigstry here + container: { + image: indexerImage, + secrets: cdkSecretsMap, + }, + }, }); stack.addOutputs({ indexerServiceId: indexerService.id, }); - // Set up connections to database via security groups + // Set up connections to database via the security group const cluster = indexerService.cdk?.cluster; if (cluster) { // Get the security group for the database and link to it @@ -125,52 +147,47 @@ function IndexerStack({ stack }: StackContext) { `Found container: ${containerName}: ${container.containerName}` ); - // Add a stage secret to the container - const addSecret = (secretName: string) => { - const ssmPath = `/indexer/sst/Secret/${secretName}/value`; - try { - const stringParameter = + // Add all the secrets directly to the container environment + /*for (const secretName of Object.keys(cdkSecretsMap)) { + const secret = cdkSecretsMap[secretName]; + if (!secret) continue; + container.addSecret(secretName, secret); + }*/ +} + +/** + * Build a list of secret name to CDK secret, for direct binding + * @param stack + * @param secrets + */ +function buildSecretsMap(stack: Stack, secrets: Config.Secret[]) { + return secrets.reduce( + (acc, secret) => { + // Add the default secret + const ssmPath = `/indexer/sst/Secret/${secret.name}/value`; + let stringParameter = StringParameter.fromSecureStringParameterAttributes( stack, - `Secret${secretName}`, + `Secret${secret.name}`, { parameterName: ssmPath, } ); - container.addSecret( - secretName, - Secret.fromSsmParameter(stringParameter) - ); - } catch { - console.error(`Failed to regular secret: ${secretName}`); - } - }; + acc[secret.name] = Secret.fromSsmParameter(stringParameter); - // Add a fallback secret to the container - const addFallbackSecret = (secretName: string) => { - const ssmPath = `/sst/frak-indexer/.fallback/Secret/${secretName}/value`; - try { - const stringParameter = + // Add the fallback secrets + stringParameter = StringParameter.fromSecureStringParameterAttributes( stack, - `SecretFallback${secretName}`, + `SecretFallback${secret.name}`, { - parameterName: ssmPath, + parameterName: `/sst/frak-indexer/.fallback/Secret/${secret.name}/value`, } ); - container.addSecret( - `${secretName}_FALLBACK`, - Secret.fromSsmParameter(stringParameter) - ); - } catch { - console.error(`Failed to add fallback secret: ${secretName}`); - } - }; - - // Add all the secrets directly to the container environment - for (const secret of secrets) { - // Add the secrets - addSecret(secret.name); - addFallbackSecret(secret.name); - } + acc[`${secret.name}_FALLBACK`] = + Secret.fromSsmParameter(stringParameter); + return acc; + }, + {} as Record + ); }