Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
b05e2a5
chore: update development script to set NODE_ENV for improved environ…
wiktoriavh Nov 4, 2025
48f31b9
feat: add development environment support for configuration management
wiktoriavh Nov 4, 2025
0e09848
feat: add environment configuration files for development and production
wiktoriavh Nov 4, 2025
4e7beee
chore: simplify development script by removing NODE_ENV setting
wiktoriavh Nov 4, 2025
d967a7a
feat: enhance environment loading by adding dynamic file selection an…
wiktoriavh Nov 4, 2025
d9aea1f
feat: add NODE_ENV settings and environment config files for producti…
wiktoriavh Nov 4, 2025
143162f
Merge branch 'main' into feat/use-env-in-dev
wiktoriavh Nov 4, 2025
3502031
refactor: remove unused development environment function and related …
wiktoriavh Nov 4, 2025
3b84703
chore: update docker-compose configuration
wiktoriavh Nov 4, 2025
384c452
chore: update production environment variables for development server
wiktoriavh Nov 4, 2025
fb04483
chore: update .gitignore to include .env.development.example and adju…
wiktoriavh Nov 4, 2025
b911e2a
chore: remove .env.development file
wiktoriavh Nov 4, 2025
8d620ff
chore: add example development environment configuration file
wiktoriavh Nov 4, 2025
85835e3
chore: standardize environment configuration by replacing .env.local …
wiktoriavh Nov 5, 2025
8292591
chore: consolidate environment configuration by removing .env.develop…
wiktoriavh Nov 5, 2025
0dbe7ca
chore: clean up environment configuration by removing commented-out s…
wiktoriavh Nov 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
DISCORD_TOKEN="" # Your bot token
CLIENT_ID="" # Your bot's application ID
# Local Environment Variables (Secrets)
# Copy this file to .env and fill in your actual values
# .env is gitignored and should NEVER be committed

SERVER_ID= # Discord Server ID where the bot will operate
MODERATORS_ROLE_IDS= # Comma separated list of role IDs that are Moderators(Mods, Admins, etc)
# Discord Bot Token & Application ID (REQUIRED)
# Get this from: https://discord.com/developers/applications
DISCORD_TOKEN=your-bot-token-here
CLIENT_ID=your-bot-application-id

REPEL_LOG_CHANNEL_ID= # Channel ID where the bot will log repel actions
REPEL_ROLE_ID= # Role ID assigned to users who can use the repel command
GUIDES_CHANNEL_ID="" # The ID of the channel where guides will be posted
# Override any public config values for local testing

# Discord Server ID (your dev server)
SERVER_ID=your-server-id

# Channel IDs (from your dev server)
GUIDES_CHANNEL_ID=your-guide-channel-id
REPEL_LOG_CHANNEL_ID=your-repel-log-channel-id

# Role IDs (from your dev server)
REPEL_ROLE_ID=your-repel-role-id
MODERATORS_ROLE_IDS=your-moderator-role-id

# Other
GUIDES_TRACKER_PATH=guides-tracker.json
19 changes: 19 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Production Environment Configuration
# Public values - safe to commit to repository
# These are Discord IDs that are publicly visible anyway

# Discord Server ID (your dev server)
SERVER_ID=434487340535382016

# Channel IDs (from your dev server)
GUIDES_CHANNEL_ID=1429492053825290371
REPEL_LOG_CHANNEL_ID=1403558160144531589

# Role IDs (from your dev server)
REPEL_ROLE_ID=1002411741776461844
MODERATORS_ROLE_IDS=849481536654803004

# Other
GUIDES_TRACKER_PATH=/app/data/guides-tracker.json

# Note: DISCORD_TOKEN & CLIENT_ID should be in .env.local (not committed)
12 changes: 5 additions & 7 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,19 @@ jobs:
export NODE_VERSION=$(cat .nvmrc | sed 's/v//')
echo "Using Node version: $NODE_VERSION"

# Create .env.local file with secrets
cat > .env.local << EOF
# Create .env file with secrets
# Public config comes from .env.production (committed to repo)
# NODE_ENV=production is set in docker-compose.yml
cat > .env << EOF
DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }}
CLIENT_ID=${{ secrets.CLIENT_ID }}
GUIDES_CHANNEL_ID=${{ secrets.GUIDES_CHANNEL_ID }}
SERVER_ID=${{ secrets.SERVER_ID }}
REPEL_LOG_CHANNEL_ID=${{ secrets.REPEL_LOG_CHANNEL_ID }}
REPEL_ROLE_ID=${{ secrets.REPEL_ROLE_ID }}
MODERATORS_ROLE_IDS=${{ secrets.MODERATORS_ROLE_IDS }}
EOF

# Stop any existing containers
docker compose down || true

# Build and start production container with profile
# NODE_ENV=production is explicitly set in docker-compose.yml bot-prod service
docker compose --profile prod up -d --build

# Check status
Expand Down
13 changes: 9 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ yarn-debug.log*
yarn-error.log*

# Env files
!.env.example
.env
.env.local
.env.*.local
.env.*

# Public config (committed to repo)
!.env.production
!.env.example

# guides tracker
guides-tracker.json
guides-tracker.json

# Docker
docker-compose.yml
10 changes: 5 additions & 5 deletions DOCKER.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ This document explains how to run the webdev-bot using Docker.

- Docker installed (version 20.10 or higher)
- Docker Compose installed (version 2.0 or higher)
- `.env.local` file with required environment variables
- `.env` file with required environment variables

## Node Version Management

