Reputation: 1578
I have spent AGES trying to get a Docker, Typescript, Postgres, Prisma backend setup working, please help find where i am going wrong! My containers are running, i think my ports are exposed from the API and DB, and thus i should be able to connect / see the graphql panel in my browser on http://0.0.0.0:3000/graphql
i.e. the port that is exposed - but no luck!
Dockerfile
FROM node:16-alpine
# Create app directory
WORKDIR /usr/src/app
# copy both to the container
COPY package*.json ./
# install packages to the container
RUN npm install
# copy everything
COPY . .
# generate the prisma database client
RUN npx prisma generate
# expose the api port
EXPOSE 3000
# run the dev app - prod is not currently Dockerised
CMD [ "npm", "run", "dev" ]
docker-compose.yml
version: "3.9"
services:
api:
build: .
container_name: api
image: api:latest
volumes:
- postgres-data:/app/postgres-data
restart: always
environment:
DB_URL: ${DB_URL}
expose:
- 3000
ports:
- 3000:3000
depends_on:
db:
condition: service_healthy
command: ["npm", "run", "dev"]
db:
container_name: db
image: postgres:15
restart: always
ports:
- 5432:5432
expose:
- 5432
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "sh -c 'pg_isready -U ${DB_USER} -d ${DB_NAME}'"]
interval: 10s
timeout: 3s
retries: 3
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
name: postgres-data
You can see here that the ports are ok (i think).
package.json
{
"name": "budgetappbackend",
"version": "1.0.0",
"description": "A typescript and express backend service",
"main": "dist/index.js",
"type": "module",
"scripts": {
"clean": "rm -rf ./build",
"compile": "tsc",
"start": "NODE_ENV=production node ./build/index.js",
"docker:up": "docker-compose up -d",
"prebuild": "rm -rf ./build",
"build": "npm install && npm -s run migrate && npm -s run generate && npm -s run compile",
"prisma:generate": "npx prisma generate",
"prisma:migrate": "npx prisma migrate dev",
"dev": "set NODE_ENV=development && npm install && concurrently npm:dev:*",
"dev:run": "DOTENV_CONFIG_PATH=.env.development nodemon -r dotenv/config ./src/index.ts",
"test": "DOTENV_CONFIG_PATH=.env.test jest --setupFiles dotenv/config"
},
"repository": {
"type": "git",
"url": "git+https://github.com/JRRS1982/BudgetAppBackend.git"
},
"engines": {
"node": "16.15.1"
},
"prisma": {
"schema": "src/Libs/prisma/schema.prisma"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/JRRS1982/BudgetAppBackend/issues"
},
"homepage": "https://github.com/JRRS1982/BudgetAppBackend#readme",
"dependencies": {
"@apollo/server": "^4.3.2",
"@prisma/client": "^4.9.0",
"envalid": "^7.3.1",
"express": "^4.18.2",
"graphql": "^16.6.0",
"graphql-scalars": "^1.20.1",
"graphql-tag": "^2.12.6"
},
"devDependencies": {
"@faker-js/faker": "^7.6.0",
"@jest/globals": "^29.4.2",
"@types/cors": "^2.8.13",
"@types/jest": "^29.4.0",
"@types/node": "^18.11.18",
"concurrently": "^7.6.0",
"dotenv": "^16.0.3",
"jest": "^29.4.2",
"jest-mock-extended": "^3.0.1",
"nodemon": "^2.0.20",
"prisma": "^4.9.0",
"ts-jest": "^29.0.5",
"ts-node": "^10.9.1",
"typescript": "^4.9.4"
}
}
index.ts file
import { ApolloServer } from "@apollo/server";
import { expressMiddleware } from "@apollo/server/express4";
import { ApolloServerPluginDrainHttpServer } from "@apollo/server/plugin/drainHttpServer";
import bodyParser from "body-parser";
import cors from "cors";
import express from "express";
import http from "http";
import { resolvers } from "./resolvers.js";
import { typeDefs } from "./schema.js";
import validateEnv from "./Utils/validateEnv.js";
/**
* Throw error if we are missing any env variables
*/
validateEnv();
/**
* Create a server
*/
const app = express();
const httpServer = http.createServer(app);
/**
* Start server with a plugin to drain server - to shutdown gracefully
*/
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
/**
* Wait for server to start
*/
await server.start();
/**
* Add the Apollo server to Express
*/
app.use(cors<cors.CorsRequest>(), bodyParser.json(), expressMiddleware(server));
/**
* Listen for requests on PORT, or fallback to 4000
*/
await new Promise<void>((resolve) => {
httpServer.listen({ port: process.env.PORT || 4000 }, resolve);
});
/**
* Tell the user we are ready
*/
console.log(
`🚀 Server ready at http://localhost:${process.env.PORT || 4000}/graphql`
);
I am running docker compose up -d --remove-orphans
to start the containers
I think this is required, docker exec -it api sh -c "npx prisma migrate dev"
to migrate the Prisma schema, but RUN npx prisma generate
exists in the Dockerfile to generate the client.
I would like to at least be able to see (the containerised) graphql in the browser (npm run dev will lauch - but not dockerised)?!
I am eager to fix so that the prisma migrations / whatever i am missing happens on the docker compose up -d
command (i am also using a makefile for convenience).
The logs here with the up command show that the app is running, but the database is shut down - argh! Help! Thank you.
Upvotes: 0
Views: 1286
Reputation: 26
The log output provided suggests the service is listening on port 3001
, but the docker-compose.yml
is exposing port 3000
.
Aligning these should resolve the issue.
Upvotes: 1