Prerequisites:

  • node (used here v13.9.0)
  • docker (used here v19.03.5)
  • docker-compose (used here v1.25.4)

Install @adonisjs/cli globally:

Create a new --api-only project using the CLI:

adonis new adonis-postgres-demo-project --api-only

Run npm i pg so that our project can connect to PostgreSQL.

Add the .prettierrc file:

{
  "printWidth": 120,
  "singleQuote": true,
  "useTabs": false,
  "tabWidth": 2,
  "semi": false,
  "bracketSpacing": true,
  "trailingComma": "es5"
}

Create the Dockerfile:

FROM node:13.10.1-alpine3.10

# so that we can use the adonis command to serve the app in --dev mode
RUN npm i -g @adonisjs/cli@4.0.12

WORKDIR /usr/src/app

COPY package.json ./package.json
RUN npm install

# copy all project files to the container
COPY . .

# start the adonis server in --dev mode
CMD adonis serve --dev

And the .dockerignorefile:

node_modules

Update the .env file to use HOST=0.0.0.0 instead of HOST=127.0.0.1 to make the API available outside of the localhost of the docker container.

Run docker build -t adonis-demo-project . to build the Docker image named adonis-demo-project:latest.

Run the image with:

docker run --rm -it -p 3333:3333 adonis-demo-project:latest

The API should now be accessible in the browser at the address http://localhost:3333 and should respond with the following JSON:

{"greeting":"Hello world in JSON"}

You can now stop the container with Ctrl-C.

Create the docker-compose.yaml file (which also setups volumes so that the code updates done in the project are reflected immediately in the docker container):

version: '3.7'

services:
  api:
    container_name: adonis-demo-api
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - type: bind
        source: .
        target: /usr/src/app
      - type: volume
        target: /usr/src/app/node_modules
    ports:
      - 3333:3333

  db:
    container_name: adonis-demo-db
    image: postgres:12.2-alpine
    ports:
      - 5432:5432
    environment:
      POSTGRES_DB: demo_db
      POSTGRES_USER: demo
      POSTGRES_PASSWORD: demo1234

  adminer:
    container_name: adonis-demo-adminer
    image: adminer:4.7.6
    ports:
      - 8080:8080

Update the .env file with the Postgres DB config (also change the DB_CONNECTIION to pg for Adonis):

HOST=0.0.0.0
PORT=3333
NODE_ENV=development
APP_NAME=AdonisJs
APP_URL=http://${HOST}:${PORT}
CACHE_VIEWS=false
APP_KEY=LaeQghKnovGDmDnKQlMBIrnjZFUEmyzf

DB_CONNECTION=pg
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=demo
DB_PASSWORD=demo1234
DB_DATABASE=demo_db

HASH_DRIVER=bcrypt

Check that Postgres and Adminer are started and working by going to http://localhost:8080 in the browser and login with the following:

System  : PosgreSQL
Server  : db (the name of the service in docker-compose.yaml)
Username: demo (from POSTGRES_USER: demo)
Password: demo1234 (from POSTGRES_PASSWORD: demo1234)
Database: demo_db (from POSTGRES_DB: demo_db)

If the login was sucessful, we can now check that Adonis can connect to the DB by running:

adonis migration:run

It should say that the Database migrated successfully, and if you refresh Adminer on http://localhost:8080 you should now have 3 new tables: users, tokens, and adonis_schema (these migrations were created automatically by the adonis-cli).

And now you have a fully functioning AdonisJS API setup with PosgreSQL and Adminer, with easy replication due to Docker and docker-compose.