The Docker setup uses `.nvmrc` as the single source of truth for the Node.js version. The Dockerfile automatically reads this version at build time via the `NODE_VERSION` build argument. No need to manually sync versions between `.nvmrc` and Docker files.

## Environment Variables

Before running the bot, create a `.env.local` file in the project root with the following variables:
Before running the bot, create a `.env` file in the project root with the following variables:

```env
DISCORD_TOKEN=your_discord_bot_token
Expand Down Expand Up @@ -104,7 +104,7 @@ Run the production container manually (after building with the NODE_VERSION arg)
```bash
docker run -d \
--name webdev-bot \
--env-file .env.local \
--env-file .env \
--restart unless-stopped \
webdev-bot:latest
```
Expand All @@ -114,7 +114,7 @@ Run the development container manually (after building with the NODE_VERSION arg
```bash
docker run -it \
--name webdev-bot-dev \
--env-file .env.local \
--env-file .env \
-v $(pwd)/src:/app/src:ro \
webdev-bot:dev
```
Expand Down Expand Up @@ -183,7 +183,7 @@ docker compose build --no-cache

## Best Practices

1. **Never commit `.env.local`** - Keep your secrets secure
1. **Never commit `.env`** - Keep your secrets secure
2. **Use production profile for deployment** - Smaller, more secure images
3. **Keep development profile for local testing** - Faster iteration with hot reload
4. **Node version is managed in `.nvmrc`** - Update `.nvmrc` to change Node version for Docker
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package.json ./

# Copy environment config file (public, non-secret)
COPY .env.production ./

# Create data directory and set permissions for node user
RUN mkdir -p /app/data && chown -R node:node /app/data

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ A comprehensive Discord bot designed specifically for the Web Dev Discord server
pnpm install
```

3. Create a `.env.local` file based on `.env.example` and fill in the required environment variables:
3. Create a `.env` file based on `.env.example` and fill in the required environment variables:
```bash
cp .env.example .env.local
# Edit .env.local to add your Discord bot token and other configurations
cp .env.example .env
# Edit .env to add your Discord bot token and other configurations
```

4. Build and start the bot:
Expand Down
12 changes: 8 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ services:
container_name: webdev-bot-prod
restart: unless-stopped
env_file:
- .env.local
- .env
environment:
- GUIDES_TRACKER_PATH=/app/data/guides-tracker.json
- NODE_ENV=production
volumes:
# Mount environment config file
- ./.env.production:/app/.env.production:ro
# Persist guides tracker data
- guides-data:/app/data
profiles:
Expand All @@ -28,9 +30,9 @@ services:
container_name: webdev-bot-dev
restart: unless-stopped
env_file:
- .env.local
- .env
environment:
- GUIDES_TRACKER_PATH=/app/data/guides-tracker.json
- NODE_ENV=development
volumes:
# Mount source code for hot reload
- ./src:/app/src:ro
Expand All @@ -40,6 +42,8 @@ services:
# Mount package files (in case dependencies change)
- ./package.json:/app/package.json:ro
- ./pnpm-lock.yaml:/app/pnpm-lock.yaml:ro
# Mount environment config files
- ./.env.production:/app/.env.production:ro
# Persist guides tracker data
- guides-data:/app/data
profiles:
Expand Down
2 changes: 1 addition & 1 deletion docs/GUIDE_SYNC.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The bot automatically synchronizes guide markdown files from `src/commands/guide

## Setup

Add to your `.env.local` file:
Add to your `.env` file:
```
GUIDES_CHANNEL_ID=1234567890123456789
```
Expand Down
9 changes: 1 addition & 8 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function requireEnv(key: string): string {
const value = process.env[key];
if (!value) {
console.error(`❌ Required environment variable ${key} is not set`);
console.error('Please check your .env.local file or CI/CD configuration');
console.error('Please check your .env file or CI/CD configuration');
process.exit(1);
}
return value;
Expand All @@ -33,13 +33,6 @@ export const config = {
channelId: requireEnv('GUIDES_CHANNEL_ID'),
trackerPath: optionalEnv('GUIDES_TRACKER_PATH'),
},
// Add more config sections as needed:
// database: {
// url: requireEnv('DATABASE_URL'),
// },
// api: {
// openaiKey: optionalEnv('OPENAI_API_KEY'),
// },
};

export type Config = typeof config;
Expand Down
19 changes: 16 additions & 3 deletions src/loadEnvFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { join } from 'node:path';
// Simple .env loader without external dependencies
function loadEnvFile(filePath: string) {
if (!existsSync(filePath)) {
console.warn(`Warning: File ${filePath} not found`);
return;
}

Expand All @@ -24,12 +25,24 @@ function loadEnvFile(filePath: string) {
}
}
}
console.log(`✅ Loaded: ${filePath}`);
} catch (error) {
console.warn(`Warning: Could not load ${filePath}`);
console.warn('Make sure a valid .env.local file exists.');
console.warn(error);
}
}

// Load local environment file if it exists
loadEnvFile(join(process.cwd(), '.env.local'));
// Determine environment (defaults to development)
const nodeEnv = process.env.NODE_ENV || 'development';
console.log(`🌍 Environment: ${nodeEnv}`);

// Load environment-specific config first (public values, production only)
if (nodeEnv === 'production') {
const envFile = join(process.cwd(), '.env.production');
loadEnvFile(envFile);
}

// Load .env file with secrets and local config (overrides public config if any)
// Required for DISCORD_TOKEN and other secrets
const localEnvFile = join(process.cwd(), '.env');
loadEnvFile(localEnvFile);