Skip to content

Commit

Permalink
Merge pull request #899 from CodeForAfrica/ft/techlabblog-workflow
Browse files Browse the repository at this point in the history
Techlab Blog Deploy
  • Loading branch information
kelvinkipruto authored Sep 27, 2024
2 parents 159a220 + b066c17 commit 30aea2d
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 22 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/build-docker-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Build Docker Image

on:
workflow_call:
inputs:
tags:
required: true
type: string
description: "The tags to use for the Docker image"
target:
required: true
type: string
description: "The target to use for the Docker image"
build_args:
required: true
type: string
description: "The build args to use for the Docker image"

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [20.16]
os: [ubuntu-latest]

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Cache Docker layers
uses: actions/cache@v4
with:
key: ${{ runner.os }}-buildx-${{ github.sha }}
path: /tmp/.buildx-cache
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
uses: docker/login-action@v3
with:
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
username: ${{ secrets.DOCKER_HUB_USERNAME }}

- name: Build Docker image
uses: docker/build-push-action@v5
with:
build-args: |
${{ inputs.build_args }}
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG=${{ vars.SENTRY_ORG }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
context: .
target: ${{ inputs.target }}
push: true
tags: ${{ inputs.tags }}

# Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
25 changes: 25 additions & 0 deletions .github/workflows/push-to-dokku.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Push to Dokku

on:
workflow_call:
inputs:
git_remote_url:
required: true
type: string
description: "The remote URL to push to"
deploy_docker_image:
required: true
type: string
description: "The name of the image to push"

jobs:
push:
runs-on: ubuntu-latest

steps:
- name: Push
uses: dokku/[email protected]
with:
git_remote_url: ${{ inputs.git_remote_url }}
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
deploy_docker_image: ${{ inputs.deploy_docker_image }}
35 changes: 35 additions & 0 deletions .github/workflows/techlabblog-deploy-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Techlab Blog | Dev | Deploy

on:
push:
branches: [main]
paths:
- "apps/techlabblog/**"
- "Dockerfile"
- ".github/workflows/techlabblog-deploy-dev.yml"

# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: "${{ github.workflow }} @ ${{ github.ref }}"
cancel-in-progress: true

jobs:
build-docker-image:
name: Build Docker Image
uses: ./.github/workflows/build-docker-image.yml
secrets: inherit
with:
tags: "codeforafrica/techlabblog:${{ github.sha }}"
target: "techlabblog-runner"
build_args: |
SENTRY_ENVIRONMENT=development
SENTRY_DSN: ${{ vars.TECHLABBLOG_SENTRY_DSN }}
push-to-dokku:
name: Push to Dokku
needs: [build-docker-image]
uses: ./.github/workflows/push-to-dokku.yml
secrets: inherit
with:
git_remote_url: "ssh://[email protected]/techlabblog-ui"
deploy_docker_image: "codeforafrica/techlabblog:${{ github.sha }}"
74 changes: 74 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -813,4 +813,78 @@ USER nextjs
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "apps/vpnmanager/server.js"]

# ============================================================================
# Techlab Blog
# ============================================================================

#
# techlabblog-deps: image with all techlabblog dependencies
# -----------------------------------------------------

FROM base-deps AS techlabblog-deps

COPY apps/techlabblog/package.json ./apps/techlabblog/package.json

# Use virtual store: https://pnpm.io/cli/fetch#usage-scenario
RUN pnpm --filter "./apps/techlabblog" install --offline --frozen-lockfile

#
# techlabblog-builder: image that uses deps to build shippable output
# ------------------------------------------------------------------

FROM base-builder AS techlabblog-builder

ARG NEXT_TELEMETRY_DISABLED \
# Next.js / Payload (build time)
PORT \
# Next.js (runtime)
NEXT_PUBLIC_APP_NAME="Techlab Blog" \
NEXT_PUBLIC_APP_URL \
NEXT_PUBLIC_SENTRY_DSN \
NEXT_PUBLIC_SEO_DISABLED \
NEXT_PUBLIC_GOOGLE_ANALYTICS \
# Sentry (build time)
SENTRY_AUTH_TOKEN \
SENTRY_ENVIRONMENT \
SENTRY_ORG \
SENTRY_PROJECT

# This is in app-builder instead of base-builder just incase app-deps adds deps
COPY --from=techlabblog-deps /workspace/node_modules ./node_modules

COPY --from=techlabblog-deps /workspace/apps/techlabblog/node_modules ./apps/techlabblog/node_modules

