Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
70 changes: 70 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Git
.git
.gitignore
.github

# Documentation
README.md
*.md
docs/

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~

# OS files
.DS_Store
Thumbs.db

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

# Dependencies
node_modules/
npm-debug.log*

# Build outputs
dist/
build/
.next/

# Environment files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Images and media (keep certificate images in root)
images/
*.png
*.jpg
*.jpeg
*.gif
*.svg
!images/certificate.png

# Test files
test/
tests/
__tests__/
*.test.js
*.spec.js

# Coverage
coverage/

# Temporary files
tmp/
temp/

# Other project artifacts
*.tar.gz
*.zip
151 changes: 151 additions & 0 deletions .github/workflows/docker-build-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
name: Docker Build and Publish

on:
push:
branches: [ master, main, develop ]
tags: [ 'v*' ]
pull_request:
branches: [ master, main, develop ]

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

strategy:
matrix:
project:
- name: image-filter-udagram
path: src/project/image-filter-udagram-app
- name: udacity-c2-frontend
path: src/project/c2-microservices-v1/udacity-c2-frontend
- name: udacity-c2-restapi-feed
path: src/project/c2-microservices-v1/udacity-c2-restapi-feed
- name: udacity-c2-restapi-user
path: src/project/c2-microservices-v1/udacity-c2-restapi-user

steps:
- name: Checkout repository
uses: actions/checkout@v4

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

- name: Log in to Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.project.name }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-
labels: |
org.opencontainers.image.title=${{ matrix.project.name }}
org.opencontainers.image.description=Udacity AWS Developer Project - ${{ matrix.project.name }}

- name: Check if project has package.json
id: check-project
run: |
if [ -f "${{ matrix.project.path }}/package.json" ]; then
echo "has_package=true" >> $GITHUB_OUTPUT
else
echo "has_package=false" >> $GITHUB_OUTPUT
fi

- name: Build and push Docker image
if: steps.check-project.outputs.has_package == 'true'
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
build-args: |
PROJECT_PATH=${{ matrix.project.path }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

build-individual-dockerfiles:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

strategy:
matrix:
project:
- name: c2-frontend-ionic
dockerfile: src/project/c2-microservices-v1/udacity-c2-frontend/Dockerfile
context: src/project/c2-microservices-v1/udacity-c2-frontend
- name: c2-restapi-feed-individual
dockerfile: src/project/c2-microservices-v1/udacity-c2-restapi-feed/Dockerfile
context: src/project/c2-microservices-v1/udacity-c2-restapi-feed
- name: c2-restapi-user-individual
dockerfile: src/project/c2-microservices-v1/udacity-c2-restapi-user/Dockerfile
context: src/project/c2-microservices-v1/udacity-c2-restapi-user

steps:
- name: Checkout repository
uses: actions/checkout@v4

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

- name: Log in to Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.project.name }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix={{branch}}-

- name: Check if Dockerfile exists
id: check-dockerfile
run: |
if [ -f "${{ matrix.project.dockerfile }}" ]; then
echo "has_dockerfile=true" >> $GITHUB_OUTPUT
else
echo "has_dockerfile=false" >> $GITHUB_OUTPUT
fi

