-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/docker #2
Feat/docker #2
Changes from all commits
4cfc64a
ec57476
89d1145
15871f0
f44c87d
233b711
ade4d1a
fcd3413
41a663e
e0ca7da
81927c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| # Git | ||
| .git | ||
| .gitignore | ||
| .github | ||
|
|
||
| # Dependencies | ||
| node_modules | ||
|
|
||
| # Build outputs | ||
| build | ||
| .svelte-kit | ||
| dist | ||
|
|
||
| # Data directories | ||
| pgdata | ||
| redis-data | ||
| logs | ||
| # Environment | ||
| .env | ||
| .env.* | ||
| !.env.example | ||
|
|
||
| # Debug logs | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| pnpm-debug.log* | ||
|
|
||
| # OS | ||
| .DS_Store | ||
| Thumbs.db | ||
|
|
||
| # IDE | ||
| .vscode | ||
| .idea | ||
| *.swp | ||
| *.swo | ||
|
|
||
| # Docker | ||
| Dockerfile | ||
| docker-compose* | ||
| .dockerignore | ||
|
|
||
| # Documentation | ||
| README.md | ||
| readme.md | ||
| LICENSE | ||
| licence | ||
|
|
||
| # Tests | ||
| **/*.test.ts | ||
| **/*.spec.ts | ||
| **/__tests__ | ||
| **/__mocks__ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,39 +1,60 @@ | ||
| SALT=*** | ||
| SERVER_KEY=*** | ||
| RATELIMIT_BYPASS_IPS="***,***,***" | ||
| RATELIMIT_BYPASS_USERIDS="***,***,***" | ||
| # === REQUIRED (Change before running in production) === | ||
| # `SALT`: MUST be changed before deployment. Must be at least 32 characters and generated | ||
| # with a cryptographically secure random generator. | ||
| # Example: `openssl rand -hex 32` | ||
| SALT='CHANGE_ME_SALT_generate_with_openssl_rand_hex_32' | ||
|
|
||
| # `SERVER_KEY`: secret key used for server-to-server auth. MUST be changed before deployment. | ||
| # Generate a long random value (32+ bytes of hex) with a cryptographically secure generator. | ||
| # Example: `openssl rand -hex 32` | ||
| SERVER_KEY='CHANGE_ME_SERVER_KEY_generate_with_openssl_rand_hex_32' | ||
|
|
||
| # Optional rate-limit bypass lists (comma-separated) | ||
| RATELIMIT_BYPASS_IPS="" | ||
| RATELIMIT_BYPASS_USERIDS="1" | ||
|
|
||
| # === DATABASE (Change for your environment) === | ||
| # PostgreSQL DB 설정 | ||
| POSTGRESQL_HOST=*** | ||
| POSTGRESQL_PORT=*** | ||
| POSTGRESQL_USER=*** | ||
| POSTGRESQL_PASSWORD='***' | ||
| POSTGRESQL_NAME=*** | ||
| POSTGRESQL_MAX_CONNS=*** | ||
| POSTGRESQL_CONN_MAX_LIFETIME=*** | ||
| POSTGRESQL_CONN_MAX_IDLE_TIME=*** | ||
| POSTGRESQL_SSL=require | ||
| POSTGRESQL_HOST=postgres | ||
| POSTGRESQL_PORT=5432 | ||
| # `POSTGRESQL_USER`: DB username | ||
| POSTGRESQL_USER=postgres | ||
| # `POSTGRESQL_PASSWORD`: DB password (REQUIRED if not using trust) | ||
| POSTGRESQL_PASSWORD=postgres | ||
| # `POSTGRESQL_NAME`: database name | ||
| POSTGRESQL_NAME=pjsedb | ||
| # `POSTGRESQL_SSL`: set to 'disable' for local docker; use 'require' in production if supported | ||
| POSTGRESQL_SSL=disable | ||
|
|
||
| # Redis 설정 | ||
| REDIS_HOST=*** | ||
| REDIS_PORT=*** | ||
| REDIS_USERNAME=*** | ||
| REDIS_PASSWORD='***' | ||
| REDIS_HOST=redis | ||
| REDIS_PORT=6379 | ||
| REDIS_USERNAME=default | ||
| # `REDIS_PASSWORD`: MUST be set to a strong random value in production if your Redis requires AUTH. | ||
| # Example: `openssl rand -hex 32`. Do NOT use any example or default password in production. | ||
| REDIS_PASSWORD="" | ||
| REDIS_DB=0 | ||
| REDIS_TLS=true | ||
| # 서버 설정 | ||
| REDIS_TLS=false | ||
|
|
||
| # Server settings | ||
| # `HOST`/`PORT`: server listen address and port | ||
| HOST=0.0.0.0 | ||
| ORIGIN="http://localhost:5173" | ||
| PORT=4000 | ||
| ID=1 | ||
| PORT=8000 | ||
| # `ORIGIN`: application origin used for CSRF/trusted origins | ||
| ORIGIN="http://localhost:8000" | ||
| CLOUDFLARED_TUNNEL=false | ||
| ALLOW_TEST_PAGE=true | ||
| ALLOW_REGISTER=true | ||
| SYS_LOG=true | ||
| SYS_LOG_STDOUT=true | ||
| SYS_LOG_LOCATION=./logs | ||
| # 이메일 설정 | ||
| SMTP_HOST=*** | ||
| SMTP_FROM=*** | ||
| SMTP_USERNAME=*** | ||
| SMTP_PASSWORD="***" | ||
|
|
||
| # Email (optional): fill these only if you want email features (recovery/confirmations) | ||
| SMTP_HOST= | ||
| SMTP_FROM= | ||
| SMTP_USERNAME= | ||
| SMTP_PASSWORD="" | ||
| SMTP_SECURITY=force_tls | ||
| SMTP_PORT=*** | ||
| SMTP_PORT= | ||
| # 리버스 프록시 설정 | ||
| #ADDRESS_HEADER=X-Forwarded-For | ||
| #XFF_DEPTH=1 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| name: workflow.yml | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - next | ||
| - feat/** | ||
| - release/** | ||
| paths-ignore: | ||
| - 'readme.md' | ||
| - 'readme.*' | ||
| - 'docker-compose*' | ||
| - 'docs/**' | ||
| - 'licence' | ||
|
|
||
| jobs: | ||
| build-and-push: | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@v3 | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Login to GHCR | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Build and Push Docker Image | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: . | ||
| platforms: linux/amd64 | ||
|
||
| target: runtime | ||
| push: true | ||
| tags: | | ||
| ghcr.io/${{ github.repository_owner }}/pjs2:latest | ||
| ghcr.io/${{ github.repository_owner }}/pjs2:${{ github.sha }} | ||
| cache-from: type=gha | ||
| cache-to: type=gha,mode=max | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,72 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FROM node:25.2.1-alpine AS builder | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WORKDIR /usr/src/app | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN apk update && apk upgrade --no-cache | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN apk add --no-cache \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ca-certificates \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| postgresql-client \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python3 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| make \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| g++ \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gcc \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| musl-dev \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openssl-dev \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgconfig | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| COPY package.json package-lock.json* ./ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RUN --mount=type=cache,target=/root/.npm \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f package-lock.json ]; then npm ci --no-audit --prefer-offline; \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else npm install --no-audit --prefer-offline; fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| COPY . . | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV POSTGRESQL_HOST=127.0.0.1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV POSTGRESQL_PORT=5432 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV POSTGRESQL_USER=postgres | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV POSTGRESQL_PASSWORD=postgres | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check warning on line 27 in Dockerfile
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV POSTGRESQL_NAME=pjsedb | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV POSTGRESQL_SSL=disable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV SALT='super-secret-salt-at-least-32-characters-long-0000' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV SERVER_KEY='super-secret-server-key-000000000000' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check warning on line 31 in Dockerfile
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+32
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ENV POSTGRESQL_HOST=127.0.0.1 | |
| ENV POSTGRESQL_PORT=5432 | |
| ENV POSTGRESQL_USER=postgres | |
| ENV POSTGRESQL_PASSWORD=postgres | |
| ENV POSTGRESQL_NAME=pjsedb | |
| ENV POSTGRESQL_SSL=disable | |
| ENV SALT='super-secret-salt-at-least-32-characters-long-0000' | |
| ENV SERVER_KEY='super-secret-server-key-000000000000' | |
| # Build-time database and crypto configuration used by `npm run drizzle:generate`. | |
| # These MUST be provided via `--build-arg` and MUST NOT contain production secrets. | |
| ARG POSTGRESQL_HOST | |
| ARG POSTGRESQL_PORT | |
| ARG POSTGRESQL_USER | |
| ARG POSTGRESQL_PASSWORD | |
| ARG POSTGRESQL_NAME | |
| ARG POSTGRESQL_SSL | |
| ARG SALT | |
| ARG SERVER_KEY | |
| ENV POSTGRESQL_HOST=${POSTGRESQL_HOST} | |
| ENV POSTGRESQL_PORT=${POSTGRESQL_PORT} | |
| ENV POSTGRESQL_USER=${POSTGRESQL_USER} | |
| ENV POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD} | |
| ENV POSTGRESQL_NAME=${POSTGRESQL_NAME} | |
| ENV POSTGRESQL_SSL=${POSTGRESQL_SSL} | |
| ENV SALT=${SALT} | |
| ENV SERVER_KEY=${SERVER_KEY} |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| #!/bin/sh | ||
|
|
||
| set -e | ||
|
|
||
| if [ "$(id -u)" = "0" ]; then | ||
| echo "Running as root, fixing volume permissions..." | ||
|
|
||
| if [ -d /usr/src/app/logs ]; then | ||
| echo "Fixing permissions for /usr/src/app/logs" | ||
| if ! chown -R node:node /usr/src/app/logs; then | ||
| echo "Warning: Could not change ownership of /usr/src/app/logs" >&2 | ||
| fi | ||
| fi | ||
|
|
||
| if [ -d /var/lib/postgresql/data ]; then | ||
| echo "Fixing permissions for /var/lib/postgresql/data" | ||
| if ! chown -R node:node /var/lib/postgresql/data; then | ||
| echo "Warning: Could not change ownership of /var/lib/postgresql/data" >&2 | ||
| fi | ||
| fi | ||
|
|
||
| if [ -d /data/redis ]; then | ||
| echo "Fixing permissions for /data/redis" | ||
| if ! chown -R node:node /data/redis; then | ||
| echo "Warning: Could not change ownership of /data/redis" >&2 | ||
| fi | ||
| fi | ||
|
|
||
| echo "Switching to node user with su-exec..." | ||
| if command -v su-exec >/dev/null 2>&1; then | ||
| exec su-exec node "$0" "$@" | ||
| else | ||
| echo "ERROR: su-exec not found! Falling back to su" | ||
| # shellcheck disable=SC2016 | ||
| exec su node -s /bin/sh -c 'exec "$0" "$@"' -- "$0" "$@" | ||
| fi | ||
| fi | ||
|
|
||
| # 이하 node 유저로 실행 | ||
| echo "Running as $(whoami) (UID: $(id -u))" | ||
|
|
||
| # PJSe.json 자동 다운로드 | ||
| PJSe_FILE="/usr/src/app/exchanges/PJSe.json" | ||
| DEFAULT_PJSe_URL="https://raw.githubusercontent.com/0ghost0-dev/PJS2/refs/heads/next/exchanges/PJSe.json" | ||
|
|
||
| if [ ! -f "$PJSe_FILE" ]; then | ||
| echo "PJSe.json not found. Downloading from GitHub..." | ||
| mkdir -p /usr/src/app/exchanges | ||
| PJSe_URL="${PJSe_CONFIG_URL:-$DEFAULT_PJSe_URL}" | ||
|
|
||
| if command -v wget >/dev/null 2>&1; then | ||
| wget -q "$PJSe_URL" -O "$PJSe_FILE" || { | ||
| echo "Error: Failed to download PJSe.json from $PJSe_URL" | ||
| exit 1 | ||
| } | ||
| elif command -v curl >/dev/null 2>&1; then | ||
| curl -fsSL "$PJSe_URL" -o "$PJSe_FILE" || { | ||
| echo "Error: Failed to download PJSe.json from $PJSe_URL" | ||
| exit 1 | ||
| } | ||
| else | ||
| echo "Error: Neither wget nor curl available" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Successfully downloaded PJSe.json from $PJSe_URL" | ||
| else | ||
| echo "PJSe.json already exists at $PJSe_FILE" | ||
| fi | ||
|
Comment on lines
+42
to
+69
|
||
|
|
||
| echo "Waiting for Postgres at ${POSTGRESQL_HOST:-postgres}:${POSTGRESQL_PORT:-5432}..." | ||
| until pg_isready -h "${POSTGRESQL_HOST:-postgres}" -p "${POSTGRESQL_PORT:-5432}" -U "${POSTGRESQL_USER:-postgres}" >/dev/null 2>&1; do | ||
| sleep 1 | ||
| done | ||
|
Comment on lines
+71
to
+74
|
||
|
|
||
| echo "Postgres is available. Starting app..." | ||
| exec "$@" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,12 +15,12 @@ | |
| "logo": "https://example.com/logo.png", | ||
| "description": "Project. Stock Exchange is a fictional stock exchange used for demonstration purposes.", | ||
| "pre_market_sessions": { | ||
| "Monday": { "open": "08:30", "close": "09:00" }, | ||
| "Tuesday": { "open": "08:30", "close": "09:00" }, | ||
| "Wednesday": { "open": "08:30", "close": "09:00" }, | ||
| "Thursday": { "open": "08:30", "close": "09:00" }, | ||
| "Friday": { "open": "08:30", "close": "09:00" }, | ||
| "Saturday": { "open": null, "close": null }, | ||
| "Monday": { "open": "02:00", "close": "09:00" }, | ||
| "Tuesday": { "open": "02:00", "close": "09:00" }, | ||
| "Wednesday": { "open": "02:00", "close": "09:00" }, | ||
| "Thursday": { "open": "02:00", "close": "09:00" }, | ||
| "Friday": { "open": "02:00", "close": "09:00" }, | ||
| "Saturday": { "open": "02:00", "close": "10:00" }, | ||
| "Sunday": { "open": null, "close": null } | ||
| }, | ||
| "regular_trading_sessions": { | ||
|
|
@@ -29,16 +29,16 @@ | |
| "Wednesday": { "open": "09:00", "close": "15:30" }, | ||
| "Thursday": { "open": "09:00", "close": "15:30" }, | ||
| "Friday": { "open": "09:00", "close": "15:30" }, | ||
| "Saturday": { "open": null, "close": null }, | ||
| "Saturday": { "open": "10:00", "close": "14:00" }, | ||
| "Sunday": { "open": null, "close": null } | ||
| }, | ||
| "post_market_sessions": { | ||
| "Monday": { "open": "15:30", "close": "16:00" }, | ||
| "Tuesday": { "open": "15:30", "close": "16:00" }, | ||
| "Wednesday": { "open": "15:30", "close": "16:00" }, | ||
| "Thursday": { "open": "15:30", "close": "16:00" }, | ||
| "Friday": { "open": "15:30", "close": "16:00" }, | ||
| "Saturday": { "open": null, "close": null }, | ||
| "Monday": { "open": "15:30", "close": "00:00" }, | ||
| "Tuesday": { "open": "15:30", "close": "00:00" }, | ||
| "Wednesday": { "open": "15:30", "close": "00:00" }, | ||
| "Thursday": { "open": "15:30", "close": "00:00" }, | ||
| "Friday": { "open": "15:30", "close": "00:00" }, | ||
|
Comment on lines
+36
to
+40
|
||
| "Saturday": { "open": "14:00", "close": "20:00" }, | ||
| "Sunday": { "open": null, "close": null } | ||
| }, | ||
| "anniversaries": [{ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting POSTGRESQL_SSL=disable by default in the example configuration encourages insecure deployments. While this may be appropriate for local development, the comment should more strongly emphasize that SSL should be enabled in production environments to prevent credentials and data from being transmitted in cleartext.