How to Generate IaC Templates from Your Docker Files

Last year, I found myself in a frustrating cycle. I'd discover a cool open-source project with a Docker configuration but then spend hours creating Infrastructure as Code templates just to deploy it to my favorite cloud provider. Each time, I translated the same Docker setup, i.e., into CloudFormation for AWS, Blueprints for Render, and App Specs for DigitalOcean. After doing this tedious translation work for the fifth time, I decided there had to be a better way. That's why I built docker-to-iac – to automate the conversion from Docker configurations to deployment-ready IaC templates for various cloud providers in seconds. Solution: Using docker-to-iac The docker-to-iac module converts Docker Compose files or Docker run commands into Infrastructure as Code templates for various cloud providers. Here's how to use it: Setup First, create a new project and install the necessary dependencies: mkdir iac-generator cd iac-generator npm init -y npm install @deploystack/docker-to-iac typescript ts-node Create a tsconfig.json file: { "compilerOptions": { "target": "ES2020", "module": "NodeNext", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true } } Basic Implementation Create a file named generate-template.ts with this code: import { translate } from '@deploystack/docker-to-iac'; import { writeFileSync, mkdirSync, existsSync } from 'fs'; import { join, dirname } from 'path'; // Docker Compose content - replace with your own or read from a file const dockerComposeContent = ` version: '3' services: web: image: nginx:alpine ports: - "80:80" `; // Generate Render.com Blueprint const result = translate(dockerComposeContent, { source: 'compose', target: 'RND', // RND = Render.com }); // Create output directory const outputDir = 'output'; if (!existsSync(outputDir)) { mkdirSync(outputDir, { recursive: true }); } // Write all generated files Object.entries(result.files).forEach(([path, fileData]) => { const fullPath = join(outputDir, path); const dir = dirname(fullPath); if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } writeFileSync(fullPath, fileData.content); console.log(`Created: ${path}`); }); console.log('Done! Check the output directory for your IaC templates.'); Run it with: npx ts-node generate-template.ts This will generate a Render.com Blueprint in the output directory. Practical Example: Web App + Database on Render Let's create a more realistic example with a web app connecting to a database: import { translate } from '@deploystack/docker-to-iac'; import { writeFileSync, mkdirSync, existsSync } from 'fs'; import { join, dirname } from 'path'; // Set DB password for variable interpolation const DB_PASSWORD = 'mySecurePassword123'; // Docker Compose for a web app + database const dockerComposeContent = ` version: '3' services: web: image: node:18-alpine command: npm start ports: - "3000:3000" environment: - NODE_ENV=production - DATABASE_URL=postgres://postgres:\${DB_PASSWORD}@db:5432/app db: image: postgres:14 environment: - POSTGRES_PASSWORD=\${DB_PASSWORD} - POSTGRES_DB=app volumes: - pg_data:/var/lib/postgresql/data volumes: pg_data: `; // Generate Render.com Blueprint with service connections const result = translate(dockerComposeContent, { source: 'compose', target: 'RND', // Handle environment variables environmentVariables: { DB_PASSWORD: DB_PASSWORD }, // Configure service connections serviceConnections: { mappings: [ { fromService: 'web', toService: 'db', environmentVariables: ['DATABASE_URL'], property: 'connectionString' } ] } }); // Create output directory and save files const outputDir = 'output-full'; if (!existsSync(outputDir)) { mkdirSync(outputDir, { recursive: true }); } Object.entries(result.files).forEach(([path, fileData]) => { const fullPath = join(outputDir, path); const dir = dirname(fullPath); if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } writeFileSync(fullPath, fileData.content); console.log(`Created: ${path}`); }); console.log('Done! Check the output-full directory for your IaC templates.'); This code handles: Environment variable substitution Service connections between the web app and database Generating the proper Render.com Blueprint format with correct service types Deployment The generated render.yaml will look something like this: services: - name: web type: web runtime: image image: url: docker.io/library/node:18-alpine startCommand: npm start plan: starter region: oregon envVars: - key: NODE_ENV value: production - key: PORT value: "3000" - key: DATABASE_URL fromData

Apr 22, 2025 - 21:16
 0
How to Generate IaC Templates from Your Docker Files

Last year, I found myself in a frustrating cycle. I'd discover a cool open-source project with a Docker configuration but then spend hours creating Infrastructure as Code templates just to deploy it to my favorite cloud provider. Each time, I translated the same Docker setup, i.e., into CloudFormation for AWS, Blueprints for Render, and App Specs for DigitalOcean.

After doing this tedious translation work for the fifth time, I decided there had to be a better way. That's why I built docker-to-iac – to automate the conversion from Docker configurations to deployment-ready IaC templates for various cloud providers in seconds.

Solution: Using docker-to-iac

