diff --git a/.github/workflows/publish-alpha.yml b/.github/workflows/publish-alpha.yml index 049377e3..832085a2 100644 --- a/.github/workflows/publish-alpha.yml +++ b/.github/workflows/publish-alpha.yml @@ -18,22 +18,7 @@ jobs: with: node-version: '22' - - name: Install podverse-helpers latest alpha version - run: npm i podverse-helpers@alpha --save - - - name: Install podverse-external-services latest alpha version - run: npm i podverse-external-services@alpha --save - - - name: Install podverse-orm latest alpha version - run: npm i podverse-orm@alpha --save - - - name: Install podverse-parser latest alpha version - run: npm i podverse-parser@alpha --save - - - name: Install podverse-mq latest alpha version - run: npm i podverse-mq@alpha --save - - - name: Clean install dependencies + - name: Install dependencies (clean) run: npm clean-install - name: Determine next alpha version @@ -76,17 +61,9 @@ jobs: echo "NEXT_VERSION=$NEXT_VERSION" >> $GITHUB_OUTPUT - - name: Build Docker image - run: | - docker build . -t ghcr.io/${{ github.repository }}/podverse-api:${{ steps.version.outputs.NEXT_VERSION }} - - - name: Log in to GitHub Container Registry - uses: docker/login-action@v3 + - name: Build and push Docker image + uses: docker/build-push-action@v5 with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push Docker image - run: | - docker push ghcr.io/${{ github.repository }}/podverse-api:${{ steps.version.outputs.NEXT_VERSION }} + context: . + push: true + tags: ghcr.io/${{ github.repository }}/podverse-api:${{ steps.version.outputs.NEXT_VERSION }} diff --git a/Dockerfile b/Dockerfile index 39c2aab5..18d30f5d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,35 @@ -FROM node:22-slim +FROM node:22-slim AS build WORKDIR /opt -COPY . . -RUN npm install +# Copy package files first to leverage Docker cache +COPY package*.json ./ + +# Build-time argument to control whether to install alpha prerelease packages +ARG INSTALL_ALPHA=true + +# Install alpha packages like CI (if requested), then perform a clean install +RUN if [ "$INSTALL_ALPHA" = "true" ]; then \ + npm i podverse-helpers@alpha --save && \ + npm i podverse-external-services@alpha --save && \ + npm i podverse-orm@alpha --save && \ + npm i podverse-parser@alpha --save && \ + npm i podverse-mq@alpha --save ; \ + fi && \ + npm clean-install + +# Copy the rest of the repository and build +COPY . . RUN npm run build:prod + +FROM node:22-slim AS runtime +WORKDIR /opt + +# Copy built app and node_modules from build stage +COPY --from=build /opt ./ + +ENV NODE_ENV=production +EXPOSE 1234 + +# Default command — start the compiled server +CMD ["node", "dist/index.js"] diff --git a/README.md b/README.md index 4c47132a..7fee1934 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,83 @@ npm run dev:watch ## Deploying To deploy, build the docker image using the Dockerfile, and deploy the image on your server using the `podverse-ops/docker-compose.yml` file. See the `podverse-ops/dev/deploying.md` file for more info. + +## Building & Running Locally (Docker) + +The repository includes a multi-stage `Dockerfile` that mirrors the CI workflow. The build stage optionally installs several `@alpha` prerelease packages and runs `npm clean-install` before building the TypeScript output. The runtime stage contains the compiled `dist/` files and a default command to start the server. + +Basic local build (default installs alpha packages like CI): + +```bash +docker build -t podverse-api:local . +``` + +Skip installing alpha prerelease packages (faster): + +```bash +docker build --build-arg INSTALL_ALPHA=false -t podverse-api:local . +``` + +Run the container (exposes port 1234): + +```bash +docker run --rm -p 1234:1234 \ + -e AUTH_JWT_SECRET=supersecret \ + -e DB_HOST=127.0.0.1 -e DB_PORT=5432 -e DB_USER=postgres -e DB_PASSWORD=postgres -e DB_NAME=podverse \ + podverse-api:local +``` + +Notes: +- The app initializes database and message-queue connections at startup. Provide working services or adjust env vars to avoid startup failures. +- The app listens on port `1234` by default; override with `API_PORT` / `API_PORT` environment variable if needed. + +Quick docker-compose example (Postgres + API) — adapt env keys to your setup: + +```yaml +version: "3.8" +services: + db: + image: postgres:15 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: podverse + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + + api: + image: podverse-api:local + depends_on: + - db + ports: + - "1234:1234" + environment: + NODE_ENV: development + AUTH_JWT_SECRET: supersecret + DB_HOST: db + DB_PORT: 5432 + DB_USER: postgres + DB_PASSWORD: postgres + DB_NAME: podverse + command: ["node", "dist/index.js"] + +volumes: + pgdata: +``` + +Pushing to GitHub Container Registry (GHCR): + +```bash +# Tag the local image with the GHCR name +docker tag podverse-api:local ghcr.io///podverse-api: + +# Login (use a PAT with write:packages) +echo $GHCR_PAT | docker login ghcr.io -u --password-stdin + +# Push +docker push ghcr.io///podverse-api: +``` + +If you want me to add a ready-to-run `docker-compose.yml` to this repo with sensible defaults, or to add an example `make` target for building and pushing, tell me which you prefer.