#sharing database server between containers

1 messages · Page 1 of 1 (latest)

north phoenix
#

hey, currently wondering what the current pattern is for sharing a database service between containers; i have 3 services, a db service that starts, a migration service that runs migrations against it, and a app service that starts to run tests.

it seems that when the app service starts, the db service has not yet run it's migrations. wondering if the db service is detatching after the migration service runs, (and is starting a new instance when the app service starts)

here's basically what i'm trying to do; the application container complains that the tables are not present (created by the pulumiContainer)

import { connect } from "@dagger.io/dagger";

import { fileURLToPath } from "url";
import { exec } from "child_process";
import { promisify } from "util";

import * as path from "path";

const run = promisify(exec);

const dbBase = "amazon/dynamodb-local";
const dbHost = "db";
const dbPort = 8000;

const registry = "XXXXX";

const buildBase = `XXXXX`;

const userName = "AWS";

type Entry = [string, string];

// const file = __filename;

connect(
  async (client) => {
    const loginCmd = "aws ecr get-login-password --region us-east-2";
    const cmd = await run(loginCmd, {});
    const password = client.setSecret("ecr-pass", cmd.stdout);

    // db container
    let dbContainer = client
      .container()
      .from(dbBase)
      .withExposedPort(dbPort)
      .asService();

    // pulumi container
  

    // using .env var for now
    let envVars: Array<Entry> = [
      ["CACHEBUSTER", new Date().toString()],
      ["PULUMI_CONFIG_PASSPHRASE", ""],
      ["DYNAMO_DB_ENDPOINT", `http://${dbHost}:8000/`],
      ["AWS_DEFAULT_REGION", "us-east-2"],
      ["AWS_ACCESS_KEY_ID", "fakepulumi"],
      ["AWS_SECRET_ACCESS_KEY", "fakepulumikey"],
    ];

    let commands: Array<string> = [
      'echo "PULUMI APPLY START"',
      "npm install",
      'aws configure set region "us-east-2"',
      'mkdir .pulumi.state',
      "pulumi login --local",
      "pulumi stack init local",
      "pulumi up -r -y",
      `AWS_REGION=us-east-2 aws dynamodb list-tables --endpoint-url http://${dbHost}:8000`,
    ];

    let pulumiContainer = client
      .container()
      .withRegistryAuth(registry, userName, password)
      .from(buildBase)
      .withWorkdir("/app")
      .withServiceBinding(dbHost, dbContainer);

    envVars.forEach(([name, value]) => {
      pulumiContainer = pulumiContainer.withEnvVariable(name, value);
    });

    commands.forEach((cmd) => {
      pulumiContainer = pulumiContainer.withExec(["bash", "-c", cmd]);
    });

    // lambda

    const lambdaFolder = path.resolve(path.dirname(file), "../../");
    const dir = client.host().directory(lambdaFolder);

    let container = client
      .container()
      .build(dir)
      .withServiceBinding(dbHost, dbContainer);

    await pulumiContainer.stderr();

    // using .env var for now
    envVars = [
      ["CACHEBUSTER", new Date().toString()],
      ["DYNAMO_DB_ENDPOINT", `http://${dbHost}:8000/`],
      ["AWS_DEFAULT_REGION", "us-east-2"],
      ["AWS_ACCESS_KEY_ID", "fakerunner"],
      ["AWS_SECRET_ACCESS_KEY", "fakerunnerkey"],
    ];

    commands = [
      `AWS_REGION=us-east-2 aws dynamodb list-tables --endpoint-url http://${dbHost}:8000`,
      "cargo run",
    ];

    envVars.forEach(([name, value]) => {
      container = container.withEnvVariable(name, value);
    });

    commands.forEach((cmd) => {
      container = container.withExec(["bash", "-c", cmd]);
    });

    await container.stderr();
  },
  { LogOutput: process.stdout }
);

shrewd dock
#

@north phoenix which part runs migrations?

#

is it possible to just move the migration-running to a command that runs after binding the service and before the app starts?

north phoenix
#

yeah it should be; the pulumi container runs migratoins when it executes it's commands. the "migrations" are basically pulumi declarations for dynamodb tables and a custom component that creates entries in said tables

#

i guess i'm kinda wondering when containers return from an await poll, like await stderr? or when does the actual build start to kick off, does that happen when the container's output is polled or at some other point? does it return from await when the container exits?

#

obviously in this case i'd want to make sure the container completed the migration and the db service was still running before executing the app tests

#

sorry to be clear, it should already be doing the commands in that order

#

but i could try to do right after the app container but the app hasn't runned tests yet

woven torrent
#

I don't see anything wrong in the pipeline. Maybe the dbservice is being restarted between the migrations and the app starting which would explain this

#

@north phoenix I'd try using the new service lifecycle APIs introduced in 0.9 which allow you to have more fine grained control over the service.

north phoenix
#

hmm, yeah this sounds like what i want

woven torrent
shrewd dock
#

It looks fine to me too 😅 nothing really jumps out. I'd try the explicit start/stop too, though

#

mostly as a troubleshooting tool, I'd be surprised if that fixed it

north phoenix
#

ill give that a shot, just to see if that worked hah

woven torrent
north phoenix
#

huh, thanks!

#

let me try that

north phoenix
#

i didn't think that would work only because in the docs it says that -memoryDb implies -sharedDb but it looks like that in fact, did solve the problem 😄 thanks @woven torrent !

#

i guess it's a local dynamo bug

#

much appreciated, sorry for the noise, and thanks for showing me the service lifecycle stuff ill probably end up using that later!

woven torrent
#

sure, np! happy hacking!