chore: implement semantic versioning with docker image tagging

This commit is contained in:
2026-03-31 16:34:30 -07:00
parent 777d3a93bf
commit 779f9f4e7c
7 changed files with 775 additions and 36 deletions
+4 -1
View File
@@ -7,7 +7,7 @@
services: services:
app: app:
image: euchre-camp/euchre-camp:latest image: dhg.lol:5000/euchre-camp:0.1.0.dev
container_name: euchre-camp container_name: euchre-camp
ports: ports:
- "51193:3000" - "51193:3000"
@@ -27,6 +27,9 @@ services:
# Trusted Origins for Better Auth # Trusted Origins for Better Auth
- TRUSTED_ORIGINS=${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000} - TRUSTED_ORIGINS=${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
# Version tracking
- IMAGE_VERSION=0.1.0.dev
volumes: volumes:
# Persist uploaded files and static content # Persist uploaded files and static content
- /DATA/AppData/euchre-camp/config:/app/public/uploads - /DATA/AppData/euchre-camp/config:/app/public/uploads
+69
View File
@@ -0,0 +1,69 @@
# Development Docker Compose Configuration
# Usage: docker-compose -f docker-compose.dev.yml up -d
services:
app:
build:
context: .
target: builder
args:
GIT_COMMIT: ${GIT_COMMIT:-dev}
container_name: euchre-camp-dev
ports:
- "3000:3000"
environment:
# Database Configuration
- DATABASE_PROVIDER=postgresql
- DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp
- DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow
# Better Auth Configuration
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-dev-secret-change-in-production}
- BETTER_AUTH_URL=${BETTER_AUTH_URL:-http://localhost:3000}
# Application Configuration
- NODE_ENV=development
# Trusted Origins for Better Auth
- TRUSTED_ORIGINS=${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
# Version tracking
- IMAGE_VERSION=0.1.0.dev-dev
volumes:
# Mount source code for hot reload
- .:/app
- /app/node_modules
- /app/.next
depends_on:
- db
restart: unless-stopped
networks:
- euchre-network
db:
image: postgres:15-alpine
container_name: euchre-camp-db-dev
ports:
- "5433:5432" # Different port to avoid conflicts
environment:
- POSTGRES_DB=euchre_camp
- POSTGRES_USER=euchre_camp
- POSTGRES_PASSWORD=password
volumes:
- euchre_camp_db_data_dev:/var/lib/postgresql/data
- ./scripts/init-postgres.sh:/docker-entrypoint-initdb.d/init-postgres.sh
restart: unless-stopped
networks:
- euchre-network
volumes:
euchre_camp_db_data_dev:
driver: local
networks:
euchre-network:
driver: bridge
+19 -28
View File
@@ -1,66 +1,57 @@
# Production Docker Compose Configuration
# Usage: docker-compose up -d
services: services:
app: app:
build: image: dhg.lol:5000/euchre-camp:0.1.0.dev
context: .
target: runner
container_name: euchre-camp-app container_name: euchre-camp-app
ports: ports:
- "3000:3000" - "3000:3000"
environment: environment:
# Database Configuration # Database Configuration
- DATABASE_PROVIDER=postgresql - DATABASE_PROVIDER=postgresql
- DATABASE_URL=postgresql://euchre_camp:euchrepassword@postgresql:5432/euchre_camp - DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp
- DATABASE_SHADOW_URL=postgresql://euchre_camp:euchrepassword@postgresql:5432/euchre_camp_shadow - DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow
# Better Auth Configuration # Better Auth Configuration
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-your-secret-key-change-in-production} - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-change-this-secret-in-production}
- BETTER_AUTH_URL=${BETTER_AUTH_URL:-http://localhost:3000} - BETTER_AUTH_URL=${BETTER_AUTH_URL:-http://localhost:3000}
# Application Configuration # Application Configuration
- NODE_ENV=${NODE_ENV:-production} - NODE_ENV=production
# Trusted Origins for Better Auth # Trusted Origins for Better Auth
- TRUSTED_ORIGINS=${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000} - TRUSTED_ORIGINS=${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
depends_on: # Version tracking
postgresql: - IMAGE_VERSION=0.1.0.dev
condition: service_healthy
volumes: depends_on:
# Persist uploaded files and static content - db
- app_data:/app/public/uploads
restart: unless-stopped restart: unless-stopped
networks: networks:
- euchre-network - euchre-network
postgresql: db:
image: postgres:15-alpine image: postgres:15-alpine
container_name: euchre-camp-postgres container_name: euchre-camp-db
ports:
- "5432:5432"
environment: environment:
- POSTGRES_DB=euchre_camp - POSTGRES_DB=euchre_camp
- POSTGRES_USER=euchre_camp - POSTGRES_USER=euchre_camp
- POSTGRES_PASSWORD=euchrepassword - POSTGRES_PASSWORD=password
ports:
- "5432:5432"
volumes: volumes:
- postgres_data:/var/lib/postgresql/data - euchre_camp_db_data:/var/lib/postgresql/data
- ./scripts/init-postgres.sh:/docker-entrypoint-initdb.d/init-postgres.sh - ./scripts/init-postgres.sh:/docker-entrypoint-initdb.d/init-postgres.sh
healthcheck:
test: ["CMD-SHELL", "pg_isready -U euchre_camp -d euchre_camp"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
restart: unless-stopped restart: unless-stopped
networks: networks:
- euchre-network - euchre-network
volumes: volumes:
postgres_data: euchre_camp_db_data:
driver: local
app_data:
driver: local driver: local
networks: networks:
+8 -1
View File
@@ -18,7 +18,14 @@
"docker:down": "docker-compose down", "docker:down": "docker-compose down",
"docker:logs": "docker-compose logs -f", "docker:logs": "docker-compose logs -f",
"docker:build": "docker-compose build", "docker:build": "docker-compose build",
"docker:shell": "docker exec -it euchre-camp-app sh" "docker:shell": "docker exec -it euchre-camp-app sh",
"version": "node scripts/bump-version.js",
"version:patch": "node scripts/bump-version.js patch",
"version:minor": "node scripts/bump-version.js minor",
"version:major": "node scripts/bump-version.js major",
"docker:build:push": "node scripts/build-and-push-docker.js",
"docker:compose:generate": "node scripts/generate-docker-compose.js",
"release": "npm run version:patch && npm run docker:compose:generate && npm run docker:build:push"
}, },
"dependencies": { "dependencies": {
"@hookform/resolvers": "^5.2.2", "@hookform/resolvers": "^5.2.2",
+176
View File
@@ -0,0 +1,176 @@
#!/usr/bin/env node
/**
* Docker Build and Push Script
*
* Builds Docker images and pushes them to the local registry.
* Tags images based on git state:
* - Tagged commit: versioned tags + latest
* - Untagged commit: .dev suffix + commit hash
*/
const { execSync, spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
// Configuration
const REGISTRY = 'dhg.lol:5000';
const IMAGE_NAME = 'euchre-camp';
const FULL_IMAGE_NAME = `${REGISTRY}/${IMAGE_NAME}`;
// Parse command line arguments
const args = process.argv.slice(2);
const forceVersion = args[0]; // Optional: force a specific version
// Get current version from package.json
function getCurrentVersion() {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
return packageJson.version;
}
// Get git commit hash
function getGitCommitHash(short = true) {
const flag = short ? '--short' : '';
return execSync(`git rev-parse ${flag} HEAD`, { encoding: 'utf8' }).trim();
}
// Get git tag (if any)
function getGitTag() {
try {
const tag = execSync('git describe --tags --exact-match 2>/dev/null', { encoding: 'utf8' }).trim();
return tag;
} catch (error) {
return null;
}
}
// Check if working directory is clean
function isWorkingDirectoryClean() {
try {
const status = execSync('git status --porcelain', { encoding: 'utf8' }).trim();
return status === '';
} catch (error) {
return false;
}
}
// Build Docker image
async function buildDockerImage(tags, gitCommit) {
console.log(`🔨 Building Docker image...\n`);
const buildArgs = [
'build',
'--build-arg', `GIT_COMMIT=${gitCommit}`,
'-t', `${FULL_IMAGE_NAME}:${tags[0]}`, // Primary tag
];
// Add additional tags
tags.forEach(tag => {
buildArgs.push('-t', `${FULL_IMAGE_NAME}:${tag}`);
});
buildArgs.push('.');
console.log(`Build command: docker ${buildArgs.join(' ')}\n`);
return new Promise((resolve, reject) => {
const docker = spawn('docker', buildArgs, {
cwd: path.join(__dirname, '..'),
stdio: 'inherit'
});
docker.on('close', (code) => {
if (code === 0) {
console.log('✅ Docker image built successfully\n');
resolve();
} else {
reject(new Error(`Docker build failed with code ${code}`));
}
});
});
}
// Push Docker image
async function pushDockerImage(tags) {
console.log(`🚀 Pushing Docker images to ${REGISTRY}...\n`);
for (const tag of tags) {
const imageName = `${FULL_IMAGE_NAME}:${tag}`;
console.log(`Pushing ${imageName}...`);
try {
execSync(`docker push ${imageName}`, { stdio: 'inherit' });
console.log(`✅ Pushed ${imageName}\n`);
} catch (error) {
console.error(`❌ Failed to push ${imageName}:`, error.message);
throw error;
}
}
console.log('✅ All images pushed successfully\n');
}
// Main function
async function main() {
console.log('🐳 Docker Build & Push Tool\n');
console.log(`Registry: ${REGISTRY}`);
console.log(`Image: ${IMAGE_NAME}\n`);
// Check if working directory is clean
if (!isWorkingDirectoryClean()) {
console.log('⚠️ Warning: Working directory is not clean');
console.log(' Proceeding anyway...\n');
}
// Determine image tags
const gitCommit = getGitCommitHash();
const gitTag = getGitTag();
const version = forceVersion || getCurrentVersion();
let tags = [];
if (gitTag) {
// Tagged commit - use version and 'latest'
const tagWithoutV = gitTag.startsWith('v') ? gitTag.slice(1) : gitTag;
if (tagWithoutV !== version) {
console.log(`⚠️ Warning: Git tag (${gitTag}) doesn't match package.json version (${version})`);
console.log(' Using package.json version for Docker tags\n');
}
tags = [
version, // e.g., 0.1.0
'latest', // Latest stable
];
} else {
// Untagged commit - use version with .dev suffix and commit hash
tags = [
`${version}.dev`, // e.g., 0.1.0.dev
`${version}-sha-${gitCommit}`, // e.g., 0.1.0-sha-abc123
];
}
console.log(`Git commit: ${gitCommit}`);
console.log(`Git tag: ${gitTag || '(none)'}`);
console.log(`Package version: ${version}`);
console.log(`Docker tags: ${tags.join(', ')}\n`);
// Build the image
await buildDockerImage(tags, gitCommit);
// Push the images
await pushDockerImage(tags);
console.log('🎉 Docker build and push complete!\n');
console.log('Images available at:');
tags.forEach(tag => {
console.log(` - ${FULL_IMAGE_NAME}:${tag}`);
});
}
// Run main function
main().catch(error => {
console.error('❌ Error:', error.message);
process.exit(1);
});
+211
View File
@@ -0,0 +1,211 @@
#!/usr/bin/env node
/**
* Version Bumping Script
*
* Bumps the version based on conventional commits since last release.
* Supports:
* - major: Breaking changes (! or BREAKING CHANGE)
* - minor: Features (feat:)
* - patch: Fixes (fix:) and other changes
*/
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
// Parse command line arguments
const args = process.argv.slice(2);
const forcedVersion = args[0]; // e.g., "0.2.0" or "patch/minor/major"
// Paths
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const changelogPath = path.join(__dirname, '..', 'CHANGELOG.md');
// Load current version from package.json
function getCurrentVersion() {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
return packageJson.version;
}
// Parse version string into components
function parseVersion(version) {
const [major, minor, patch] = version.split('.').map(Number);
return { major, minor, patch };
}
// Format version string
function formatVersion(major, minor, patch) {
return `${major}.${minor}.${patch}`;
}
// Get commits since last tag
function getCommitsSinceLastTag() {
try {
const tags = execSync('git tag --sort=-version:refname', { encoding: 'utf8' }).trim();
const latestTag = tags.split('\n')[0];
if (!latestTag) {
// No tags yet, get all commits
return execSync('git log --oneline --format=%s', { encoding: 'utf8' }).trim().split('\n');
}
const commits = execSync(`git log ${latestTag}..HEAD --oneline --format=%s`, { encoding: 'utf8' }).trim();
return commits ? commits.split('\n') : [];
} catch (error) {
// If no commits since tag or other error, get recent commits
return execSync('git log --oneline --format=%s -n 20', { encoding: 'utf8' }).trim().split('\n');
}
}
// Analyze commits to determine version bump type
function analyzeCommits(commits) {
let bumpType = 'patch'; // default
for (const commit of commits) {
if (!commit) continue;
// Breaking change indicators
if (commit.includes('!') || commit.includes('BREAKING CHANGE')) {
bumpType = 'major';
break; // Major takes precedence
}
// Feature indicators
if (commit.startsWith('feat:') || commit.startsWith('feat(')) {
if (bumpType === 'patch') {
bumpType = 'minor';
}
}
// Fix indicators (already patch by default)
}
return bumpType;
}
// Generate new version based on bump type
function generateNewVersion(currentVersion, bumpType) {
const { major, minor, patch } = parseVersion(currentVersion);
switch (bumpType) {
case 'major':
return formatVersion(major + 1, 0, 0);
case 'minor':
return formatVersion(major, minor + 1, 0);
case 'patch':
default:
return formatVersion(major, minor, patch + 1);
}
}
// Update package.json version
function updatePackageJson(newVersion) {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
packageJson.version = newVersion;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
console.log(`✓ Updated package.json to version ${newVersion}`);
}
// Generate changelog entry
function generateChangelogEntry(newVersion, commits, bumpType) {
const date = new Date().toISOString().split('T')[0];
const relevantCommits = commits.filter(commit => {
if (!commit) return false;
// Filter out non-user-facing commits
if (commit.startsWith('chore:') && !commit.includes('BREAKING')) return false;
return true;
});
const changelogEntry = `## [${newVersion}] - ${date}\n\n` +
`### ${bumpType.charAt(0).toUpperCase() + bumpType.slice(1)} Changes\n\n` +
relevantCommits.map(commit => `- ${commit}`).join('\n') +
'\n\n';
return changelogEntry;
}
// Update CHANGELOG.md
function updateChangelog(newVersion, commits, bumpType) {
const changelogEntry = generateChangelogEntry(newVersion, commits, bumpType);
if (fs.existsSync(changelogPath)) {
const content = fs.readFileSync(changelogPath, 'utf8');
const newContent = changelogEntry + content;
fs.writeFileSync(changelogPath, newContent);
} else {
fs.writeFileSync(changelogPath, `# Changelog\n\n${changelogEntry}`);
}
console.log(`✓ Updated CHANGELOG.md`);
}
// Main function
function main() {
console.log('🔄 Version Bumping Tool\n');
const currentVersion = getCurrentVersion();
console.log(`Current version: ${currentVersion}`);
let newVersion;
let bumpType;
if (forcedVersion) {
// Check if it's a bump type or explicit version
if (['patch', 'minor', 'major'].includes(forcedVersion.toLowerCase())) {
bumpType = forcedVersion.toLowerCase();
newVersion = generateNewVersion(currentVersion, bumpType);
console.log(`Forced bump type: ${bumpType}`);
} else {
// Assume it's an explicit version
newVersion = forcedVersion;
bumpType = 'custom';
console.log(`Forced version: ${newVersion}`);
}
} else {
// Analyze commits to determine bump type
const commits = getCommitsSinceLastTag();
console.log(`\nAnalyzing ${commits.length} commits since last release...`);
bumpType = analyzeCommits(commits);
newVersion = generateNewVersion(currentVersion, bumpType);
console.log(`\nDetected bump type: ${bumpType}`);
console.log(`New version: ${currentVersion}${newVersion}`);
}
// Confirm with user
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(`\nApply version ${newVersion}? (y/N) `, (answer) => {
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
// Update package.json
updatePackageJson(newVersion);
// Update changelog
if (bumpType !== 'custom') {
const commits = getCommitsSinceLastTag();
updateChangelog(newVersion, commits, bumpType);
}
console.log(`\n✅ Version bumped to ${newVersion}`);
console.log(`\nNext steps:`);
console.log(` 1. Review changes: git diff`);
console.log(` 2. Commit changes: git commit -am "chore: bump version to v${newVersion}"`);
console.log(` 3. Create tag: git tag -a v${newVersion} -m "Release v${newVersion}"`);
console.log(` 4. Push changes: git push origin main`);
console.log(` 5. Push tag: git push origin v${newVersion}`);
} else {
console.log('❌ Version bump cancelled');
}
rl.close();
});
}
// Run main function
main();
+282
View File
@@ -0,0 +1,282 @@
#!/usr/bin/env node
/**
* Generate Docker Compose Files with Versioned Images
*
* This script generates docker-compose files with the appropriate image tags
* based on the current version and git state.
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
// Configuration
const REGISTRY = 'dhg.lol:5000';
const IMAGE_NAME = 'euchre-camp';
// Get current version from package.json
function getCurrentVersion() {
const packageJsonPath = path.join(__dirname, '..', 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
return packageJson.version;
}
// Get git tag (if any)
function getGitTag() {
try {
const tag = execSync('git describe --tags --exact-match 2>/dev/null', { encoding: 'utf8' }).trim();
return tag;
} catch (error) {
return null;
}
}
// Get image tag based on git state
function getImageTag() {
const version = getCurrentVersion();
const gitTag = getGitTag();
if (gitTag) {
// Tagged commit - use version tag
return version;
} else {
// Untagged commit - use .dev suffix
return `${version}.dev`;
}
}
// Generate docker-compose.casaos.yml
function generateCasaosYml(imageTag) {
return `# CasaOS Optimized Docker Compose Configuration
# This file is optimized for deployment on CasaOS
# Usage: docker-compose -f docker-compose.casaos.yml up -d
#
# IMPORTANT: This configuration requires an external PostgreSQL database.
# Set DATABASE_URL environment variable to your PostgreSQL connection string.
services:
app:
image: ${REGISTRY}/${IMAGE_NAME}:${imageTag}
container_name: euchre-camp
ports:
- "51193:3000"
environment:
# Database Configuration (REQUIRED: Set via CasaOS environment variables)
- DATABASE_PROVIDER=postgresql
- DATABASE_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp"
- DATABASE_SHADOW_URL="postgresql://euchre_camp:LINGO5row_hiding@dhg.lol:5432/euchre_camp_shadow"
# Better Auth Configuration
- BETTER_AUTH_SECRET=\${BETTER_AUTH_SECRET:-change-this-secret-in-production}
- BETTER_AUTH_URL=\${BETTER_AUTH_URL:-http://localhost:3000}
# Application Configuration
- NODE_ENV=production
# Trusted Origins for Better Auth
- TRUSTED_ORIGINS=\${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
# Version tracking
- IMAGE_VERSION=${imageTag}
volumes:
# Persist uploaded files and static content
- /DATA/AppData/euchre-camp/config:/app/public/uploads
restart: unless-stopped
networks:
- euchre-network
volumes:
euchre_camp_app_data:
driver: local
networks:
euchre-network:
driver: bridge
`;
}
// Generate docker-compose.yml (production with PostgreSQL)
function generateDockerComposeYml(imageTag) {
return `# Production Docker Compose Configuration
# Usage: docker-compose up -d
services:
app:
image: ${REGISTRY}/${IMAGE_NAME}:${imageTag}
container_name: euchre-camp-app
ports:
- "3000:3000"
environment:
# Database Configuration
- DATABASE_PROVIDER=postgresql
- DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp
- DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow
# Better Auth Configuration
- BETTER_AUTH_SECRET=\${BETTER_AUTH_SECRET:-change-this-secret-in-production}
- BETTER_AUTH_URL=\${BETTER_AUTH_URL:-http://localhost:3000}
# Application Configuration
- NODE_ENV=production
# Trusted Origins for Better Auth
- TRUSTED_ORIGINS=\${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
# Version tracking
- IMAGE_VERSION=${imageTag}
depends_on:
- db
restart: unless-stopped
networks:
- euchre-network
db:
image: postgres:15-alpine
container_name: euchre-camp-db
ports:
- "5432:5432"
environment:
- POSTGRES_DB=euchre_camp
- POSTGRES_USER=euchre_camp
- POSTGRES_PASSWORD=password
volumes:
- euchre_camp_db_data:/var/lib/postgresql/data
- ./scripts/init-postgres.sh:/docker-entrypoint-initdb.d/init-postgres.sh
restart: unless-stopped
networks:
- euchre-network
volumes:
euchre_camp_db_data:
driver: local
networks:
euchre-network:
driver: bridge
`;
}
// Generate docker-compose.dev.yml (development with hot reload)
function generateDockerComposeDevYml(imageTag) {
return `# Development Docker Compose Configuration
# Usage: docker-compose -f docker-compose.dev.yml up -d
services:
app:
build:
context: .
target: builder
args:
GIT_COMMIT: \${GIT_COMMIT:-dev}
container_name: euchre-camp-dev
ports:
- "3000:3000"
environment:
# Database Configuration
- DATABASE_PROVIDER=postgresql
- DATABASE_URL=postgresql://euchre_camp:password@db:5432/euchre_camp
- DATABASE_SHADOW_URL=postgresql://euchre_camp:password@db:5432/euchre_camp_shadow
# Better Auth Configuration
- BETTER_AUTH_SECRET=\${BETTER_AUTH_SECRET:-dev-secret-change-in-production}
- BETTER_AUTH_URL=\${BETTER_AUTH_URL:-http://localhost:3000}
# Application Configuration
- NODE_ENV=development
# Trusted Origins for Better Auth
- TRUSTED_ORIGINS=\${TRUSTED_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
# Version tracking
- IMAGE_VERSION=${imageTag}-dev
volumes:
# Mount source code for hot reload
- .:/app
- /app/node_modules
- /app/.next
depends_on:
- db
restart: unless-stopped
networks:
- euchre-network
db:
image: postgres:15-alpine
container_name: euchre-camp-db-dev
ports:
- "5433:5432" # Different port to avoid conflicts
environment:
- POSTGRES_DB=euchre_camp
- POSTGRES_USER=euchre_camp
- POSTGRES_PASSWORD=password
volumes:
- euchre_camp_db_data_dev:/var/lib/postgresql/data
- ./scripts/init-postgres.sh:/docker-entrypoint-initdb.d/init-postgres.sh
restart: unless-stopped
networks:
- euchre-network
volumes:
euchre_camp_db_data_dev:
driver: local
networks:
euchre-network:
driver: bridge
`;
}
// Main function
function main() {
const imageTag = getImageTag();
console.log('🔧 Generating Docker Compose files...\n');
console.log(`Registry: ${REGISTRY}`);
console.log(`Image: ${IMAGE_NAME}`);
console.log(`Tag: ${imageTag}\n`);
// Generate casaos configuration
const casaosContent = generateCasaosYml(imageTag);
fs.writeFileSync(
path.join(__dirname, '..', 'docker-compose.casaos.yml'),
casaosContent
);
console.log('✓ Generated docker-compose.casaos.yml');
// Generate production configuration
const prodContent = generateDockerComposeYml(imageTag);
fs.writeFileSync(
path.join(__dirname, '..', 'docker-compose.yml'),
prodContent
);
console.log('✓ Generated docker-compose.yml');
// Generate development configuration
const devContent = generateDockerComposeDevYml(imageTag);
fs.writeFileSync(
path.join(__dirname, '..', 'docker-compose.dev.yml'),
devContent
);
console.log('✓ Generated docker-compose.dev.yml');
console.log('\n✅ Docker Compose files generated successfully');
console.log('\nNext steps:');
console.log(' 1. Review the generated files');
console.log(' 2. Commit changes to git');
console.log(' 3. Run: docker-compose build');
console.log(' 4. Run: docker-compose push');
}
// Run main function
main();