- name: Build and push Docker image
if: steps.check-dockerfile.outputs.has_dockerfile == 'true'
uses: docker/build-push-action@v5
with:
context: ${{ matrix.project.context }}
file: ${{ matrix.project.dockerfile }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
8 changes: 4 additions & 4 deletions .github/workflows/project-c2-udagram.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: cd project/image-filter-udagram-app/
- run: cd project/image-filter-udagram-app/ && npm ci
- run: cd project/image-filter-udagram-app/ && npm run build --if-present
#- run: cd exercises/udacity-c2-restapi/ && npm test
- run: cd src/project/image-filter-udagram-app/
- run: cd src/project/image-filter-udagram-app/ && npm ci
- run: cd src/project/image-filter-udagram-app/ && npm run build --if-present
#- run: cd src/exercises/udacity-c2-restapi/ && npm test
env:
CI: true
8 changes: 4 additions & 4 deletions .github/workflows/udacity-c2-basic-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: cd exercises/udacity-c2-basic-server/
- run: cd exercises/udacity-c2-basic-server/ && npm ci
- run: cd exercises/udacity-c2-basic-server/ && npm run build --if-present
# - run: cd exercises/udacity-c2-basic-server/ && npm test
- run: cd src/exercises/udacity-c2-basic-server/
- run: cd src/exercises/udacity-c2-basic-server/ && npm ci
- run: cd src/exercises/udacity-c2-basic-server/ && npm run tsc --if-present
# - run: cd src/exercises/udacity-c2-basic-server/ && npm test
env:
CI: true
8 changes: 4 additions & 4 deletions .github/workflows/udacity-c2-frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: cd exercises/udacity-c2-frontend/
- run: cd exercises/udacity-c2-frontend/ && npm ci
- run: cd exercises/udacity-c2-frontend/ && npm run build --if-present
# - run: cd exercises/udacity-c2-frontend/ && npm test
- run: cd src/exercises/udacity-c2-frontend/
- run: cd src/exercises/udacity-c2-frontend/ && npm ci
- run: cd src/exercises/udacity-c2-frontend/ && npm run build --if-present
# - run: cd src/exercises/udacity-c2-frontend/ && npm test
env:
CI: true
8 changes: 4 additions & 4 deletions .github/workflows/udacity-c2-restapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: cd exercises/udacity-c2-restapi/
- run: cd exercises/udacity-c2-restapi/ && npm ci
- run: cd exercises/udacity-c2-restapi/ && npm run build --if-present
#- run: cd exercises/udacity-c2-restapi/ && npm test
- run: cd src/exercises/udacity-c2-restapi/
- run: cd src/exercises/udacity-c2-restapi/ && npm ci
- run: cd src/exercises/udacity-c2-restapi/ && npm run tsc --if-present
#- run: cd src/exercises/udacity-c2-restapi/ && npm test
env:
CI: true
39 changes: 39 additions & 0 deletions DOCKER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Docker Usage

This repository includes Docker support for building and running the various projects.

## Building a Docker Image

To build a Docker image for a specific project, use the following command from the root directory:

```bash
# Build image for the image filter project
docker build --build-arg PROJECT_PATH=src/project/image-filter-udagram-app -t udacity-image-filter .

# Build image for microservices frontend
docker build --build-arg PROJECT_PATH=src/project/c2-microservices-v1/udacity-c2-frontend -t udacity-c2-frontend .

# Build image for microservices REST API feed service
docker build --build-arg PROJECT_PATH=src/project/c2-microservices-v1/udacity-c2-restapi-feed -t udacity-c2-restapi-feed .
```

## Running a Docker Container

After building an image, run it with:

```bash
docker run -p 8080:8080 udacity-image-filter
```

## GitHub Actions

The repository includes GitHub Actions workflows that automatically build and publish Docker images to GitHub Container Registry when code is pushed to main branches.

### Available Images

- `ghcr.io/nithinmohantk/udacity-aws-developer-project-workspace/image-filter-udagram`
- `ghcr.io/nithinmohantk/udacity-aws-developer-project-workspace/udacity-c2-frontend`
- `ghcr.io/nithinmohantk/udacity-aws-developer-project-workspace/udacity-c2-restapi-feed`
- `ghcr.io/nithinmohantk/udacity-aws-developer-project-workspace/udacity-c2-restapi-user`

Images are tagged with branch names, semantic versions, and SHA hashes.
60 changes: 60 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Multi-stage Dockerfile for building and serving Udacity AWS Developer projects
# This Dockerfile can build any of the Node.js projects in the src directory

ARG PROJECT_PATH=src/project/image-filter-udagram-app
ARG NODE_VERSION=18.20.3

# Build stage
FROM node:${NODE_VERSION}-slim AS builder

# Install build dependencies
RUN apt-get update && apt-get install -y \
git \
python3 \
make \
g++ \
&& rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /usr/src/app

# Copy the entire src directory
COPY src/ ./src/

# Set the project path as build argument
ARG PROJECT_PATH
ENV PROJECT_DIR=${PROJECT_PATH}

# Install dependencies for the specific project
WORKDIR /usr/src/app/${PROJECT_DIR}
RUN npm ci --only=production

# Production stage
FROM node:${NODE_VERSION}-slim AS production

# Install runtime dependencies
RUN apt-get update && apt-get install -y \
dumb-init \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN groupadd -r appuser && useradd -r -g appuser appuser

# Set working directory
WORKDIR /usr/src/app

# Copy built application from builder stage
ARG PROJECT_PATH
COPY --from=builder --chown=appuser:appuser /usr/src/app/${PROJECT_PATH} ./

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 8080

# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]

# Default command
CMD ["npm", "start"]
Loading
Loading