diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ce4a916 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +docs +node_modules +.prettierrc +.gitignore +shell.nix +render.yaml +plugin +.direnv +pruned +.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..086cca4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM node:22-alpine AS base +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable +COPY . /app +WORKDIR /app + + +FROM base AS build +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +RUN pnpm prisma-generate +RUN pnpm -F obsidian-sync-server build:prod + +FROM build AS pruned +RUN pnpm -F obsidian-sync-server --prod deploy pruned + +# entrypoint container with dumb-init +FROM node:22-alpine +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable +WORKDIR /app +RUN apk update && apk add --no-cache dumb-init +RUN pnpm install -g pm2 +ENV NODE_ENV=production +ENV PORT=8000 +ENV DATABASE_URL="file://./prisma.db" +COPY --from=pruned --chown=node:node /app/pruned /app +RUN pnpx prisma generate --schema=./db/schema.prisma +RUN pnpx pnpm prisma db push --schema=./db/schema.prisma --skip-generate +EXPOSE 8000 + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] +CMD [ "pm2-runtime", "--", "./build/server.js" ] diff --git a/README.md b/README.md index bf403f8..bcff341 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This is a monorepo made with pnpm workspaces. - pnpm - node - npm +- podman ### Technologies Used @@ -15,6 +16,7 @@ This is a monorepo made with pnpm workspaces. - Prisma - sqlite - this is the default. You may use any DB supported by Prisma - obsidian-sample-plugin (used for the plugin template) +- Docker/podman ## To get started for local development: @@ -64,6 +66,20 @@ The server is needed to talk to the database (in this case, sqlite). The server Media is not currently supported. +### Dockerfile + +To build the server into a Docker image (use docker if you prefer): + +```sh +podman build -f Dockerfile -t obsidian-server +``` + +and to run it, use the `.env` file created earlier. Note: you may want to mount the sqlite db file from a volume + +```sh +podman run -p 8000:8000 -d --name obsidian-server --env-file=.env obsidian-server:latest +``` + ### The Blog Route There is also a route at `/api/blog` that is not blocked by cors by default. Given a query string parameter of a vault name, you can fetch all nodes that have frontmatter `published: true` or a #published hashtag. (The #published hashtag is removed from the response.) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d9b5eec..ebaaa15 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,6 +94,9 @@ importers: cors: specifier: ^2.8.5 version: 2.8.5 + dotenv: + specifier: ^16.0.1 + version: 16.0.1 express: specifier: ^4.18.1 version: 4.18.1 @@ -140,9 +143,6 @@ importers: '@vitest/coverage-c8': specifier: ^0.25.7 version: 0.25.7 - dotenv: - specifier: ^16.0.1 - version: 16.0.1 eslint: specifier: ^8.20.0 version: 8.20.0 diff --git a/server/package.json b/server/package.json index a379876..6ec0021 100644 --- a/server/package.json +++ b/server/package.json @@ -3,6 +3,10 @@ "version": "0.1.0", "description": "", "main": "./build/server.js", + "files": [ + "build", + "db/schema.prisma" + ], "scripts": { "build:prod": "tsc", "dev": "pnpm watch & NODE_ENV=development pnpm nodemon ./build/server.js", @@ -18,6 +22,7 @@ "@prisma/client": "^4.9.0", "bcrypt": "^5.0.1", "cors": "^2.8.5", + "dotenv": "^16.0.1", "express": "^4.18.1", "jsonwebtoken": "^9.0.0", "morgan": "^1.10.0", @@ -35,7 +40,6 @@ "@typescript-eslint/eslint-plugin": "^5.31.0", "@typescript-eslint/parser": "^5.31.0", "@vitest/coverage-c8": "^0.25.7", - "dotenv": "^16.0.1", "eslint": "^8.20.0", "nodemon": "^2.0.19", "prettier": "^2.7.1",