Is there a way to deploy a Postgres Database using Pulumi and Docker while keeping the password secure?

How can I securely provision a Postgres database using Docker with Pulumi without exposing the password?

I need to ensure that the password is not visible when inspecting the container's environment variables.

import * as docker from '@pulumi/docker'
import * as pulumi from '@pulumi/pulumi'
import network from '../network'
import { Volume } from '../volumes'

const container_name = `${pulumi.getProject()}-postgres`

const postgresConfig = new pulumi.Config('postgres')

const postgres = pulumi
    .all([postgresConfig.requireSecret('password')])
    .apply(([password]) => {
        const env = {
            POSTGRES_DB: postgresConfig.require('db'),
            POSTGRES_USER: postgresConfig.require('user'),
            POSTGRES_PASSWORD: password,
        }

        return new docker.Container(container_name, {
            name: container_name,
            image: 'postgres:latest',
            restart: 'always',
            ports: [
                {
                    internal: 5432,
                    external: 5432,
                },
            ],
            networksAdvanced: [
                {
                    name: network.name,
                },
            ],
            volumes: [
                {
                    volumeName: Volume.postgres,
                    containerPath: '/var/lib/postgres/data',
                },
            ],
            healthcheck: {
                interval: '10s',
                retries: 10,
                tests: ['pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'],
                timeout: '2s',
            },
            envs: [
                `POSTGRES_DB=${env.POSTGRES_DB}`,
                `POSTGRES_USER=${env.POSTGRES_USER}`,
                `POSTGRES_PASSWORD=${env.POSTGRES_PASSWORD}`,
            ],
        })
    })

export default postgres

Answer №1

Your scenario involves encryption of secrets by Pulumi to ensure they are not visible in plaintext. However, once passed to the Docker container, these secrets become accessible in plaintext through environment variables.

To prevent passwords from being exposed in plaintext, you can utilize a Docker Secret for encrypting these values. It's important to note that Docker secrets functionality is restricted to Docker Swarm.

A relevant quote from the documentation:

Docker secrets are exclusive to swarm services and not stand-alone containers. For utilizing this feature, it's advisable to configure your container to operate as a service. Stateful containers typically function efficiently with a scale of 1 without necessitating modifications to the container code.

If you opt to proceed with Docker Swarm, you can initialize it on a standalone node using the following command:

docker swarm init

Afterwards, define your container as a service, as demonstrated below:

import * as pulumi from "@pulumi/pulumi";
import * as docker from "@pulumi/docker";

const container_name = `${pulumi.getProject()}-postgres`;
const postgresConfig = new pulumi.Config("postgres");

const password = postgresConfig.requireSecret("password");
const env = {
  POSTGRES_DB: postgresConfig.require("db"),
  POSTGRES_USER: postgresConfig.require("user"),
  POSTGRES_PASSWORD: password,
};

const secret = new docker.Secret("password", {
    name: "postgres-password",
    data: password.apply((pwd) => Buffer.from(pwd, 'utf8').toString('base64'))
})

