diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6949e23..a44e480 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -23,8 +23,8 @@ jobs: testandcoverage: name: Test and Coverage uses: ./.github/workflows/npm-test-and-coverage.yml - dockerimage: - name: Docker Build and Push - uses: ./.github/workflows/docker-build-and-push.yml + dockercomposetest: + name: Docker Compose & Test + uses: ./.github/workflows/docker-compose-test.yml with: - imageName: stanfordbdhg/typescripttemplate + testscript: test.sh diff --git a/.github/workflows/docker-build-and-push.yml b/.github/workflows/docker-build-and-push.yml index fba8f35..304c1b8 100644 --- a/.github/workflows/docker-build-and-push.yml +++ b/.github/workflows/docker-build-and-push.yml @@ -72,15 +72,15 @@ jobs: run: | USERNAME=${{ secrets.username }} PASSWORD=${{ secrets.password }} - + if [ -z "$USERNAME" ]; then USERNAME=${{ github.actor }} fi - + if [ -z "$PASSWORD" ]; then PASSWORD=${{ secrets.GITHUB_TOKEN }} fi - + echo "username=$USERNAME" >> "$GITHUB_OUTPUT" echo "password=$PASSWORD" >> "$GITHUB_OUTPUT" - name: Log in to ${{ inputs.registry }} @@ -132,15 +132,15 @@ jobs: run: | USERNAME=${{ secrets.username }} PASSWORD=${{ secrets.password }} - + if [ -z "$USERNAME" ]; then USERNAME=${{ github.actor }} fi - + if [ -z "$PASSWORD" ]; then PASSWORD=${{ secrets.GITHUB_TOKEN }} fi - + echo "username=$USERNAME" >> "$GITHUB_OUTPUT" echo "password=$PASSWORD" >> "$GITHUB_OUTPUT" - name: Log in to ${{ inputs.registry }} diff --git a/.github/workflows/docker-compose-test.yml b/.github/workflows/docker-compose-test.yml new file mode 100644 index 0000000..1a9b69f --- /dev/null +++ b/.github/workflows/docker-compose-test.yml @@ -0,0 +1,49 @@ +# +# This source file is part of the Stanford Biodesign Digital Health TypeScript Template open-source project +# Based on the Apodini workflow found at: https://github.com/Apodini/.github/workflows/docker-compose-test.yml +# +# SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md) +# +# SPDX-License-Identifier: MIT +# + +name: Docker Compose + +on: + workflow_call: + inputs: + dockerComposeFile: + description: 'Path or name of the Docker compose file. The default values is `docker-compose.yml`' + required: false + type: string + default: 'docker-compose.yml' + workingDirectory: + description: 'The workingDirectory of the GitHub Action. Defaults to $GITHUB_WORKSPACE' + required: false + type: string + default: '.' + testscript: + description: 'Optional path or name to a test script to test the Docker compose setup' + required: false + type: string + +jobs: + buildandtest: + name: Build and Test + runs-on: ubuntu-latest + defaults: + run: + workingDirectory: ${{ inputs.workingDirectory }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Docker compose up + run: docker-compose -f ${{ inputs.workingDirectory }}/${{ inputs.dockerComposeFile }} up -d --build + - name: Run test script + if: inputs.testscript != '' + run: | + sleep 5 + sh ${{ inputs.testscript }} + - name: Docker compose down + if: always() + run: docker-compose down diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2774b85..9618ca5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,3 +22,8 @@ jobs: name: Deploy Next.js site to GitHub Pages needs: buildandtest uses: ./.github/workflows/nextjs-github-pages.yml + dockerimage: + name: Docker Build and Push + uses: ./.github/workflows/docker-build-and-push.yml + with: + imageName: stanfordbdhg/typescripttemplate diff --git a/Dockerfile b/Dockerfile index 7d741ea..f3101c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,9 +58,9 @@ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static USER nextjs -EXPOSE 3000 +EXPOSE 80 -ENV PORT 3000 +ENV PORT 80 # set hostname to localhost ENV HOSTNAME "0.0.0.0" diff --git a/README.md b/README.md index 48d4a36..bcc617e 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,17 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the You can edit the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -## Using Docker +## Docker 1. [Install Docker](https://docs.docker.com/get-docker/) on your machine. -2. Build your container: `docker build -t nextjs-docker .`. -3. Run your container: `docker run -p 3000:3000 nextjs-docker`. +2. Build the image and run the docker compose setup: `docker compose -f docker-compose-development.yml up`. You can view your images created with `docker images`. +Open [http://localhost](http://localhost) with your browser to see the result. You can visit [http://localhost:8080](http://localhost:8080) to see the reverse proxy setup before the main application. + +The `docker-compose.yml` setup contains a production-ready setup using a reverse proxy. + ## Learn More To learn more about Next.js, take a look at the following resources: diff --git a/docker-compose-development.yml b/docker-compose-development.yml new file mode 100644 index 0000000..3cc1259 --- /dev/null +++ b/docker-compose-development.yml @@ -0,0 +1,54 @@ +# +# This source file is part of the Stanford Biodesign Digital Health TypeScript Template open-source project +# Based on the Apodini workflow found at: https://github.com/Apodini/ApodiniExample/docker-compose-development.yml +# +# SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md) +# +# SPDX-License-Identifier: MIT +# + +version: '3.9' + +services: + # An TypeScript Template + stanford-bdhg-typescript-template: + container_name: 'stanford-bdhg-typescript-template' + image: 'stanfordbdgh/typescripttemplate:dev' + build: + context: ./ + dockerfile: ./Dockerfile + expose: + - '80' + command: ['node', 'server.js'] + labels: + # The domain the service will respond to + - 'traefik.http.routers.backend.rule=Host(`localhost`)' + # Allow request only from the predefined entry point named "web" + - 'traefik.http.routers.backend.entrypoints=web' + # We need to define the a service and specify, on which port our server is reachable + - 'traefik.http.services.backend-service.loadbalancer.server.port=80' + # We have to add this service to our router "backend". That's how the router knows where to forward the requests + - 'traefik.http.routers.backend.service=backend-service' + # Reverse Proxy to protect our service from direct access + traefik: + container_name: 'traefik' + image: 'traefik:v2.4' + command: + # Enable Debug output + - '--log.level=DEBUG' + # Enable the api and the traefik dashboard for debugging purposes, which can be reached under 127.0.0.1:8080 + - '--api.insecure=true' + - '--api.dashboard=true' + # Enabling docker provider + - '--providers.docker=true' + # Traefik will listen to incoming request on the port 80 + - '--entrypoints.web.address=:80' + ports: + # 8080 on the container is mapped to 8080 on the server/VM/your Machine. + # Port 8080 is where the api traefik dashboard is located + - '8080:8080' + # Port 80 is where our stanford-bdhg-typescript-template is running + - '80:80' + # Traefik needs the docker.sock to detect new docker container + volumes: + - '/var/run/docker.sock:/var/run/docker.sock:ro' diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d921578 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,43 @@ +# +# This source file is part of the Stanford Biodesign Digital Health TypeScript Template open-source project +# Based on the Apodini workflow found at: https://github.com/Apodini/ApodiniExample/docker-compose.yml +# +# SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md) +# +# SPDX-License-Identifier: MIT +# + +version: '3.9' + +services: + # An TypeScript Template + stanford-bdhg-typescript-template: + container_name: 'stanford-bdhg-typescript-template' + image: 'ghcr.io/stanfordbdhg/typescripttemplate:latest' + expose: + - '80' + command: ['node', 'server.js'] + labels: + # The domain the service will respond to + - 'traefik.http.routers.backend.rule=Host(`localhost`)' + # Allow request only from the predefined entry point named "web" + - 'traefik.http.routers.backend.entrypoints=web' + # We need to define the a service and specify, on which port our server is reachable + - 'traefik.http.services.backend-service.loadbalancer.server.port=80' + # We have to add this service to our router "backend". That's how the router knows where to forward the requests + - 'traefik.http.routers.backend.service=backend-service' + # Reverse Proxy to protect our service from direct access + traefik: + container_name: 'traefik' + image: 'traefik:v2.4' + command: + # Enabling docker provider + - '--providers.docker=true' + # Traefik will listen to incoming request on the port 80 (HTTP) + - '--entrypoints.web.address=:80' + ports: + # 80 on the container is mapped to 80 on the server/VM/your Machine. + - '80:80' + # Traefik needs the docker.sock to detect new docker container + volumes: + - '/var/run/docker.sock:/var/run/docker.sock:ro' diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..bdc21e8 --- /dev/null +++ b/test.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# +# This source file is part of the Stanford OwnYourData Application project +# +# SPDX-FileCopyrightText: 2023 Stanford University +# +# SPDX-License-Identifier: MIT +# + +set -e + +CONTENT=$(curl --fail http://localhost:3000) +echo "$CONTENT" | grep "Welcome to the Stanford Biodesign Digital Health TypeScript Template" + +echo "✅ Test Passed!"