Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect to Postgres from Github Codespaces

I am experimenting with GitHub Codespaces, trying to spin up an app using Node and Postgres.

I selected the following option: codespace option

which produced the following devcontainer.json:

// Update the VARIANT arg in docker-compose.yml to pick a Node.js version: 10, 12, 14 
{
    "name": "Node.js & PostgreSQL",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
    "workspaceFolder": "/workspace",

    // Set *default* container specific settings.json values on container create.
    "settings": { 
        "terminal.integrated.shell.linux": "/bin/bash",
        "sqltools.connections": [{
            "name": "Container database",
            "driver": "PostgreSQL",
            "previewLimit": 50,
            "server": "localhost",
            "port": 5432,
            "database": "postgres",
            "username": "postgres",
            "password": "postgres"
        }]
    },

    // Add the IDs of extensions you want installed when the container is created.
    "extensions": [
        "dbaeumer.vscode-eslint",
        "mtxr.sqltools",
        "mtxr.sqltools-driver-pg"
    ]

    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [3000, 5432],

    // Use 'postCreateCommand' to run commands after the container is created.
    // "postCreateCommand": "yarn install",

    // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
    // "remoteUser": "node"
}

and docker-compose.yml:

version: '3'

services:
  app:
    build: 
      context: .
      dockerfile: Dockerfile
      args:
        # [Choice] Node.js version: 14, 12, 10
        VARIANT: 14
        # On Linux, you may need to update USER_UID and USER_GID below if not your local UID is not 1000.
        USER_UID: 1000
        USER_GID: 1000

    volumes:
      - ..:/workspace:cached
      
    # Overrides default command so things don't shut down after the process ends.
    command: sleep infinity

    # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
    network_mode: service:db

    # Uncomment the next line to use a non-root user for all processes.
    # user: node

    # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. 
    # (Adding the "ports" property to this file will not forward from a Codespace.)

  db:
    image: postgres:latest
    restart: unless-stopped
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: postgres

    # Add "forwardPorts": ["5432"] to **devcontainer.json** to forward MongoDB locally.
    # (Adding the "ports" property to this file will not forward from a Codespace.)

volumes:
  postgres-data:

My package.json is as follows:

{
  "dependencies": {
    "pg": "^8.4.2"
  },
  "scripts": {
    "start": "node index.js"
  }
}

and my index.js is like so:

const { Pool } = require("pg")

const db = new Pool()

db.query(`CREATE TABLE IF NOT EXISTS testing(id SERIAL PRIMARY KEY);`)

Running yarn start produces the following error:

codespace ➜ ~/workspace/codespace-demo (main ✗) $ yarn start
yarn run v1.17.3
warning package.json: No license field
$ node index.js
(node:1037) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:5432
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
(node:1037) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:1037) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Done in 0.11s.

Which leads me to believe the Postgres instance is not up and running inside the Codespace.

I tried uncommenting this line about forwarding ports:

"forwardPorts": [3000, 5432]

but no luck there.

I am probably missing some insight about how the Docker pieces fit in to play here, but would love it if someone could point me in the right direction!

like image 247
Andy Weiss Avatar asked Nov 05 '20 19:11

Andy Weiss


1 Answers

I was able to get this working with two points.

  1. It's not enough to simply add a .devcontainer with the files inside. You need to commit the changes, push them, delete the codespace and then make a new one for the changes to reflect.

  2. Inside of .devcontainer/docker-compose.yml, I had add the line network_mode: host to the db service. According to this thread, this requirement will be removed soon, but for now it is required: https://github.community/t/cant-connect-to-postgres/142655/2?u=andyweiss1982

like image 115
Andy Weiss Avatar answered Oct 12 '22 17:10

Andy Weiss