add docker and docker-compose
This commit is contained in:
7
.claude/settings.local.json
Normal file
7
.claude/settings.local.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(sudo docker compose:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
34
.dockerignore
Normal file
34
.dockerignore
Normal file
@@ -0,0 +1,34 @@
|
||||
node_modules
|
||||
.git
|
||||
.env
|
||||
.env*
|
||||
*.log
|
||||
.nyc_output
|
||||
coverage
|
||||
.DS_Store
|
||||
.turbo
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# Test files
|
||||
integration-tests/
|
||||
**/__tests__/
|
||||
**/*.spec.ts
|
||||
**/*.test.ts
|
||||
|
||||
# Documentation
|
||||
www/
|
||||
**/*.md
|
||||
!README.md
|
||||
docs/
|
||||
|
||||
# Build artifacts
|
||||
**/dist/
|
||||
**/build/
|
||||
|
||||
# Cache
|
||||
.yarn/cache
|
||||
.yarn/install-state.gz
|
||||
|
||||
# Misc
|
||||
.claude/
|
||||
32
.gitignore
vendored
32
.gitignore
vendored
@@ -1,21 +1,21 @@
|
||||
.env
|
||||
node_modules
|
||||
*yarn-error.log
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
packages/**/.yarn/*
|
||||
integration-tests/**/.yarn/*
|
||||
www/**/.yarn/*
|
||||
|
||||
packages/**/plugins/**/.medusa/
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
.env.test
|
||||
.nyc_output
|
||||
coverage
|
||||
.DS_Store
|
||||
*.log
|
||||
dist
|
||||
build
|
||||
.yarn
|
||||
.env
|
||||
.env*
|
||||
/packages
|
||||
|
||||
.eslintcache
|
||||
|
||||
|
||||
@@ -11,5 +11,3 @@ plugins:
|
||||
spec: "@yarnpkg/plugin-workspace-tools"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.1.cjs
|
||||
|
||||
35
Dockerfile
Normal file
35
Dockerfile
Normal file
@@ -0,0 +1,35 @@
|
||||
ARG NODE_VERSION=20
|
||||
ARG NODE_ENV=production
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine AS deps
|
||||
WORKDIR /server
|
||||
RUN corepack enable && corepack prepare yarn@3.2.1 --activate
|
||||
COPY package.json yarn.lock .yarnrc.yml ./
|
||||
COPY .yarn .yarn
|
||||
# Copy package.json files to preserve workspace structure
|
||||
COPY packages packages
|
||||
RUN yarn install --immutable
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine AS builder
|
||||
WORKDIR /server
|
||||
RUN corepack enable && corepack prepare yarn@3.2.1 --activate
|
||||
COPY --from=deps /server .
|
||||
COPY . .
|
||||
RUN yarn build
|
||||
|
||||
# Build draft-order plugin admin extensions
|
||||
RUN cd packages/plugins/draft-order && npx medusa plugin:build
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine AS runtime
|
||||
WORKDIR /server
|
||||
RUN addgroup -g 1001 medusa && adduser -D -u 1001 -G medusa medusa
|
||||
RUN corepack enable && corepack prepare yarn@3.2.1 --activate
|
||||
COPY --from=builder --chown=medusa:medusa /server .
|
||||
USER medusa
|
||||
EXPOSE 9000 5173
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
|
||||
CMD wget -q --spider http://localhost:9000/health || exit 1
|
||||
LABEL org.opencontainers.image.description="Medusa Commerce Platform"
|
||||
|
||||
ENTRYPOINT []
|
||||
CMD ["./start.sh"]
|
||||
51
Dockerfile.dev
Normal file
51
Dockerfile.dev
Normal file
@@ -0,0 +1,51 @@
|
||||
ARG NODE_VERSION=20
|
||||
ARG NODE_ENV=production
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine
|
||||
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
|
||||
WORKDIR /server
|
||||
|
||||
# Install dependencies for native modules
|
||||
RUN apk add --no-cache python3 make g++ git
|
||||
|
||||
# Enable Corepack
|
||||
RUN corepack enable && corepack prepare yarn@3.2.1 --activate
|
||||
|
||||
# Create non-root user (remove default node user if it conflicts)
|
||||
RUN deluser --remove-home node 2>/dev/null || true && \
|
||||
addgroup -g ${GID} medusa && \
|
||||
adduser -D -u ${UID} -G medusa medusa && \
|
||||
chown medusa:medusa /server
|
||||
|
||||
# Switch to non-root user
|
||||
USER medusa
|
||||
|
||||
# Copy dependency files first for better caching
|
||||
COPY --chown=medusa:medusa package.json yarn.lock .yarnrc.yml ./
|
||||
COPY --chown=medusa:medusa .yarn .yarn
|
||||
COPY --chown=medusa:medusa packages packages
|
||||
|
||||
# Install all dependencies (including devDependencies)
|
||||
RUN yarn install
|
||||
|
||||
# Copy remaining files
|
||||
COPY --chown=medusa:medusa . .
|
||||
|
||||
# Build packages
|
||||
RUN yarn build
|
||||
|
||||
# Build draft-order plugin admin extensions
|
||||
RUN cd packages/plugins/draft-order && npx medusa plugin:build
|
||||
|
||||
EXPOSE 9000 5173
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \
|
||||
CMD wget -q --spider http://localhost:9000/health || exit 1
|
||||
|
||||
LABEL org.opencontainers.image.description="Medusa Commerce Platform (Dev)"
|
||||
|
||||
ENTRYPOINT []
|
||||
CMD ["./start.sh"]
|
||||
110
docker-compose.yml
Normal file
110
docker-compose.yml
Normal file
@@ -0,0 +1,110 @@
|
||||
services:
|
||||
# PostgreSQL Database
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: medusa-store
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- ${GLOBAL_DATA_FOLDER:-/Data}/${SERVICE_NAME_OVERRIDE:-my-medusa-store}/postgres_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- default
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres -d medusa-store"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
|
||||
# Redis
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6379:6379"
|
||||
networks:
|
||||
- default
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
|
||||
medusa:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
args:
|
||||
UID: ${UID:-1000}
|
||||
GID: ${GID:-1000}
|
||||
user: "${UID:-1000}:${GID:-1000}"
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "9000:9000"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/medusa-store
|
||||
- REDIS_URL=redis://redis:6379
|
||||
env_file:
|
||||
- .env
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "--spider", "http://localhost:9000/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
start_period: 120s
|
||||
retries: 3
|
||||
develop:
|
||||
watch:
|
||||
- action: sync
|
||||
path: ./packages
|
||||
target: /server/packages
|
||||
- action: sync
|
||||
path: ./medusa-config.js
|
||||
target: /server/medusa-config.js
|
||||
- action: sync
|
||||
path: ./start.sh
|
||||
target: /server/start.sh
|
||||
- action: rebuild
|
||||
path: package.json
|
||||
- action: rebuild
|
||||
path: yarn.lock
|
||||
networks:
|
||||
- default
|
||||
- traefik_default
|
||||
labels:
|
||||
com.centurylinklabs.watchtower.enable: "true"
|
||||
traefik.docker.network: traefik_default
|
||||
traefik.enable: true
|
||||
traefik.http.routers.my-medusa-store.entrypoints: websecure
|
||||
traefik.http.routers.my-medusa-store.rule: Host(`${SERVICE_NAME_OVERRIDE:-my-medusa-store}.${DOMAIN_NAME:-local}`)
|
||||
traefik.http.routers.my-medusa-store.service: my-medusa-store
|
||||
traefik.http.routers.my-medusa-store.tls: true
|
||||
traefik.http.routers.my-medusa-store.tls.certresolver: letsencrypt-cloudflare-dns-challenge
|
||||
traefik.http.services.my-medusa-store.loadbalancer.server.port: 9000
|
||||
local.yacht.port.9000: WebUI
|
||||
traefik.http.routers.my-medusa-store-admin.entrypoints: websecure
|
||||
traefik.http.routers.my-medusa-store-admin.rule: Host(`${SERVICE_NAME_OVERRIDE:-my-medusa-store}-admin.${DOMAIN_NAME:-local}`)
|
||||
traefik.http.routers.my-medusa-store-admin.service: my-medusa-store-admin
|
||||
traefik.http.routers.my-medusa-store-admin.tls: true
|
||||
traefik.http.routers.my-medusa-store-admin.tls.certresolver: letsencrypt-cloudflare-dns-challenge
|
||||
traefik.http.services.my-medusa-store-admin.loadbalancer.server.port: 5173
|
||||
local.yacht.port.5173: WebUI
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
traefik_default:
|
||||
external: true
|
||||
63
medusa-config.js
Normal file
63
medusa-config.js
Normal file
@@ -0,0 +1,63 @@
|
||||
const { defineConfig, Modules } = require("@medusajs/framework/utils")
|
||||
|
||||
module.exports = defineConfig({
|
||||
admin: {
|
||||
vite: () => {
|
||||
return {
|
||||
server: {
|
||||
allowedHosts: [
|
||||
".nett00n.org",
|
||||
"reka.nett00n.org",
|
||||
"http://reka.nett00n.org:9000",
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
projectConfig: {
|
||||
databaseUrl: process.env.DATABASE_URL,
|
||||
databaseDriverOptions: {
|
||||
connection: {
|
||||
ssl: false,
|
||||
},
|
||||
},
|
||||
redisUrl: process.env.REDIS_URL,
|
||||
http: {
|
||||
jwtSecret: process.env.JWT_SECRET || "supersecret",
|
||||
cookieSecret: process.env.COOKIE_SECRET || "supersecret",
|
||||
},
|
||||
},
|
||||
modules: {
|
||||
[Modules.FILE]: {
|
||||
resolve: "@medusajs/file",
|
||||
options: {
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/file-local",
|
||||
id: "local",
|
||||
options: {
|
||||
upload_dir: "uploads",
|
||||
backend_url: "http://localhost:9000",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
[Modules.NOTIFICATION]: {
|
||||
resolve: "@medusajs/notification",
|
||||
options: {
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/notification-local",
|
||||
id: "local",
|
||||
options: {
|
||||
name: "Local Notification Provider",
|
||||
channels: ["feed"],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -23,6 +23,7 @@
|
||||
"@atomico/rollup-plugin-sizes": "^1.1.4",
|
||||
"@aws-sdk/client-dynamodb": "^3.218.0",
|
||||
"@faker-js/faker": "^9.2.0",
|
||||
"@medusajs/medusa": "workspace:^",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@storybook/addon-essentials": "^8.3.5",
|
||||
|
||||
114
start.sh
Executable file
114
start.sh
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
# Colors (disabled if not a terminal)
|
||||
if [ -t 1 ]; then
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
else
|
||||
RED='' GREEN='' YELLOW='' BLUE='' NC=''
|
||||
fi
|
||||
|
||||
timestamp() {
|
||||
date -u +%Y-%m-%dT%H:%M:%SZ
|
||||
}
|
||||
|
||||
log_info() {
|
||||
printf "💙 ${BLUE}[%s] [INFO]${NC} %s\n" "$(timestamp)" "$1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
printf "💚 ${GREEN}[%s] [SUCCESS]${NC} %s\n" "$(timestamp)" "$1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
printf "❤ ${RED}[%s] [ERROR]${NC} %s\n" "$(timestamp)" "$1" >&2
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
printf "💛 ${YELLOW}[%s] [WARN]${NC} %s\n" "$(timestamp)" "$1"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
log_warn "Received shutdown signal, cleaning up..."
|
||||
# Kill child processes
|
||||
jobs -p | xargs kill 2>/dev/null || true
|
||||
exit 130
|
||||
}
|
||||
|
||||
trap cleanup INT TERM
|
||||
|
||||
# Pre-flight checks
|
||||
log_info "Starting Medusa development environment..."
|
||||
|
||||
if find . -maxdepth 1 -mindepth 1 ! -uid "$UID" -print -quit | grep -q .; then
|
||||
echo "ERROR: files not owned by UID=$UID exist in current directory. If running in DEVELOPER_MODE, fill UID and GID of your user in .env file and rebuild" >&2
|
||||
find . -maxdepth 1 -mindepth 1 ! -uid "$UID" -ls >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if find . -maxdepth 1 -mindepth 1 ! -gid "$GID" -print -quit | grep -q .; then
|
||||
echo "ERROR: files not owned by GID=$GID exist in current directory. If running in DEVELOPER_MODE, fill UID and GID of your user in .env file and rebuild" >&2
|
||||
find . -maxdepth 1 -mindepth 1 ! -gid "$GID" -ls >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "medusa-config.js" ]; then
|
||||
log_error "medusa-config.js not found. Are you in the Medusa project root?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "node_modules" ]; then
|
||||
log_error "node_modules/ not found. Run 'yarn install' first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${DATABASE_URL:-}" ]; then
|
||||
log_error "DATABASE_URL environment variable is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Database connectivity check (optional, can be skipped with --skip-db-check)
|
||||
if [ "${1:-}" != "--skip-db-check" ]; then
|
||||
log_info "Checking database connectivity..."
|
||||
# Simple check using npx medusa (will fail if DB is unreachable)
|
||||
if ! npx medusa db:check 2>/dev/null; then
|
||||
log_warn "Database connectivity check failed (this is OK if db:check doesn't exist)"
|
||||
else
|
||||
log_success "Database is reachable"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run migrations
|
||||
log_info "Running database migrations..."
|
||||
start_time=$(date +%s)
|
||||
|
||||
if npx medusa db:migrate; then
|
||||
migration_time=$(($(date +%s) - start_time))
|
||||
log_success "Migrations completed in ${migration_time}s"
|
||||
else
|
||||
log_error "Migration failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create admin user if credentials are provided
|
||||
if [ -n "${ADMIN_LOGIN:-}" ] && [ -n "${ADMIN_PASSWORD:-}" ]; then
|
||||
log_info "Creating admin user with email: ${ADMIN_LOGIN}..."
|
||||
|
||||
if npx medusa user -e "${ADMIN_LOGIN}" -p "${ADMIN_PASSWORD}"; then
|
||||
log_success "Admin user created successfully"
|
||||
else
|
||||
log_warn "Admin user creation failed (user may already exist)"
|
||||
fi
|
||||
elif [ -n "${ADMIN_LOGIN:-}" ] || [ -n "${ADMIN_PASSWORD:-}" ]; then
|
||||
log_warn "Both ADMIN_LOGIN and ADMIN_PASSWORD must be set to create admin user"
|
||||
fi
|
||||
|
||||
# Start development server
|
||||
log_info "Starting Medusa development server..."
|
||||
log_info "Press Ctrl+C to stop"
|
||||
|
||||
npx medusa develop
|
||||
6
tsconfig.json
Normal file
6
tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user