Skip to content

Dockerized and added Workflow #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Build & Publish Docker Image

# trigger on pushes to main or on version tags (e.g. v1.2.3)
on:
push:
branches:
- main

permissions:
contents: read # for actions/checkout
packages: write # to push to GHCR

jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
# 1) checkout code
- name: Checkout repository
uses: actions/checkout@v3

# 2) set up Docker Buildx (for multi-arch, caching, etc.)
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

# 3) authenticate with GHCR
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# 4) build and push
- name: Build and push Docker image
uses: docker/build-push-action@v3
with:
context: .
file: Dockerfile
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/image-generator:latest
ghcr.io/${{ github.repository_owner }}/image-generator:${{ github.sha }}
platforms: linux/amd64
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 1) use a lightweight Node.js runtime
FROM node:18-alpine

# 2) set working dir
WORKDIR /usr/src/app

# 3) install dependencies
COPY package.json package-lock.json* ./
RUN npm install --only=production

# 4) copy source
COPY . .

# 5) expose the port your Express server listens on
EXPOSE 3000

# 6) start the app
CMD ["npm", "start"]
8 changes: 3 additions & 5 deletions api/generate-img.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
const express = require('express');
const sharp = require('sharp');
const axios = require('axios');
const app = express();
const router = express.Router();

app.use(express.static('public'));

app.get('/api/generate-image', async (req, res) => {
router.get('/', async (req, res) => {
try {
const { imageUrl, cropWidth, cropHeight, liveText } = req.query;

Expand Down Expand Up @@ -89,4 +87,4 @@ app.get('/api/generate-image', async (req, res) => {
}
});

module.exports = app;
module.exports = router;
40 changes: 38 additions & 2 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
const express = require('express');
const app = express();

app.use(express.static('public'));

const generateImageRouter = require('./generate-img');
app.use('/api/generate-image', generateImageRouter);

app.get('/', (req, res) => {
let vercelDomain = 'http://localhost:3000'; // Default for local development
let vercelDomain = `http://localhost:${process.env.PORT || 3000}`; // Default for local development

if (process.env.VERCEL_URL) {
// VERCEL_URL might be like 'my-project-abcd.vercel.app' or 'my-custom-domain.com'
Expand All @@ -14,7 +19,7 @@ app.get('/', (req, res) => {
vercelDomain = `https://${parts[0]}.vercel.app`;
} else {
// If it's a custom domain or already a clean vercel.app alias
vercelDomain = `https://${process.env.VERCEL_URL}`;
vercelDomain = process.env.VERCEL_URL;
}
}

Expand Down Expand Up @@ -75,4 +80,35 @@ app.get('/', (req, res) => {
res.send(documentationContent);
});

const port = parseInt(process.env.PORT, 10) || 3000;
const server = app.listen(port, () => {
console.log(`Server is UP and running on http://localhost:${port}`);
});

// 2. Log any errors emitted by the HTTP server
server.on('error', (err) => {
console.error('Server error:', err);
});

// 3. Graceful shutdown logging
const shutdown = (signal) => {
console.log(`Received ${signal}, shutting down server…`);
server.close(() => {
console.log('Server has stopped.');
process.exit(0);
});
};
process.on('SIGINT', () => shutdown('SIGINT'));
process.on('SIGTERM', () => shutdown('SIGTERM'));

// 4. Catch any uncaught exceptions or promise rejections
process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err);
// you might want to exit or restart the process here
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
// you might want to exit or restart the process here
});

module.exports = app;
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
image-generator:
image: ghcr.io/mkcfdc/image-generator:latest
container_name: image-generator
restart: unless-stopped
ports:
- "3000:3000" # adjust if your app listens on a different port
environment:
- NODE_ENV=production
- VERCEL_URL=http://localhost:3000
# - PORT=3000 # uncomment if your app reads PORT from env
Loading