diff --git a/.gitignore b/.gitignore index ee677a7..403b982 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,8 @@ Temporary Items # Local runtime data and certificates data/ deploy/bin/ + +# Environment secrets +.env +deploy/.env +!deploy/.env.example diff --git a/deploy/.env.example b/deploy/.env.example new file mode 100644 index 0000000..f9d37d9 --- /dev/null +++ b/deploy/.env.example @@ -0,0 +1,13 @@ +# Copy this file to .env and fill in real values +# NEVER commit .env to git + +# Database passwords (REQUIRED) +MYSQL_ROOT_PASSWORD=your_mysql_password_here +POSTGRES_PASSWORD=your_postgres_password_here + +# JWT secret for gateway auth (REQUIRED) +ACCESS_SECRET=your_jwt_secret_here + +# Neo4j (only needed for graph stack: docker-compose.graph.yaml) +NEO4J_AUTH=neo4j/your_neo4j_password_here +NEO4J_PASS=your_neo4j_password_here diff --git a/deploy/Dockerfile.gateway b/deploy/Dockerfile.gateway index 5a3daf9..beb980d 100644 --- a/deploy/Dockerfile.gateway +++ b/deploy/Dockerfile.gateway @@ -11,10 +11,12 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./gateway/gateway. FROM ${BASE_REGISTRY}/alpine:3.20 RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories -RUN apk add --no-cache ca-certificates tzdata +RUN apk add --no-cache ca-certificates tzdata gettext WORKDIR /app COPY --from=builder /server ./gateway COPY deploy/etc/gateway.yaml etc/gateway.yaml COPY deploy/tools/ tools/ +COPY deploy/entrypoint.sh /entrypoint.sh EXPOSE 8888 +ENTRYPOINT ["/entrypoint.sh"] CMD ["./gateway", "-f", "etc/gateway.yaml"] diff --git a/deploy/Dockerfile.inventory b/deploy/Dockerfile.inventory index be680ef..fde5328 100644 --- a/deploy/Dockerfile.inventory +++ b/deploy/Dockerfile.inventory @@ -11,9 +11,11 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./rpc/inventory/in FROM ${BASE_REGISTRY}/alpine:3.20 RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories -RUN apk add --no-cache ca-certificates tzdata +RUN apk add --no-cache ca-certificates tzdata gettext WORKDIR /app COPY --from=builder /server ./inventory COPY deploy/etc/inventory.yaml etc/inventory.yaml +COPY deploy/entrypoint.sh /entrypoint.sh EXPOSE 9002 +ENTRYPOINT ["/entrypoint.sh"] CMD ["./inventory", "-f", "etc/inventory.yaml"] diff --git a/deploy/Dockerfile.purchase b/deploy/Dockerfile.purchase index 0685300..c63bb1a 100644 --- a/deploy/Dockerfile.purchase +++ b/deploy/Dockerfile.purchase @@ -1,7 +1,9 @@ FROM alpine:3.19 -RUN apk add --no-cache ca-certificates tzdata +RUN apk add --no-cache ca-certificates tzdata gettext WORKDIR /app COPY deploy/bin/purchase . COPY deploy/etc/purchase.yaml etc/purchase.yaml +COPY deploy/entrypoint.sh /entrypoint.sh EXPOSE 9003 +ENTRYPOINT ["/entrypoint.sh"] CMD ["./purchase", "-f", "etc/purchase.yaml"] diff --git a/deploy/Dockerfile.system b/deploy/Dockerfile.system index f6de550..84aa713 100644 --- a/deploy/Dockerfile.system +++ b/deploy/Dockerfile.system @@ -11,9 +11,11 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /server ./rpc/system/syste FROM ${BASE_REGISTRY}/alpine:3.20 RUN sed -i "s|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g" /etc/apk/repositories -RUN apk add --no-cache ca-certificates tzdata +RUN apk add --no-cache ca-certificates tzdata gettext WORKDIR /app COPY --from=builder /server ./system COPY deploy/etc/system.yaml etc/system.yaml +COPY deploy/entrypoint.sh /entrypoint.sh EXPOSE 9001 +ENTRYPOINT ["/entrypoint.sh"] CMD ["./system", "-f", "etc/system.yaml"] diff --git a/deploy/docker-compose.graph.yaml b/deploy/docker-compose.graph.yaml index 41fe1ca..87b9cac 100644 --- a/deploy/docker-compose.graph.yaml +++ b/deploy/docker-compose.graph.yaml @@ -5,7 +5,7 @@ services: restart: always environment: POSTGRES_USER: muyu - POSTGRES_PASSWORD: muyu2026 + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env} POSTGRES_DB: muyu_crm TZ: Asia/Shanghai ports: @@ -70,7 +70,7 @@ services: container_name: muyu-neo4j restart: always environment: - NEO4J_AUTH: neo4j/muyu2026 + NEO4J_AUTH: ${NEO4J_AUTH:?Set NEO4J_AUTH in .env (e.g. neo4j/yourpassword)} NEO4J_server_memory_heap_initial__size: 512m NEO4J_server_memory_heap_max__size: 1024m NEO4J_server_default__listen__address: 0.0.0.0 @@ -103,7 +103,7 @@ services: KAFKA_GROUP: graphsync NEO4J_URI: bolt://neo4j:7687 NEO4J_USER: neo4j - NEO4J_PASS: muyu2026 + NEO4J_PASS: ${NEO4J_PASS:?Set NEO4J_PASS in .env} TZ: Asia/Shanghai kafka-ui: diff --git a/deploy/docker-compose.yaml b/deploy/docker-compose.yaml index 3394045..1429ac1 100644 --- a/deploy/docker-compose.yaml +++ b/deploy/docker-compose.yaml @@ -4,7 +4,7 @@ services: container_name: muyu-mysql restart: always environment: - MYSQL_ROOT_PASSWORD: muyu2026 + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?Set MYSQL_ROOT_PASSWORD in .env} MYSQL_DATABASE: muyu_wms TZ: Asia/Shanghai ports: @@ -39,7 +39,7 @@ services: restart: always environment: POSTGRES_USER: muyu - POSTGRES_PASSWORD: muyu2026 + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env} POSTGRES_DB: muyu_crm TZ: Asia/Shanghai ports: @@ -90,6 +90,7 @@ services: condition: service_healthy environment: TZ: Asia/Shanghai + MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai" inventory-rpc: build: @@ -106,6 +107,7 @@ services: condition: service_healthy environment: TZ: Asia/Shanghai + MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai" purchase-rpc: build: @@ -122,6 +124,7 @@ services: condition: service_healthy environment: TZ: Asia/Shanghai + MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai" gateway: build: @@ -142,6 +145,9 @@ services: condition: service_healthy environment: TZ: Asia/Shanghai + MYSQL_DSN: "root:${MYSQL_ROOT_PASSWORD}@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai" + POSTGRES_DSN: "postgres://muyu:${POSTGRES_PASSWORD}@postgres:5432/muyu_crm?sslmode=disable" + ACCESS_SECRET: ${ACCESS_SECRET:?Set ACCESS_SECRET in .env} nginx: image: nginx:alpine diff --git a/deploy/entrypoint.sh b/deploy/entrypoint.sh new file mode 100755 index 0000000..66709c4 --- /dev/null +++ b/deploy/entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# Substitute environment variables in YAML config templates before starting the service. +# Usage: entrypoint.sh -f +# +# The YAML file is treated as a template with ${VAR} placeholders. +# envsubst replaces them with actual environment variable values at container start time. + +set -e + +BINARY="$1" +shift + +CONFIG_FILE="" +for arg in "$@"; do + case "$prev" in + -f) CONFIG_FILE="$arg" ;; + esac + prev="$arg" +done + +if [ -n "$CONFIG_FILE" ] && [ -f "$CONFIG_FILE" ]; then + # Replace ${VAR} placeholders with environment variable values + envsubst < "$CONFIG_FILE" > "${CONFIG_FILE}.tmp" + mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE" +fi + +exec "$BINARY" "$@" diff --git a/deploy/etc/gateway.yaml b/deploy/etc/gateway.yaml index 626135d..a67dc4b 100644 --- a/deploy/etc/gateway.yaml +++ b/deploy/etc/gateway.yaml @@ -4,12 +4,12 @@ Port: 8888 Timeout: 120000 Auth: - AccessSecret: muyu-wms-jwt-secret-key-2026 + AccessSecret: ${ACCESS_SECRET} AccessExpire: 7200 DefaultTenantId: t_default_001 -DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai -PostgresDataSource: "postgres://muyu:muyu2026@postgres:5432/muyu_crm?sslmode=disable" +DataSource: ${MYSQL_DSN} +PostgresDataSource: ${POSTGRES_DSN} SystemRpc: Etcd: diff --git a/deploy/etc/inventory.yaml b/deploy/etc/inventory.yaml index 4c6c6d4..327f143 100644 --- a/deploy/etc/inventory.yaml +++ b/deploy/etc/inventory.yaml @@ -6,7 +6,7 @@ Etcd: - etcd:2379 Key: inventory.rpc -DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai +DataSource: ${MYSQL_DSN} Cache: - Host: redis:6379 diff --git a/deploy/etc/purchase.yaml b/deploy/etc/purchase.yaml index 4f5e2d3..4530dba 100644 --- a/deploy/etc/purchase.yaml +++ b/deploy/etc/purchase.yaml @@ -6,7 +6,7 @@ Etcd: - etcd:2379 Key: purchase.rpc -DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai +DataSource: ${MYSQL_DSN} Cache: - Host: redis:6379 diff --git a/deploy/etc/system.yaml b/deploy/etc/system.yaml index 199ffb6..594a20b 100644 --- a/deploy/etc/system.yaml +++ b/deploy/etc/system.yaml @@ -6,7 +6,7 @@ Etcd: - etcd:2379 Key: system.rpc -DataSource: root:muyu2026@tcp(mysql:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai +DataSource: ${MYSQL_DSN} Cache: - Host: redis:6379 diff --git a/gateway/etc/gateway-api.yaml b/gateway/etc/gateway-api.yaml index dda2fdd..576d03d 100644 --- a/gateway/etc/gateway-api.yaml +++ b/gateway/etc/gateway-api.yaml @@ -1,14 +1,15 @@ +# Local development config — fill in credentials before running locally. Name: gateway-api Host: 0.0.0.0 Port: 8888 Auth: - AccessSecret: muyu-wms-jwt-secret-key-2026 + AccessSecret: your_jwt_secret_here AccessExpire: 7200 DefaultTenantId: t_default_001 -DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai -PostgresDataSource: "postgres://muyu:muyu2026@127.0.0.1:5432/muyu_crm?sslmode=disable" +DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai +PostgresDataSource: "postgres://muyu:your_password@127.0.0.1:5432/muyu_crm?sslmode=disable" SystemRpc: Etcd: diff --git a/rpc/inventory/etc/inventory.yaml b/rpc/inventory/etc/inventory.yaml index c91f827..fcb1fda 100644 --- a/rpc/inventory/etc/inventory.yaml +++ b/rpc/inventory/etc/inventory.yaml @@ -1,3 +1,4 @@ +# Local development config — fill in DataSource before running locally. Name: inventory.rpc ListenOn: 0.0.0.0:9002 @@ -6,7 +7,7 @@ Etcd: - 127.0.0.1:2379 Key: inventory.rpc -DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai +DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai Cache: - Host: 127.0.0.1:6379 diff --git a/rpc/purchase/etc/purchase.yaml b/rpc/purchase/etc/purchase.yaml index 0fbdf34..e0a9138 100644 --- a/rpc/purchase/etc/purchase.yaml +++ b/rpc/purchase/etc/purchase.yaml @@ -1,3 +1,4 @@ +# Local development config — fill in DataSource before running locally. Name: purchase.rpc ListenOn: 0.0.0.0:9003 @@ -6,7 +7,7 @@ Etcd: - 127.0.0.1:2379 Key: purchase.rpc -DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai +DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai Cache: - Host: 127.0.0.1:6379 diff --git a/rpc/system/etc/system.yaml b/rpc/system/etc/system.yaml index 9f32d80..c052953 100644 --- a/rpc/system/etc/system.yaml +++ b/rpc/system/etc/system.yaml @@ -1,3 +1,5 @@ +# Local development config — fill in DataSource before running locally. +# For Docker deployment, see deploy/etc/system.yaml (uses envsubst). Name: system.rpc ListenOn: 0.0.0.0:9001 @@ -6,7 +8,7 @@ Etcd: - 127.0.0.1:2379 Key: system.rpc -DataSource: root:muyu2026@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai +DataSource: root:your_password@tcp(127.0.0.1:3306)/muyu_wms?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai Cache: - Host: 127.0.0.1:6379 diff --git a/worker/graphsync/main.go b/worker/graphsync/main.go index 08f4fed..9d9e9b6 100644 --- a/worker/graphsync/main.go +++ b/worker/graphsync/main.go @@ -32,7 +32,7 @@ func main() { flag.StringVar(&cfg.KafkaGroup, "kafka-group", envOr("KAFKA_GROUP", "graphsync"), "consumer group") flag.StringVar(&cfg.Neo4jURI, "neo4j-uri", envOr("NEO4J_URI", "bolt://localhost:7687"), "Neo4j bolt URI") flag.StringVar(&cfg.Neo4jUser, "neo4j-user", envOr("NEO4J_USER", "neo4j"), "Neo4j user") - flag.StringVar(&cfg.Neo4jPass, "neo4j-pass", envOr("NEO4J_PASS", "muyu2026"), "Neo4j password") + flag.StringVar(&cfg.Neo4jPass, "neo4j-pass", envOr("NEO4J_PASS", ""), "Neo4j password") flag.Parse() ctx, cancel := context.WithCancel(context.Background())