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/
|
||||||
34
.gitignore
vendored
34
.gitignore
vendored
@@ -1,21 +1,21 @@
|
|||||||
.env
|
|
||||||
node_modules
|
node_modules
|
||||||
*yarn-error.log
|
npm-debug.log*
|
||||||
.pnp.*
|
yarn-debug.log*
|
||||||
.yarn/*
|
yarn-error.log*
|
||||||
!.yarn/patches
|
.git
|
||||||
!.yarn/plugins
|
.gitignore
|
||||||
!.yarn/releases
|
README.md
|
||||||
!.yarn/sdks
|
.env.test
|
||||||
!.yarn/versions
|
.nyc_output
|
||||||
|
coverage
|
||||||
packages/**/.yarn/*
|
|
||||||
integration-tests/**/.yarn/*
|
|
||||||
www/**/.yarn/*
|
|
||||||
|
|
||||||
packages/**/plugins/**/.medusa/
|
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.log
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
.yarn
|
||||||
|
.env
|
||||||
|
.env*
|
||||||
|
/packages
|
||||||
|
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
|
||||||
@@ -34,4 +34,4 @@ dist/**
|
|||||||
/packages/**/.cache
|
/packages/**/.cache
|
||||||
|
|
||||||
.cursorignore
|
.cursorignore
|
||||||
**/.medusa
|
**/.medusa
|
||||||
|
|||||||
@@ -11,5 +11,3 @@ plugins:
|
|||||||
spec: "@yarnpkg/plugin-workspace-tools"
|
spec: "@yarnpkg/plugin-workspace-tools"
|
||||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||||
spec: "@yarnpkg/plugin-interactive-tools"
|
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",
|
"@atomico/rollup-plugin-sizes": "^1.1.4",
|
||||||
"@aws-sdk/client-dynamodb": "^3.218.0",
|
"@aws-sdk/client-dynamodb": "^3.218.0",
|
||||||
"@faker-js/faker": "^9.2.0",
|
"@faker-js/faker": "^9.2.0",
|
||||||
|
"@medusajs/medusa": "workspace:^",
|
||||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||||
"@rollup/plugin-replace": "^5.0.2",
|
"@rollup/plugin-replace": "^5.0.2",
|
||||||
"@storybook/addon-essentials": "^8.3.5",
|
"@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