Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Munkkeli committed Jan 30, 2025
0 parents commit d2361f6
Show file tree
Hide file tree
Showing 13 changed files with 377 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .diploi/helm/app-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: traefik
spec:
tls:
- hosts:
- {{ .Values.hosts.app }}
secretName: tls-secret
rules:
- host: {{ .Values.hosts.app }}
http:
paths:
- path: '/'
pathType: Prefix
backend:
service:
name: app
port:
number: 3000
10 changes: 10 additions & 0 deletions .diploi/helm/app-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: app
spec:
ports:
- port: 3000
name: app
selector:
app: app
84 changes: 84 additions & 0 deletions .diploi/helm/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
apiVersion: apps/v1
{{- if eq .Values.stage "development"}}
kind: StatefulSet
{{- else }}
kind: Deployment
{{- end }}
metadata:
name: app
labels:
app: app
spec:
selector:
matchLabels:
app: app
{{- if eq .Values.stage "development"}}
serviceName: app
{{- else }}
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
{{- end }}
replicas: {{ ternary 1 0 .Values.enabled }}
template:
metadata:
labels:
app: app
spec:
terminationGracePeriodSeconds: 10
imagePullSecrets:
- name: diploi-pull-secret
{{- if eq .Values.stage "development"}}
initContainers:
- name: install-dependencies
image: {{ .Values.images.app }}
imagePullPolicy: Always
command: ['npm', 'install']
workingDir: /app/{{ .Values.identifier }}
volumeMounts:
- name: app-mount
mountPath: /app
{{- end }}
containers:
- name: app
image: {{ .Values.images.app }}
imagePullPolicy: Always
ports:
- containerPort: 3000
{{- if eq .Values.stage "development" }}
workingDir: /app/{{ .Values.identifier }}
{{- end }}
env:
{{ range $key, $val := .Values.parameterGroupsEnabled }}
{{ if $val }}
- name: parameter_group_{{ $key }}_enabled
value: "1"
{{ end }}
{{ end }}
{{- range .Values.env }}
{{- if contains "app" .contexts }}
- name: {{ .identifier }}
value: {{ .value | quote }}
{{- end }}
{{- end }}
{{- range .Values.parameterGroups }}
- name: {{ .identifier }}
value: {{ .value | quote }}
{{- end }}
- name: APP_PUBLIC_URL
value: {{ .Values.hosts.app }}
- name: STAGE
value: {{ .Values.stage }}
volumeMounts:
{{- if hasKey .Values.storage "code" }}
- name: app-mount
mountPath: /app
{{- end }}
volumes:
{{- if hasKey .Values.storage "code" }}
- name: app-mount
hostPath:
path: {{ .Values.storage.code.hostPath }}
{{- end }}
1 change: 1 addition & 0 deletions .diploi/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Dockerfile
Dockerfile.dev
.dockerignore
node_modules
npm-debug.log
README.md
.git
95 changes: 95 additions & 0 deletions .github/workflows/Prebuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Pre-Build

on:
push:

env:
REGISTRY: ghcr.io

jobs:
production:
name: 'Production'
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}

- name: 'Login to GitHub Container Registry'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set tags
id: set-tags
run: |
TAGS="${{ steps.meta.outputs.tags }}"
if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
TAGS="${TAGS},${{ env.REGISTRY }}/${{ github.repository }}:latest"
fi
echo "tags=$TAGS" >> $GITHUB_ENV
- name: Build and push
uses: docker/build-push-action@v6
with:
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/arm64
tags: ${{ env.tags }}
labels: ${{ steps.meta.outputs.labels }}

development:
name: 'Development'
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}
flavor: |
suffix=-dev.
- name: 'Login to GitHub Container Registry'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set tags
id: set-tags
run: |
TAGS="${{ steps.meta.outputs.tags }}"
if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then
TAGS="${TAGS},${{ env.REGISTRY }}/${{ github.repository }}:latest"
fi
echo "tags=$TAGS" >> $GITHUB_ENV
- name: Build and push
uses: docker/build-push-action@v6
with:
file: Dockerfile.dev
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/arm64
tags: ${{ env.tags }}
labels: ${{ steps.meta.outputs.labels }}
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# typescript
*.tsbuildinfo
52 changes: 52 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
FROM node:22-alpine AS base

# This will be set by the GitHub action to the folder containing this component.
ARG FOLDER=/app

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat

COPY . /app
WORKDIR ${FOLDER}

# Install dependencies based on the preferred package manager
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi

# Rebuild the source code only when needed
FROM base AS builder
COPY . /app
WORKDIR ${FOLDER}
COPY --from=deps ${FOLDER}/node_modules ./node_modules

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

# Production image, copy all the files and run "npm start"
FROM base AS runner

RUN addgroup --system --gid 1000 nodejs
RUN adduser --system --uid 1000 nodejs

COPY --from=builder --chown=nodejs:nodejs /app /app
WORKDIR ${FOLDER}

ENV NODE_ENV=production

USER nodejs

EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["npm", "start"]
18 changes: 18 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This will be set by the GitHub action to the folder containing this component.
ARG FOLDER=/app

FROM node:22-alpine

# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat

COPY . /app
WORKDIR ${FOLDER}

Check warning on line 10 in Dockerfile.dev

View workflow job for this annotation

GitHub Actions / Development

Relative workdir without an absolute workdir declared within the build can have unexpected results if the base image changes

WorkdirRelativePath: Relative workdir "" can have unexpected results if the base image changes More info: https://docs.docker.com/go/dockerfile/rule/workdir-relative-path/

Check warning on line 10 in Dockerfile.dev

View workflow job for this annotation

GitHub Actions / Development

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$FOLDER' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

ENV NODE_ENV=development

EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["npm", "run", "dev"]
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<img alt="icon" src=".diploi/icon.svg" width="32">

# Node.js Component for Diploi

A generic Node.js component that can be used to run any Node.js app.

Uses the official [node](https://hub.docker.com/_/node) Docker image.

## Operation

### Development

Will run `npm install` when component is first initialized, and `npm run dev` when deployment is started.

### Production

Will build a production ready image. Image runs `npm install` & `npm build` when being created. Once the image runs, `npm start` is called.
22 changes: 22 additions & 0 deletions diploi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
diploiVersion: v1.0
type: component
name: Node.js
description: Official Diploi component for Node.js

contexts:
- name: app
identifier: app

hosts:
- name: Node.js
identifier: app
urlFormat: '[label].[default-domain]'

images:
- identifier: app
prebuildImage: ghcr.io/diploi/component-nodejs:[tag]

logs:
- name: Node.js Log
type: log
labelSelector: app=app
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "component-nodejs",
"version": "1.0.0",
"main": "src/index.mjs",
"scripts": {
"dev": "node --watch src/index.mjs",
"build": "echo 'Add your build step here if one is required'",
"start": "node src/index.mjs"
}
}
14 changes: 14 additions & 0 deletions src/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createServer } from 'node:http';

const server = createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World!\n');
});

const port = process.env.PORT;
const host = process.env.HOSTNAME;

// Starts a simple HTTP server
server.listen(port, host, () => {
console.log(`Listening on ${host}:${port}`);
});

0 comments on commit d2361f6

Please sign in to comment.