Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Vapor 3 + PostgreSQL + Docker-Compose Correct configuration?

Currently building a package to test some devOps configurations with AWS. Building an application with Swift Vapor3, PostgreSQL 11, Docker. Given my github Repo the project builds/tests/runs just fine with vapor build vapor test vapor run given that you have a local installation of postgresql installed with a username: test, password: test

However my api is not connecting to my DB and am worried my configuration is wrong.

version: "3.5"
services:
  api:
    container_name: vapor_it_container
    build:
      context: .
      dockerfile: web.Dockerfile
    image: api:dev
    networks:
      - vapor-it
    environment:
      POSTGRES_PASSWORD: 'test'
      POSTGRES_DB: 'test'
      POSTGRES_USER: 'test'
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
    ports:
      - 8080:8080
    volumes:
      - .:/app
    working_dir: /app
    stdin_open: true
    tty: true
    entrypoint: bash
    restart: always
    depends_on:
      - db

  db:
    container_name: postgres_container
    image: postgres:11.2-alpine
    restart: unless-stopped
    networks:
      - vapor-it
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
      PGDATA: /var/lib/postgresql/data
    volumes:
      - database_data:/var/lib/postgresql/data

  pgadmin:
    container_name: pgadmin_container
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: [email protected]
      PGADMIN_DEFAULT_PASSWORD: admin
    volumes:
      - pgadmin:/root/.pgadmin
    ports:
      - "${PGADMIN_PORT:-5050}:80"
    networks:
      - vapor-it
    restart: unless-stopped

networks:
  vapor-it:
    driver: bridge

volumes:
  database_data:
  pgadmin:
  #  driver: local

Also while reading the Docker postgres docs I came across this in the "Caveats" section.

If there is no database when postgres starts in a container, then postgres will create the default database for you. While this is the expected behavior of postgres, this means that it will not accept incoming connections during that time. This may cause issues when using automation tools, such as docker-compose, that start several containers simultaneously.postgres dockerhub

I have not made those changes because I am not sure how to go about making that file or how the configuration would look. Has anyone done something like this that has some experience with connecting to Postgresql and using vapor as a back end?

like image 819
mjwrazor Avatar asked Apr 03 '19 17:04

mjwrazor


People also ask

How to create a Postgres docker compose?

Create a Postgres Docker Compose 1 Step 1. Create the Docker Compose file#N#The first step consists of creating the configuration file to run Postgres in... 2 Step 2. Configure your Postgres Docker Compose file More ...

How does docker-compose use the Postgres_version environment variable in the shell?

For example, suppose the shell contains POSTGRES_VERSION=9.3 and you supply this configuration: When you run docker-compose up with this configuration, Compose looks for the POSTGRES_VERSION environment variable in the shell and substitutes its value in.

What's new in Docker-compose-3?

Added in version 3 file format. Specify configuration related to the deployment and running of services. This only takes effect when deploying to a swarm with docker stack deploy, and is ignored by docker-compose up and docker-compose run. Several sub-options are available: Added in version 3.2 file format.

Can docker compose run multiple apps on the same host?

For example, with Docker Compose, you can spin up both your Vapor app and a PostgreSQL database instance with just one command. They can communicate with each other but are isolated from other instances running on the same host.


1 Answers

The theory is, a well-behaved container should be able to gracefully handle not having its dependencies running, because despite the best efforts of your container scheduler, containers may come and go. So if your app needs a DB, but at any given moment the DB is unavailable, it should respond rationally. For example, returning a 503 for an HTTP request, or trying again after a delay for a scheduled task.

That’s theory though, and not always applicable. In your situation, maybe you really do just need your Vapor app to wait for Postgres to come available, in which case you could use a wrapper script that polls your DB and only starts your main app after the DB is ready.

See this suggested wrapper script from the Docker docs:

#!/bin/sh
# wait-for-postgres.sh

set -e

host="$1"
shift
cmd="$@"

until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c '\q'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec $cmd
command: ["./wait-for-postgres.sh", "db", "vapor-app", "run"]
like image 128
tobygriffin Avatar answered Oct 21 '22 13:10

tobygriffin