COPY apps/techlabblog ./apps/techlabblog

RUN pnpm --filter "./apps/techlabblog" build

#
# techlabblog-runner: final deployable image
# -----------------------------------------

FROM base-runner AS techlabblog-runner

RUN set -ex \
# Create nextjs cache dir w/ correct permissions
&& mkdir -p ./apps/techlabblog/.next \
&& chown nextjs:nodejs ./apps/techlabblog/.next

# PNPM
# symlink some dependencies
COPY --from=techlabblog-builder --chown=nextjs:nodejs /workspace/node_modules ./node_modules

# Next.js
# Public assets
COPY --from=techlabblog-builder --chown=nextjs:nodejs /workspace/apps/techlabblog/public ./apps/techlabblog/public

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=techlabblog-builder --chown=nextjs:nodejs /workspace/apps/techlabblog/.next/standalone ./apps/techlabblog
COPY --from=techlabblog-builder --chown=nextjs:nodejs /workspace/apps/techlabblog/.next/static ./apps/techlabblog/.next/static
USER nextjs

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "apps/techlabblog/server.js"]


4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@ pesayetu:
roboshield:
$(COMPOSE_BUILD_ENV) $(COMPOSE) --env-file apps/roboshield/.env.local up roboshield --build

techlabblog:
$(COMPOSE_BUILD_ENV) $(COMPOSE) --env-file apps/techlabblog/.env.local up techlabblog --build

vpnmanager:
$(COMPOSE_BUILD_ENV) $(COMPOSE) --env-file apps/vpnmanager/.env.local up vpnmanager --build

1 change: 1 addition & 0 deletions apps/techlabblog/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import createMDX from "@next/mdx";

/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
pageExtensions: ["mdx", "tsx"],
reactStrictMode: true,
transpilePackages: ["@commons-ui/core", "@commons-ui/next"],
Expand Down
1 change: 1 addition & 0 deletions apps/techlabblog/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@mui/material-nextjs": "catalog:",
"@mui/utils": "catalog:",
"@next/mdx": "catalog:",
"@next/third-parties": "catalog:",
"date-fns": "catalog:",
"gray-matter": "catalog:",
"@types/mdx": "catalog:",
Expand Down
54 changes: 35 additions & 19 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ services:
ports:
- 3000:3000

mongodb:
image: mongo:6.0.13
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME:-root}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD:-rootpassword}
ports:
- 27017:27017
volumes:
- db_data:/data/db
- ./mongo-keyfile:/etc/mongo-keyfile
extra_hosts:
- "host.docker.internal:host-gateway"
healthcheck:
# https://medium.com/workleap/the-only-local-mongodb-replica-set-with-docker-compose-guide-youll-ever-need-2f0b74dd8384
test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'host.docker.internal:27017'}]}) }" | mongosh --port 27017 --quiet
interval: 5s
timeout: 30s
start_period: 0s
retries: 30
command:
["--replSet", "rs0", "--bind_ip_all", "--keyFile", "/etc/mongo-keyfile"]
pesayetu:
build:
context: .
Expand Down Expand Up @@ -142,27 +163,22 @@ services:
ports:
- 3000:3000

mongodb:
image: mongo:6.0.13
techlabblog:
build:
context: .
target: techlabblog-runner
args:
- SENTRY_AUTH_TOKEN
- SENTRY_ORG
- SENTRY_ENV
- SENTRY_PROJECT
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME:-root}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD:-rootpassword}
SENTRY_AUTH_TOKEN: ${SENTRY_AUTH_TOKEN}
SENTRY_ORG: ${SENTRY_ORG}
SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT}
SENTRY_PROJECT: ${SENTRY_PROJECT}
ports:
- 27017:27017
volumes:
- db_data:/data/db
- ./mongo-keyfile:/etc/mongo-keyfile
extra_hosts:
- "host.docker.internal:host-gateway"
healthcheck:
# https://medium.com/workleap/the-only-local-mongodb-replica-set-with-docker-compose-guide-youll-ever-need-2f0b74dd8384
test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'host.docker.internal:27017'}]}) }" | mongosh --port 27017 --quiet
interval: 5s
timeout: 30s
start_period: 0s
retries: 30
command:
["--replSet", "rs0", "--bind_ip_all", "--keyFile", "/etc/mongo-keyfile"]
- 3000:3000

vpnmanager:
build:
Expand Down
9 changes: 6 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 30aea2d

Please sign in to comment.