Add Portainer stack.env support for environment variable management
- Add docker/stack.env template for Portainer deployment - Update Dockerfile to accept build args for Next.js environment variables - Update docker-compose.deploy.yml to pass build args from environment - Add comprehensive Portainer deployment guide in DOCKER_DEPLOYMENT.md - Document environment variable setup for both CLI and Portainer deployments
This commit is contained in:
+71
-2
@@ -26,6 +26,8 @@ MinIO console: `http://localhost:9001` (minioadmin / minioadmin)
|
|||||||
|
|
||||||
## Production Deployment
|
## Production Deployment
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
### 1. Prepare Environment
|
### 1. Prepare Environment
|
||||||
|
|
||||||
Copy and configure the production environment file:
|
Copy and configure the production environment file:
|
||||||
@@ -34,7 +36,13 @@ Copy and configure the production environment file:
|
|||||||
cp docker/.env.production .env.production
|
cp docker/.env.production .env.production
|
||||||
```
|
```
|
||||||
|
|
||||||
Edit `.env.production` and set:
|
Or for Portainer deployment, copy the stack environment file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp docker/stack.env stack.env.local
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit the file and set:
|
||||||
- `POSTGRES_PASSWORD` - Strong random password
|
- `POSTGRES_PASSWORD` - Strong random password
|
||||||
- `REDIS_PASSWORD` - Strong random password
|
- `REDIS_PASSWORD` - Strong random password
|
||||||
- `MINIO_ROOT_PASSWORD` - Strong random password
|
- `MINIO_ROOT_PASSWORD` - Strong random password
|
||||||
@@ -44,6 +52,7 @@ Edit `.env.production` and set:
|
|||||||
- `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` - OAuth credentials
|
- `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` - OAuth credentials
|
||||||
- `OPENROUTER_API_KEY` - AI provider key
|
- `OPENROUTER_API_KEY` - AI provider key
|
||||||
- `SMTP_*` - Email configuration
|
- `SMTP_*` - Email configuration
|
||||||
|
- `NEXT_PUBLIC_VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY` - Push notification keys
|
||||||
|
|
||||||
### 2. Build Docker Image
|
### 2. Build Docker Image
|
||||||
|
|
||||||
@@ -59,7 +68,67 @@ Or let Docker Compose build it automatically.
|
|||||||
docker compose -f docker/docker-compose.deploy.yml --env-file .env.production up -d
|
docker compose -f docker/docker-compose.deploy.yml --env-file .env.production up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Verify Deployment
|
## Portainer Deployment
|
||||||
|
|
||||||
|
Portainer provides a web UI for managing Docker containers and deploying stacks easily.
|
||||||
|
|
||||||
|
### Portainer Setup
|
||||||
|
|
||||||
|
1. **Prepare Environment File**
|
||||||
|
|
||||||
|
Copy the stack environment template:
|
||||||
|
```bash
|
||||||
|
cp docker/stack.env stack.env.local
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `stack.env.local` with your production values.
|
||||||
|
|
||||||
|
2. **Access Portainer**
|
||||||
|
|
||||||
|
Open your Portainer instance (typically `https://portainer.your-domain.com`).
|
||||||
|
|
||||||
|
3. **Deploy Stack**
|
||||||
|
|
||||||
|
- Go to **Stacks** → **Add Stack**
|
||||||
|
- Choose **Docker Compose** mode
|
||||||
|
- Select **Upload** to upload the compose file, or use **Editor** to paste the contents of `docker/docker-compose.deploy.yml`
|
||||||
|
- Copy the contents of `docker/stack.env` into the **Environment variables** section
|
||||||
|
- Click **Deploy the stack**
|
||||||
|
|
||||||
|
**Alternative: Using Environment File UI**
|
||||||
|
- In the stack creation form, there's an "Environment file" option
|
||||||
|
- You can paste the entire `stack.env` content there
|
||||||
|
- Portainer will parse and use all variables
|
||||||
|
|
||||||
|
4. **Verify Deployment**
|
||||||
|
|
||||||
|
- Check the **Containers** tab to see all services running
|
||||||
|
- View logs by clicking on each container
|
||||||
|
- Verify the app is accessible at `https://your-domain.com`
|
||||||
|
|
||||||
|
### Portainer Stack Update
|
||||||
|
|
||||||
|
To update the application after code changes:
|
||||||
|
|
||||||
|
1. Build new Docker image locally:
|
||||||
|
```bash
|
||||||
|
docker build -f Dockerfile -t epicure-web:latest .
|
||||||
|
docker push your-registry/epicure-web:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
2. In Portainer:
|
||||||
|
- Go to your stack
|
||||||
|
- Click **Editor**
|
||||||
|
- Update the image reference if needed
|
||||||
|
- Click **Update the stack**
|
||||||
|
|
||||||
|
### Portainer Secrets (Optional)
|
||||||
|
|
||||||
|
For better security, use Portainer Secrets instead of environment variables:
|
||||||
|
|
||||||
|
1. Create a secret in Portainer with sensitive values
|
||||||
|
2. Reference it in the compose file: `${POSTGRES_PASSWORD}`
|
||||||
|
3. Portainer will inject the secret value during deployment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check all services are running
|
# Check all services are running
|
||||||
|
|||||||
+11
-5
@@ -12,17 +12,23 @@ RUN pnpm install --frozen-lockfile --prod
|
|||||||
# Build stage
|
# Build stage
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
RUN apk add --no-cache libc6-compat git postgresql-client
|
RUN apk add --no-cache libc6-compat git postgresql-client
|
||||||
|
|
||||||
|
# Accept build arguments for Next.js environment
|
||||||
|
ARG NEXT_PUBLIC_VAPID_PUBLIC_KEY=dummy_key_for_build
|
||||||
|
ARG BETTER_AUTH_SECRET=dummy_secret_for_build
|
||||||
|
ARG BETTER_AUTH_URL=http://localhost:3000
|
||||||
|
|
||||||
|
# Set environment variables for build
|
||||||
|
ENV NEXT_PUBLIC_VAPID_PUBLIC_KEY=${NEXT_PUBLIC_VAPID_PUBLIC_KEY}
|
||||||
|
ENV BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
|
||||||
|
ENV BETTER_AUTH_URL=${BETTER_AUTH_URL}
|
||||||
|
|
||||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
|
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
|
||||||
RUN pnpm install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
# Copy source code
|
# Copy source code
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Set required build-time environment variables
|
|
||||||
ENV NEXT_PUBLIC_VAPID_PUBLIC_KEY=dummy_key_for_build
|
|
||||||
ENV BETTER_AUTH_SECRET=dummy_secret_for_build
|
|
||||||
ENV BETTER_AUTH_URL=http://localhost:3000
|
|
||||||
|
|
||||||
# Build the app
|
# Build the app
|
||||||
RUN pnpm build 2>&1
|
RUN pnpm build 2>&1
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
NEXT_PUBLIC_VAPID_PUBLIC_KEY: ${NEXT_PUBLIC_VAPID_PUBLIC_KEY}
|
||||||
|
BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}
|
||||||
|
BETTER_AUTH_URL: ${BETTER_AUTH_URL}
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: postgresql://${POSTGRES_USER:-epicure}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-epicure}
|
DATABASE_URL: postgresql://${POSTGRES_USER:-epicure}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-epicure}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# Portainer Stack Environment Variables
|
||||||
|
# Copy this file to stack.env.local and fill in your production values
|
||||||
|
# Portainer will read this file when deploying the stack
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Database Configuration
|
||||||
|
# ============================================
|
||||||
|
POSTGRES_DB=epicure
|
||||||
|
POSTGRES_USER=epicure
|
||||||
|
POSTGRES_PASSWORD=changeme_strong_password_here
|
||||||
|
DB_HOST=postgres
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Redis Configuration
|
||||||
|
# ============================================
|
||||||
|
REDIS_PASSWORD=changeme_strong_password_here
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# MinIO / S3 Storage Configuration
|
||||||
|
# ============================================
|
||||||
|
MINIO_ROOT_USER=minioadmin
|
||||||
|
MINIO_ROOT_PASSWORD=changeme_strong_password_here
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Better Auth Configuration
|
||||||
|
# ============================================
|
||||||
|
BETTER_AUTH_SECRET=changeme_generate_with_openssl_rand_base64_32
|
||||||
|
BETTER_AUTH_URL=https://your-domain.com
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Domain Configuration
|
||||||
|
# ============================================
|
||||||
|
DOMAIN=your-domain.com
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# OAuth Configuration
|
||||||
|
# ============================================
|
||||||
|
GOOGLE_CLIENT_ID=your-google-client-id
|
||||||
|
GOOGLE_CLIENT_SECRET=your-google-client-secret
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# AI Provider Configuration
|
||||||
|
# ============================================
|
||||||
|
OPENROUTER_API_KEY=your-openrouter-api-key
|
||||||
|
OPENROUTER_DEFAULT_MODEL=nvidia/nemotron-3-ultra-550b-a55b:free
|
||||||
|
OPENAI_API_KEY=
|
||||||
|
ANTHROPIC_API_KEY=
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Email / SMTP Configuration
|
||||||
|
# ============================================
|
||||||
|
SMTP_HOST=smtp.eu.mailgun.org
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_SECURE=false
|
||||||
|
SMTP_USER=your-email@example.com
|
||||||
|
SMTP_PASS=your-smtp-password
|
||||||
|
SMTP_FROM=Epicure <noreply@example.com>
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Push Notifications
|
||||||
|
# ============================================
|
||||||
|
NEXT_PUBLIC_VAPID_PUBLIC_KEY=your-vapid-public-key
|
||||||
|
VAPID_PRIVATE_KEY=your-vapid-private-key
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# Node Environment
|
||||||
|
# ============================================
|
||||||
|
NODE_ENV=production
|
||||||
Reference in New Issue
Block a user