Migrate to Env Secret and Add Frontend Dockerfile
This commit is contained in:
@@ -106,19 +106,19 @@ DATABASE_BACKUP_PATH=/data/backups
|
||||
EOF
|
||||
```
|
||||
|
||||
### 5. Create Docker Secret
|
||||
### 5. Generate JWT Secret
|
||||
|
||||
The JWT_SECRET is already included in your `.env` file. The secret is generated automatically when you create the `.env` file:
|
||||
|
||||
```bash
|
||||
# Generate secure JWT secret
|
||||
openssl rand -base64 32 > ~/edh-stats/jwt_secret.txt
|
||||
# Already done in step 4, but if you need to regenerate:
|
||||
openssl rand -base64 32
|
||||
|
||||
# Create Docker secret (one-time setup)
|
||||
docker secret create jwt_secret ~/edh-stats/jwt_secret.txt
|
||||
|
||||
# Verify
|
||||
docker secret ls
|
||||
# Copy the output and update JWT_SECRET in .env
|
||||
```
|
||||
|
||||
Your JWT secret is stored in the `.env` file which is protected by `.gitignore` (not committed to git).
|
||||
|
||||
## Deployment
|
||||
|
||||
### 1. Log in to GHCR
|
||||
@@ -351,9 +351,10 @@ docker update --memory 1G --cpus 1.0 edh-stats-backend-1
|
||||
## Security Best Practices
|
||||
|
||||
1. **Secrets Management**
|
||||
- Never commit secrets to Git
|
||||
- Use Docker secrets for sensitive data
|
||||
- Rotate JWT_SECRET periodically
|
||||
- Never commit `.env` file to Git (already in .gitignore)
|
||||
- Keep `.env` file secure on your server (chmod 600)
|
||||
- Rotate JWT_SECRET periodically by updating .env and restarting services
|
||||
- Backup `.env` file securely (offsite)
|
||||
|
||||
2. **Environment Variables**
|
||||
- Set CORS_ORIGIN to your domain
|
||||
|
||||
@@ -33,11 +33,14 @@ scp docker-compose.prod.deployed.yml user@server:~/edh-stats/
|
||||
ssh user@server
|
||||
cd ~/edh-stats
|
||||
|
||||
# Create secret
|
||||
openssl rand -base64 32 > jwt_secret.txt
|
||||
docker secret create jwt_secret jwt_secret.txt
|
||||
# Create .env file with configuration
|
||||
cat > .env << EOF
|
||||
JWT_SECRET=$(openssl rand -base64 32)
|
||||
CORS_ORIGIN=https://yourdomain.com
|
||||
ALLOW_REGISTRATION=false
|
||||
EOF
|
||||
|
||||
# Start
|
||||
# Start services
|
||||
docker-compose -f docker-compose.prod.deployed.yml up -d
|
||||
```
|
||||
|
||||
@@ -117,40 +120,25 @@ scp frontend/nginx.prod.conf user@your-server.com:~/edh-stats/
|
||||
|
||||
**Create .env File on Server:**
|
||||
```bash
|
||||
cat > ~/.env << EOF
|
||||
# Required
|
||||
cat > .env << EOF
|
||||
# Required - Generate secure JWT secret
|
||||
JWT_SECRET=$(openssl rand -base64 32)
|
||||
|
||||
# Your domain for CORS
|
||||
CORS_ORIGIN=https://yourdomain.com
|
||||
|
||||
# Optional
|
||||
# Optional - Allow user registration (default: false)
|
||||
ALLOW_REGISTRATION=false
|
||||
|
||||
# Optional - Log level in production
|
||||
LOG_LEVEL=warn
|
||||
EOF
|
||||
|
||||
# Keep this file safe! It contains your JWT_SECRET
|
||||
chmod 600 .env
|
||||
```
|
||||
|
||||
### 4. Setup Docker Secrets
|
||||
|
||||
**Generate JWT Secret:**
|
||||
```bash
|
||||
# On server
|
||||
openssl rand -base64 32 > jwt_secret.txt
|
||||
cat jwt_secret.txt
|
||||
# Save this somewhere safe for backups!
|
||||
```
|
||||
|
||||
**Create Docker Secret:**
|
||||
```bash
|
||||
docker secret create jwt_secret jwt_secret.txt
|
||||
|
||||
# Verify
|
||||
docker secret ls
|
||||
docker secret inspect jwt_secret
|
||||
```
|
||||
|
||||
**Cleanup:**
|
||||
```bash
|
||||
# Remove local secret file after import
|
||||
rm jwt_secret.txt
|
||||
```
|
||||
**Note:** The `.env` file is already in `.gitignore` so it won't be committed to git.
|
||||
|
||||
### 5. Start Services
|
||||
|
||||
|
||||
17
deploy.sh
17
deploy.sh
@@ -167,7 +167,7 @@ EOF
|
||||
--file ./frontend/Dockerfile.prod \
|
||||
--tag "${FRONTEND_IMAGE}" \
|
||||
--tag "${FRONTEND_IMAGE_LATEST}" \
|
||||
./
|
||||
./frontend
|
||||
|
||||
print_success "Frontend image built successfully"
|
||||
}
|
||||
@@ -255,6 +255,13 @@ generate_deployment_config() {
|
||||
# Version: ${VERSION}
|
||||
# Generated: $(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
# GitHub User: ${GITHUB_USER}
|
||||
#
|
||||
# IMPORTANT: Create a .env file with these variables:
|
||||
# JWT_SECRET=\$(openssl rand -base64 32)
|
||||
# CORS_ORIGIN=https://yourdomain.com
|
||||
# ALLOW_REGISTRATION=false
|
||||
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
backend:
|
||||
@@ -262,7 +269,7 @@ services:
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- DATABASE_PATH=/app/database/data/edh-stats.db
|
||||
- JWT_SECRET_FILE=/run/secrets/jwt_secret
|
||||
- JWT_SECRET=\${JWT_SECRET}
|
||||
- CORS_ORIGIN=\${CORS_ORIGIN:-https://yourdomain.com}
|
||||
- LOG_LEVEL=warn
|
||||
- RATE_LIMIT_WINDOW=15
|
||||
@@ -271,8 +278,6 @@ services:
|
||||
volumes:
|
||||
- sqlite_data:/app/database/data
|
||||
- app_logs:/app/logs
|
||||
secrets:
|
||||
- jwt_secret
|
||||
restart: unless-stopped
|
||||
deploy:
|
||||
resources:
|
||||
@@ -307,10 +312,6 @@ volumes:
|
||||
app_logs:
|
||||
driver: local
|
||||
|
||||
secrets:
|
||||
jwt_secret:
|
||||
external: true
|
||||
|
||||
networks:
|
||||
edh-stats-network:
|
||||
driver: bridge
|
||||
|
||||
16
frontend/Dockerfile.prod
Normal file
16
frontend/Dockerfile.prod
Normal file
@@ -0,0 +1,16 @@
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy nginx configuration
|
||||
COPY ./nginx.prod.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Copy frontend files
|
||||
COPY ./public /usr/share/nginx/html
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 80 443
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost/health.html || exit 1
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
Reference in New Issue
Block a user