diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e6bbb1c5..5114afbc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,14 @@ # Contribution Guide -## Environment +## Local Development + +### Prerequisites - Deno >= v1.36.1 -- [Vercel](https://vercel.com/) - GitHub API v4 - Docker and Docker compose (optional) -## Local Run +### Setup Create `.env` file to project root directory, and write your GitHub token to the `.env` file. Please select the authority of `repo` when creating token. @@ -71,3 +72,87 @@ deno task format ```sh deno task test ``` + +## Production Deployment + +### Vercel + +The project is configured for deployment on Vercel by default. The `vercel.json` +configuration handles the routing automatically. + +For more information, see the [Vercel documentation](https://vercel.com/docs). + +### Linux Server (Ubuntu) + +#### Prerequisites + +- Linux server with SSH access (Ubuntu in this example) +- Docker installed +- Reverse proxy server installed (nginx in this example) +- certbot installed for SSL certificate (https) + +#### Deployment Steps + +1. **SSH into your server and clone the repository**: + ```sh + ssh your-server + git clone https://github.com/ryo-ma/github-profile-trophy.git + cd github-profile-trophy + ``` + +2. **Set up environment file** (see [Local Development](#local-development) for + token setup): + ```sh + cp env-example .env + ``` + + Edit `.env` and configure: + ```properties + ENABLE_REDIS=true + REDIS_HOST=redis + REDIS_PORT=6379 + REDIS_PASSWORD=dummy-pwd-to-avoid-ERR-AUTH + ``` + +3. **Build and start services**: + ```sh + docker compose -f docker-compose.prod.yml up --build -d + ``` + +#### Server configuration + +1. **Add DNS record pointing on your server** + + ``` + A your-server-ip your-domain.com + ``` + +2. **Add Reverse Proxy Configuration (nginx)** + + In `/etc/nginx/sites-enabled/default`, add the following configuration: + + ```nginx + server { + server_name your-domain.com; + + location / { + proxy_pass http://127.0.0.1:3000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } + ``` + +3. **Add SSL certificate** + + ``` + certbot --nginx + ``` + +4. **Reload nginx configuration** + + ``` + systemctl reload nginx + ``` diff --git a/README.md b/README.md index b2f05617..630c63ae 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ These are endpoints provided by volunteers. Please use these in moderation. by [PracticalRyan](https://github.com/PracticalRyan) - [https://github-profile-trophy-tawny.vercel.app](https://github-profile-trophy-tawny.vercel.app) by [vijaypurohit322](https://github.com/vijaypurohit322) +- [https://gh-trophy.cdnsoft.net](https://gh-trophy.cdnsoft.net) + by [cromatikap](https://github.com/cromatikap) # Quick Start diff --git a/api/index.ts b/api/index.ts index ac51d90b..fc29f45f 100644 --- a/api/index.ts +++ b/api/index.ts @@ -1,5 +1,5 @@ import { Card } from "../src/card.ts"; -import { CONSTANTS, parseParams } from "../src/utils.ts"; +import { CONSTANTS, getBaseUrl, parseParams } from "../src/utils.ts"; import { COLORS, Theme } from "../src/theme.ts"; import { Error400 } from "../src/error_page.ts"; import "https://deno.land/x/dotenv@v0.5.0/load.ts"; @@ -43,7 +43,7 @@ async function app(req: Request): Promise { const column = params.getNumberValue("column", CONSTANTS.DEFAULT_MAX_COLUMN); const themeParam: string = params.getStringValue("theme", "default"); if (username === null) { - const [base] = req.url.split("?"); + const base = getBaseUrl(req); const error = new Error400( `
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 00000000..0f044c0f --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,21 @@ +services: + redis: + image: redis:latest + container_name: gh-trophy_db + restart: unless-stopped + volumes: + - redis-data:/data + command: ["redis-server", "--requirepass", "dummy-pwd-to-avoid-ERR-AUTH"] + + github-profile-trophy: + image: github-profile-trophy:latest + build: . + container_name: gh-trophy_app + restart: unless-stopped + ports: + - "127.0.0.1:3000:8080" + env_file: + - .env + +volumes: + redis-data: diff --git a/src/utils.ts b/src/utils.ts index 9d529731..d9f25ee7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -38,6 +38,12 @@ export function parseParams(req: Request): CustomURLSearchParams { return new CustomURLSearchParams(splittedURL[1]); } +export function getBaseUrl(req: Request): string { + const proto = req.headers.get("x-forwarded-proto") || "http"; // reverse proxy compatible protocol discovery + const host = req.headers.get("host"); + return `${proto}://${host}`; +} + export function abridgeScore(score: number): string { if (Math.abs(score) < 1) { return "0pt";