Skip to content

Commit

Permalink
Merge pull request #12 from serlo/docker
Browse files Browse the repository at this point in the history
chore: Add docker related files for deployment
  • Loading branch information
LarsTheGlidingSquirrel authored Jun 11, 2024
2 parents f88ab0e + 1530b63 commit ec6a211
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 10 deletions.
22 changes: 22 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# .env - Should not be added because it contains private keys used for encryption. Instead, provide env variables to the docker container.
.env

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
30 changes: 30 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# name: Deploy
# on:
# push:
# branches:
# - main

# jobs:
# docker-image:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: serlo/configure-repositories/actions/setup-node@main
# - uses: google-github-actions/auth@v2
# with:
# credentials_json: '${{ secrets.GCP_KEY_CONTAINER_REGISTRY }}'
# - run: gcloud auth configure-docker
# - uses: google-github-actions/setup-gcloud@v2
# - run: yarn push-image:latest
# deploy-image:
# runs-on: ubuntu-latest
# needs: docker-image
# steps:
# - uses: google-github-actions/auth@v2
# with:
# credentials_json: '${{ secrets.GCP_STAGING_SERVICE_ACCOUNT }}'
# - uses: google-github-actions/get-gke-credentials@v2
# with:
# cluster_name: serlo-staging-cluster
# location: europe-west3-a
# - run: kubectl delete pod -n editor -l app=editor-as-lti-tool
34 changes: 34 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# name: Docker
# on:
# pull_request:
# merge_group:
# jobs:
# build-docker-images:
# name: Build docker images
# runs-on: ubuntu-latest
# strategy:
# fail-fast: false
# matrix:
# imagetag: [dev, latest]
# include:
# - imagetag: dev
# dockerfile: Dockerfile.dev
# - imagetag: latest
# dockerfile: Dockerfile
# steps:
# - uses: actions/checkout@v4
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3
# - name: Build the ${{ matrix.imagetag }} image
# uses: docker/build-push-action@v5
# with:
# push: false
# load: true
# file: ${{ matrix.dockerfile }}
# tags: local-build:${{ matrix.imagetag }}
# - uses: serlo/configure-repositories/actions/setup-node@main
# - name: Run the ${{ matrix.imagetag }} docker image
# run: yarn docker:run local-build:${{ matrix.imagetag }}
# # TODO
# # - name: Test the docker container ${{ matrix.imagetag }}
# # run: yarn test:docker
5 changes: 0 additions & 5 deletions .yarnrc

This file was deleted.

14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# TODO: when this repo build first the src code, change to only run dist folders

FROM node:20.13-alpine
WORKDIR /app

COPY tsconfig.json tsconfig.node.json \
vite.config.ts index.html \
package.json yarn.lock ./
COPY src src
RUN yarn --immutable --immutable-cache --silent
RUN yarn build

EXPOSE 3000
ENTRYPOINT ["yarn", "start"]
11 changes: 11 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM node:20.13
WORKDIR /app

# maybe easier to git clone the repo
COPY . .

RUN apt update && apt install neovim nano -y
RUN yarn --immutable --immutable-cache --silent
RUN yarn build

ENTRYPOINT ["yarn", "start:dev"]
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
"license": "Apache-2.0",
"scripts": {
"build": "tsc && vite build",
"docker:run": "docker run -p 3000:3000 -d --env-file .env-template --add-host=host.docker.internal:host-gateway",
"start": "node --loader=ts-node/esm src/backend/index.ts",
"start:dev": "nodemon --watch src --ext ts,tsx -exec 'node --loader=ts-node/esm src/backend/index.ts' --delay 3",
"lint": "tsc --noEmit",
"push-image": "yarn node --loader=ts-node/esm push-image.ts",
"push-image:dev": "yarn push-image dev",
"push-image:latest": "yarn push-image latest",
"start:mongodb": "sudo systemctl start mongod",
"stop:mongodb": "sudo systemctl stop mongod",
"helper:resolve-mongodb-issue": "sudo rm -rf /tmp/mongodb-27017.sock",
Expand Down Expand Up @@ -39,6 +44,7 @@
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"nodemon": "^3.1.3",
"vite": "^5.2.0"
},
"packageManager": "[email protected]"
Expand Down
75 changes: 75 additions & 0 deletions push-image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import * as t from "io-ts";
import { spawnSync } from "node:child_process";


enum ImageTag {
Dev = "dev",
Latest = "latest",
}

void run();

function run() {
const imageTag = process.argv[2];

if (!imageTag) {
throw new Error(
`You have to specify image tag, ${ImageTag.Dev} or ${ImageTag.Latest}`
);
}
if (
!t.union([t.literal(ImageTag.Dev), t.literal(ImageTag.Latest)]).is(imageTag)
) {
throw new Error(
`Invalid environment name, please use ${ImageTag.Dev} or ${ImageTag.Latest}`
);
}
buildDockerImage({
name: "editor-as-lti-tool",
imageTag,
});
}

function buildDockerImage({
name,
imageTag,
}: {
name: string;
imageTag: ImageTag;
}) {
const remoteName = `eu.gcr.io/serlo-shared/${name}`;
const date = new Date();
const timestamp = `${date.toISOString().split("T")[0]}-${date.getTime()}`;

const { stdout: gitHashBuffer } = spawnSync("git", [
"rev-parse",
"--short",
"HEAD",
]);

const remoteTags = toTags(remoteName, [
imageTag,
timestamp,
gitHashBuffer.toString().split("\n")[0],
]);
const tags = [...remoteTags, ...toTags(name, [imageTag])];

const dockerfile = imageTag == ImageTag.Dev ? ["-f", "Dockerfile.dev"] : [];

spawnSync(
"docker",
["build", ...dockerfile, ...tags.flatMap((tag) => ["-t", tag]), "."],
{ stdio: "inherit" }
);

remoteTags.forEach((remoteTag) => {
// eslint-disable-next-line no-console
console.log("Pushing", remoteTag);
spawnSync("docker", ["push", remoteTag], { stdio: "inherit" });
});
}

function toTags(name: string, versions: string[]) {
return versions.map((version) => `${name}:${version}`);
}

1 change: 1 addition & 0 deletions src/backend/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from "path";
import * as t from "io-ts";
import * as jwt from "jsonwebtoken";

// Requires Node.js 20.11 or higher
const __dirname = import.meta.dirname;

const ltijsKey = readEnvVariable("LTIJS_KEY");
Expand Down
Loading

0 comments on commit ec6a211

Please sign in to comment.