Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2e53ce7d8 | ||
|
|
d8b7b9735b |
No files matched your search
@@ -0,0 +1,21 @@
|
||||
# Unified production environment template
|
||||
# Copy and fill values with your real production endpoints/secrets.
|
||||
|
||||
NODE_ENV=production
|
||||
|
||||
# Shared infrastructure
|
||||
DATABASE_URL=postgres://user:password@db-host:5432/app
|
||||
MONGO_URL=mongodb://user:password@mongo-host:27017/app
|
||||
REDIS_URL=redis://redis-host:6379
|
||||
|
||||
# API ports (optional, if your runtime uses explicit ports)
|
||||
CRUD_PORT=3000
|
||||
INGEST_PORT=3001
|
||||
|
||||
# Service-specific prefixes used by release filtering
|
||||
CRUD_HOST=0.0.0.0
|
||||
INGEST_HOST=0.0.0.0
|
||||
|
||||
# Frontend build/runtime values
|
||||
VITE_API_BASE_URL=https://api.example.com
|
||||
VITE_INGEST_BASE_URL=https://ingest.example.com
|
||||
@@ -0,0 +1,79 @@
|
||||
name: release-crud-api
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'crud-api/v*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Extract version from tag
|
||||
id: meta
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TAG="${GITHUB_REF_NAME}"
|
||||
VERSION="${TAG#crud-api/v}"
|
||||
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Build Docker image (root context)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker build \
|
||||
--file apps/crud-api/Dockerfile \
|
||||
--tag crud-api:${{ steps.meta.outputs.version }} \
|
||||
.
|
||||
|
||||
- name: Package tar + filtered env
|
||||
id: bundle
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${{ steps.meta.outputs.version }}"
|
||||
OUT_DIR="dist/release"
|
||||
TAR_PATH="${OUT_DIR}/crud-api-${VERSION}.tar"
|
||||
ZIP_PATH="${OUT_DIR}/crud-api-${VERSION}-deploy-bundle.zip"
|
||||
ENV_PATH="${OUT_DIR}/crud-api.env"
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
docker save --output "${TAR_PATH}" "crud-api:${VERSION}"
|
||||
|
||||
if [ ! -f .env.production ]; then
|
||||
echo ".env.production is missing at repository root" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Keep only variables needed by crud-api deployment.
|
||||
grep -E '^(NODE_ENV|CRUD_|DATABASE_URL|REDIS_URL)=' .env.production > "${ENV_PATH}"
|
||||
|
||||
zip -j "${ZIP_PATH}" "${TAR_PATH}" "${ENV_PATH}"
|
||||
echo "zip_path=${ZIP_PATH}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Verify bundle content
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
unzip -l "${{ steps.bundle.outputs.zip_path }}"
|
||||
|
||||
- name: Create Gitea release with artifact
|
||||
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: crud-api v${{ steps.meta.outputs.version }}
|
||||
body: |
|
||||
Automated release bundle for crud-api.
|
||||
Download the attached *-deploy-bundle.zip asset from this release.
|
||||
Includes:
|
||||
- Docker image tar
|
||||
- filtered crud-api.env for deploy
|
||||
files: |
|
||||
${{ steps.bundle.outputs.zip_path }}
|
||||
@@ -0,0 +1,79 @@
|
||||
name: release-ingest-api
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'ingest-api/v*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Extract version from tag
|
||||
id: meta
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TAG="${GITHUB_REF_NAME}"
|
||||
VERSION="${TAG#ingest-api/v}"
|
||||
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Build Docker image (root context)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker build \
|
||||
--file apps/ingest-api/Dockerfile \
|
||||
--tag ingest-api:${{ steps.meta.outputs.version }} \
|
||||
.
|
||||
|
||||
- name: Package tar + filtered env
|
||||
id: bundle
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${{ steps.meta.outputs.version }}"
|
||||
OUT_DIR="dist/release"
|
||||
TAR_PATH="${OUT_DIR}/ingest-api-${VERSION}.tar"
|
||||
ZIP_PATH="${OUT_DIR}/ingest-api-${VERSION}-deploy-bundle.zip"
|
||||
ENV_PATH="${OUT_DIR}/ingest-api.env"
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
docker save --output "${TAR_PATH}" "ingest-api:${VERSION}"
|
||||
|
||||
if [ ! -f .env.production ]; then
|
||||
echo ".env.production is missing at repository root" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Keep only variables needed by ingest-api deployment.
|
||||
grep -E '^(NODE_ENV|INGEST_|DATABASE_URL|MONGO_URL|REDIS_URL)=' .env.production > "${ENV_PATH}"
|
||||
|
||||
zip -j "${ZIP_PATH}" "${TAR_PATH}" "${ENV_PATH}"
|
||||
echo "zip_path=${ZIP_PATH}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Verify bundle content
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
unzip -l "${{ steps.bundle.outputs.zip_path }}"
|
||||
|
||||
- name: Create Gitea release with artifact
|
||||
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: ingest-api v${{ steps.meta.outputs.version }}
|
||||
body: |
|
||||
Automated release bundle for ingest-api.
|
||||
Download the attached *-deploy-bundle.zip asset from this release.
|
||||
Includes:
|
||||
- Docker image tar
|
||||
- filtered ingest-api.env for deploy
|
||||
files: |
|
||||
${{ steps.bundle.outputs.zip_path }}
|
||||
@@ -0,0 +1,79 @@
|
||||
name: release-web
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'web/v*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Extract version from tag
|
||||
id: meta
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TAG="${GITHUB_REF_NAME}"
|
||||
VERSION="${TAG#web/v}"
|
||||
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Build Docker image (root context)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker build \
|
||||
--file apps/web/Dockerfile \
|
||||
--tag web:${{ steps.meta.outputs.version }} \
|
||||
.
|
||||
|
||||
- name: Package tar + filtered env
|
||||
id: bundle
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
VERSION="${{ steps.meta.outputs.version }}"
|
||||
OUT_DIR="dist/release"
|
||||
TAR_PATH="${OUT_DIR}/web-${VERSION}.tar"
|
||||
ZIP_PATH="${OUT_DIR}/web-${VERSION}-deploy-bundle.zip"
|
||||
ENV_PATH="${OUT_DIR}/web.env"
|
||||
|
||||
mkdir -p "${OUT_DIR}"
|
||||
docker save --output "${TAR_PATH}" "web:${VERSION}"
|
||||
|
||||
if [ ! -f .env.production ]; then
|
||||
echo ".env.production is missing at repository root" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Keep only variables needed by web deployment.
|
||||
grep -E '^(NODE_ENV|VITE_)=' .env.production > "${ENV_PATH}"
|
||||
|
||||
zip -j "${ZIP_PATH}" "${TAR_PATH}" "${ENV_PATH}"
|
||||
echo "zip_path=${ZIP_PATH}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Verify bundle content
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
unzip -l "${{ steps.bundle.outputs.zip_path }}"
|
||||
|
||||
- name: Create Gitea release with artifact
|
||||
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: web v${{ steps.meta.outputs.version }}
|
||||
body: |
|
||||
Automated release bundle for web.
|
||||
Download the attached *-deploy-bundle.zip asset from this release.
|
||||
Includes:
|
||||
- Docker image tar
|
||||
- filtered web.env for deploy
|
||||
files: |
|
||||
${{ steps.bundle.outputs.zip_path }}
|
||||
@@ -0,0 +1,36 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
# Build from the monorepo root context so this image can use:
|
||||
# - apps/crud-api
|
||||
# - packages/contracts
|
||||
FROM node:20-alpine AS base
|
||||
WORKDIR /workspace
|
||||
RUN corepack enable
|
||||
|
||||
FROM base AS deps
|
||||
COPY package.json yarn.lock .yarnrc.yml ./
|
||||
COPY .yarn/ ./.yarn/
|
||||
COPY apps/crud-api/package.json ./apps/crud-api/package.json
|
||||
COPY packages/contracts/package.json ./packages/contracts/package.json
|
||||
|
||||
# Use node_modules inside the container for predictable runtime behavior.
|
||||
RUN YARN_NODE_LINKER=node-modules yarn install --immutable
|
||||
|
||||
FROM deps AS build
|
||||
COPY apps/crud-api ./apps/crud-api
|
||||
COPY packages/contracts ./packages/contracts
|
||||
RUN yarn workspace crud-api build
|
||||
|
||||
FROM node:20-alpine AS runtime
|
||||
WORKDIR /workspace
|
||||
ENV NODE_ENV=production
|
||||
RUN corepack enable
|
||||
|
||||
COPY --from=build /workspace/package.json /workspace/yarn.lock /workspace/.yarnrc.yml ./
|
||||
COPY --from=build /workspace/.yarn ./.yarn
|
||||
COPY --from=build /workspace/node_modules ./node_modules
|
||||
COPY --from=build /workspace/apps/crud-api ./apps/crud-api
|
||||
COPY --from=build /workspace/packages/contracts ./packages/contracts
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["yarn", "workspace", "crud-api", "start"]
|
||||
@@ -0,0 +1,36 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
# Build from the monorepo root context so this image can use:
|
||||
# - apps/ingest-api
|
||||
# - packages/contracts
|
||||
FROM node:20-alpine AS base
|
||||
WORKDIR /workspace
|
||||
RUN corepack enable
|
||||
|
||||
FROM base AS deps
|
||||
COPY package.json yarn.lock .yarnrc.yml ./
|
||||
COPY .yarn/ ./.yarn/
|
||||
COPY apps/ingest-api/package.json ./apps/ingest-api/package.json
|
||||
COPY packages/contracts/package.json ./packages/contracts/package.json
|
||||
|
||||
# Use node_modules inside the container for predictable runtime behavior.
|
||||
RUN YARN_NODE_LINKER=node-modules yarn install --immutable
|
||||
|
||||
FROM deps AS build
|
||||
COPY apps/ingest-api ./apps/ingest-api
|
||||
COPY packages/contracts ./packages/contracts
|
||||
RUN yarn workspace ingest-api build
|
||||
|
||||
FROM node:20-alpine AS runtime
|
||||
WORKDIR /workspace
|
||||
ENV NODE_ENV=production
|
||||
RUN corepack enable
|
||||
|
||||
COPY --from=build /workspace/package.json /workspace/yarn.lock /workspace/.yarnrc.yml ./
|
||||
COPY --from=build /workspace/.yarn ./.yarn
|
||||
COPY --from=build /workspace/node_modules ./node_modules
|
||||
COPY --from=build /workspace/apps/ingest-api ./apps/ingest-api
|
||||
COPY --from=build /workspace/packages/contracts ./packages/contracts
|
||||
|
||||
EXPOSE 3001
|
||||
CMD ["yarn", "workspace", "ingest-api", "start"]
|
||||
@@ -0,0 +1,25 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
# Build from the monorepo root context so this image can use:
|
||||
# - apps/web
|
||||
# - packages/contracts
|
||||
FROM node:20-alpine AS base
|
||||
WORKDIR /workspace
|
||||
RUN corepack enable
|
||||
|
||||
FROM base AS deps
|
||||
COPY package.json yarn.lock .yarnrc.yml ./
|
||||
COPY .yarn/ ./.yarn/
|
||||
COPY apps/web/package.json ./apps/web/package.json
|
||||
COPY packages/contracts/package.json ./packages/contracts/package.json
|
||||
RUN YARN_NODE_LINKER=node-modules yarn install --immutable
|
||||
|
||||
FROM deps AS build
|
||||
COPY apps/web ./apps/web
|
||||
COPY packages/contracts ./packages/contracts
|
||||
RUN yarn workspace web build
|
||||
|
||||
FROM nginx:1.27-alpine AS runtime
|
||||
COPY --from=build /workspace/apps/web/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
Reference in new issue
Block a user