The docker-to-iac module converts Docker Compose files or Docker run commands into Infrastructure as Code templates for various cloud providers. Here's how to use it:

Setup

First, create a new project and install the necessary dependencies:

mkdir iac-generator
cd iac-generator
npm init -y
npm install @deploystack/docker-to-iac typescript ts-node

Create a tsconfig.json file:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

Basic Implementation

Create a file named generate-template.ts with this code:

import { translate } from '@deploystack/docker-to-iac';
import { writeFileSync, mkdirSync, existsSync } from 'fs';
import { join, dirname } from 'path';

// Docker Compose content - replace with your own or read from a file
const dockerComposeContent = `
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
`;

// Generate Render.com Blueprint
const result = translate(dockerComposeContent, {
  source: 'compose',
  target: 'RND',     // RND = Render.com
});

// Create output directory
const outputDir = 'output';
if (!existsSync(outputDir)) {
  mkdirSync(outputDir, { recursive: true });
}

// Write all generated files
Object.entries(result.files).forEach(([path, fileData]) => {
  const fullPath = join(outputDir, path);
  const dir = dirname(fullPath);

  if (!existsSync(dir)) {
    mkdirSync(dir, { recursive: true });
  }

  writeFileSync(fullPath, fileData.content);
  console.log(`Created: ${path}`);
});

console.log('Done! Check the output directory for your IaC templates.');

Run it with:

npx ts-node generate-template.ts

This will generate a Render.com Blueprint in the output directory.

Practical Example: Web App + Database on Render

Let's create a more realistic example with a web app connecting to a database:

import { translate } from '@deploystack/docker-to-iac';
import { writeFileSync, mkdirSync, existsSync } from 'fs';
import { join, dirname } from 'path';

// Set DB password for variable interpolation
const DB_PASSWORD = 'mySecurePassword123';

// Docker Compose for a web app + database
const dockerComposeContent = `
version: '3'
services:
  web:
    image: node:18-alpine
    command: npm start
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://postgres:\${DB_PASSWORD}@db:5432/app

  db:
    image: postgres:14
    environment:
      - POSTGRES_PASSWORD=\${DB_PASSWORD}
      - POSTGRES_DB=app
    volumes:
      - pg_data:/var/lib/postgresql/data

volumes:
  pg_data:
`;

// Generate Render.com Blueprint with service connections
const result = translate(dockerComposeContent, {
  source: 'compose',
  target: 'RND',
  // Handle environment variables
  environmentVariables: {
    DB_PASSWORD: DB_PASSWORD
  },
  // Configure service connections
  serviceConnections: {
    mappings: [
      {
        fromService: 'web',
        toService: 'db',
        environmentVariables: ['DATABASE_URL'],
        property: 'connectionString'
      }
    ]
  }
});

// Create output directory and save files
const outputDir = 'output-full';
if (!existsSync(outputDir)) {
  mkdirSync(outputDir, { recursive: true });
}

Object.entries(result.files).forEach(([path, fileData]) => {
  const fullPath = join(outputDir, path);
  const dir = dirname(fullPath);

  if (!existsSync(dir)) {
    mkdirSync(dir, { recursive: true });
  }

  writeFileSync(fullPath, fileData.content);
  console.log(`Created: ${path}`);
});

console.log('Done! Check the output-full directory for your IaC templates.');

This code handles:

  • Environment variable substitution
  • Service connections between the web app and database
  • Generating the proper Render.com Blueprint format with correct service types

Deployment

The generated render.yaml will look something like this:

services:
  - name: web
    type: web
    runtime: image
    image:
      url: docker.io/library/node:18-alpine
    startCommand: npm start
    plan: starter
    region: oregon
    envVars:
      - key: NODE_ENV
        value: production
      - key: PORT
        value: "3000"
      - key: DATABASE_URL
        fromDatabase:
          name: db-db
          property: connectionString
databases:
  - name: db-db
    plan: free

To deploy this Blueprint on Render:

  1. Push the render.yaml file to a GitHub repository
  2. Log in to your Render account
  3. Click "New Blueprint" and select your repository
  4. Review settings and click "Apply Blueprint"

Render will automatically set up both services with the correct configuration and connections between them!

Even Easier: DeployStack.io

Don't want to write any code? DeployStack.io does all this for you:

  1. Submit your GitHub repository with Docker configurations at deploystack.io/submit
  2. DeployStack generates templates for multiple cloud providers
  3. Add generated deployment buttons to your README
  4. Users can deploy your app with a single click

All generated templates are stored in the deploy-templates repository and available under an open-source license.

Conclusion

The docker-to-iac module eliminates hours of manual work translating Docker configurations to IaC templates. Whether you integrate it into your workflow or use DeployStack.io directly, you can provide easy deployment experiences across cloud providers with minimal effort.

Give it a try and let your Docker configurations do the heavy lifting!