const svc = new docker.Service(container_name, {
    endpointSpec: {
        ports: [{
            targetPort: 5432,
            publishedPort: 5432,
            publishMode: "ingress"
        }]
    },
    taskSpec: {
        containerSpec: {
            image: "postgres:latest",
            secrets: [{
                secretId: secret.id,
                fileName: "postgres-password",
                secretName: secret.name,
            }],
            env: {
                POSTGRES_DB: env.POSTGRES_DB,
                POSTGRES_USER: env.POSTGRES_USER,
                POSTGRES_PASSWORD_FILE: "/run/secrets/postgres-password",
            },
        }
    }
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Initializing an HTML5 video player directly from an Array

I am trying to populate a video player on my webpage with an array of videos. Here is the code I have so far: var current = 0; var videos = ["01", "02", "03", "04"]; function shuffle(array) { var currentIndex = array.length, temporaryValue, randomInde ...

Angular 2: Transforming File into Byte Array

Is there a preferred method in Angular2 for converting an input file (such as an image) into a byte array? Some suggest converting the image to a byte array and then sending it to a Web API, while others recommend sending the File "object" to the API for ...

Issue with Readonly modifier not functioning as expected in Angular/Typescript

My goal is to create a component property that is read-only. However, I am facing an issue where the readonly modifier does not seem to have any effect. View example on stackblitz According to the documentation, once I initialize the cars property in the ...

Error occurred while making a request in React using Axios: TypeError - Unable to retrieve the 'token' property as it is undefined

After successfully receiving a token from logging in with React Redux, I attempted to authorize it using the token. However, an error occurred stating Axios request failed: TypeError: Cannot read property 'token' of undefined. The token is stored ...

Creating a Wireframe in Three.js Using a RawShaderMaterial with LineSegments

In the midst of my work on a project, I encountered a dilemma with rendering an intricate wireframe using THREE.LineSegments. My objective is to gradually animate the vertices within this LineSegments material (referred to as warehouse in the project), but ...

The JestImportMeta interface is mistakenly extending the ImportMeta interface, causing an error

While transitioning from jest version 27 to v29, I encountered this issue: node_modules/@jest/environment/build/index.d.ts:329:26 - error TS2430: Interface 'JestImportMeta' improperly extends interface 'ImportMeta'. The types returned ...

Typescript eliminates the need for unnecessary source code compilation

Within directory TS 2.6.2, there are three files: interface.ts: export interface Env { x: string } index.ts: import {Env} from './interface' // importing only the interface const env: Env = {x: '1'} console.log(env.x) tsconfi ...

Incorporate loading spinner to enhance search functionality

I am currently using Ajax to search for cities and locations. The search query typically takes around 5 seconds to complete. I would like to know how to add a spinner to indicate the waiting time during the search process. Below is a snippet of the code ...

Filtering MUI Data Grid by array elements

I am in the process of developing a management system that utilizes three MUIDataGrids. Although only one grid is displayed at a time, users can switch between the three grids by clicking on tabs located above. The setup I have resembles the Facebook Ads ...

Struggling with JQuery to revert an element back to its original position after the mouseout event

Hello all, I'm a newcomer here and I've been trying my hand at some basic JQuery. However, I've encountered an issue that I could use some help with. Have you ever come across those boxes on websites where when you hover over them, an arrow ...

Is there a way to transform a string property into a custom type in a TypeScript array?

I am faced with a situation where I have an interface that is extending a MongoDB document, along with some sample data that is also extending that interface. Below is an outline of the interface: export default interface IModel extends Document { _id: Obj ...

What is the process of connecting a Yarn module to a Docker container in another repository?

I'm currently facing a challenge in linking a module to a Docker container from another repository. To provide some background, I have a container hosting a React application named launch-control-admin. This project relies on a yarn module called @com ...

Load a page and sprinkle some contents with a slide effect

I am brand new to jQuery and just starting out, so please excuse me if this question seems basic or silly. I would like the header and footer of my page to stay in place while the center content slides in from the right side when the page loads. This websi ...

Issue with migrating TypeOrm due to raw SQL statement

Is it possible to use a regular INSERT INTO statement with TypeOrm? I've tried various ways of formatting the string and quotes, but I'm running out of patience. await queryRunner.query('INSERT INTO "table"(column1,column2) VALUES ...

What steps do I need to take in order to transform this code into a MUI component complete with

Having some trouble converting my hero banner code to MUI in a React project. The styling is not coming out correctly. Here is the HTML code: <svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120 ...

Adjust the value of a variable within a module using Angular JS

Within my module, I have the code below: var mod; mod = angular.module('ajax-interceptor', []); mod.config(function($httpProvider) { $httpProvider.interceptors.push(["$q", function($q, dependency1, dependency2) { return { ...

Capturing authorization issues in Firebase using ngrx effects

I am currently working on an angular5/firebase/ngrx project and I'm encountering an issue when trying to handle errors during the signup process. When I attempt to submit the signup form with an email that already exists in the system, I receive the ...

What is the method in AngularJS2 for using TypeScript to inject dependencies into components?

I have been encountering different methods of injecting dependencies into my component and not all of them seem to be working for me. I am curious about the advantages and disadvantages, what the recommended best practices are, and why some methods are not ...

What could be causing my click() function to only work properly after resizing?

It's driving me crazy. The code snippet below works perfectly, but not in my project. Only the code in the resize() function seems to work. When I resize the window, everything functions as expected - I can add and remove the 'open' class by ...

Diversifying collection of entities

Imagine having an array structured like this: [ { id: 1, name: "Foo", quantity: 2 }, { id: 2, name: "Bar", quantity: 3 }, ] The goal is to duplicate or expand the array elements based on the ...