{
  "manifest_version": "1.0.0",
  "template": {
    "id": "959fe9cb-77f1-478e-b5a1-4ef045a4d4aa",
    "slug": "tFqAVW",
    "name": "Interval",
    "description": "The simplest way to build internal tools without building UIs",
    "url": "https://railway.com/deploy/tFqAVW",
    "upstream": {
      "image": "minio/minio:latest"
    }
  },
  "status": "unvalidated",
  "validated_at": null,
  "success_rate_30d": null,
  "services": [
    {
      "name": "Interval Uploads Storage",
      "source": {
        "image": "minio/minio:latest"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": true
    },
    {
      "name": "Interval Postgres",
      "source": {
        "image": "ghcr.io/railwayapp-templates/postgres-ssl:16"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "tcp_ports": [
        5432
      ],
      "http": false
    },
    {
      "name": "Interval",
      "source": {
        "repo": "https://github.com/ThallesP/interval-on-railway"
      },
      "needs_volume": false,
      "http": true
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for PORT.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MINIO_ROOT_USER",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_ROOT_USER.",
      "secret": false,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "MINIO_PUBLIC_HOST",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_PUBLIC_HOST.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "MINIO_PUBLIC_PORT",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_PUBLIC_PORT.",
      "secret": false,
      "strategy": "default",
      "default": "443"
    },
    {
      "key": "MINIO_PRIVATE_HOST",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_PRIVATE_HOST.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MINIO_PRIVATE_PORT",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_PRIVATE_PORT.",
      "secret": false,
      "strategy": "default",
      "default": "9000"
    },
    {
      "key": "MINIO_ROOT_PASSWORD",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_ROOT_PASSWORD.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "MINIO_PUBLIC_ENDPOINT",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_PUBLIC_ENDPOINT.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MINIO_PRIVATE_ENDPOINT",
      "service": "Interval Uploads Storage",
      "description": "Provide a value for MINIO_PRIVATE_ENDPOINT.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGDATA",
      "service": "Interval Postgres",
      "description": "Location where the database will be initialized",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/postgresql/data/pgdata"
    },
    {
      "key": "PGHOST",
      "service": "Interval Postgres",
      "description": "Railway Private Domain Name.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGPORT",
      "service": "Interval Postgres",
      "description": "Port to connect to Postgres.",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "PGUSER",
      "service": "Interval Postgres",
      "description": "Required variable for Data panel",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGDATABASE",
      "service": "Interval Postgres",
      "description": "Required variable for the data panel.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGPASSWORD",
      "service": "Interval Postgres",
      "description": "Required variable for Data panel",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "POSTGRES_DB",
      "service": "Interval Postgres",
      "description": "Default database created when image is started.",
      "secret": false,
      "strategy": "default",
      "default": "railway"
    },
    {
      "key": "DATABASE_URL",
      "service": "Interval Postgres",
      "description": "URL to connect to Postgres database.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "POSTGRES_USER",
      "service": "Interval Postgres",
      "description": "User to connect to Postgres DB",
      "secret": false,
      "strategy": "default",
      "default": "postgres"
    },
    {
      "key": "SSL_CERT_DAYS",
      "service": "Interval Postgres",
      "description": "SSL certificate expiry in days.",
      "secret": false,
      "strategy": "default",
      "default": "820"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "Interval Postgres",
      "description": "Password to connect to DB",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "DATABASE_PUBLIC_URL",
      "service": "Interval Postgres",
      "description": "Public URL to connect to Postgres database, used by the Data panel.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "SECRET",
      "service": "Interval",
      "description": "A secret that you must provide for use in encrypting passwords. Any string is valid for this value, but you should use something secure!",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "APP_URL",
      "service": "Interval",
      "description": "The URL where your Interval Server instance is running",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "EMAIL_FROM",
      "service": "Interval",
      "description": "From which email will be sent the emails. format: Some Name <some@domain.com>",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "DATABASE_URL",
      "service": "Interval",
      "description": "The Postgres connection string",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "WSS_API_SECRET",
      "service": "Interval",
      "description": "A secret that you must provide. It is used internally by Interval Server for communication between Interval services. Any string is valid for this value, but you should use something secure!",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "POSTMARK_API_KEY",
      "service": "Interval",
      "description": "Used for sending application emails. Create an account at postmarkapp.com",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "AUTH_COOKIE_SECRET",
      "service": "Interval",
      "description": "A secret that you must provide for use in encrypting session cookies. Any string at least 32 characters in length is valid for this value, but you should use something secure!",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "tFqAVW"
      }
    },
    "cli": "railway deploy --template tFqAVW",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "959fe9cb-77f1-478e-b5a1-4ef045a4d4aa",
            "serializedConfig": {
              "services": {
                "0f775f19-180e-40e2-b86c-b02347c76b6b": {
                  "icon": "https://devicons.railway.app/i/minio.svg",
                  "name": "Interval Uploads Storage",
                  "deploy": {
                    "startCommand": "/bin/sh -c \"mkdir -p $RAILWAY_VOLUME_MOUNT_PATH/interval-uploads && minio server --address [::]:$MINIO_PRIVATE_PORT $RAILWAY_VOLUME_MOUNT_PATH\"",
                    "healthcheckPath": "/minio/health/ready"
                  },
                  "source": {
                    "image": "minio/minio:latest"
                  },
                  "variables": {
                    "PORT": {
                      "defaultValue": "${{MINIO_PRIVATE_PORT}}"
                    },
                    "MINIO_ROOT_USER": {
                      "defaultValue": "{{MINIO_ROOT_USER}}"
                    },
                    "MINIO_PUBLIC_HOST": {
                      "defaultValue": "${{RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "MINIO_PUBLIC_PORT": {
                      "defaultValue": "443"
                    },
                    "MINIO_PRIVATE_HOST": {
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "MINIO_PRIVATE_PORT": {
                      "defaultValue": "9000"
                    },
                    "MINIO_ROOT_PASSWORD": {
                      "defaultValue": "{{MINIO_ROOT_PASSWORD}}"
                    },
                    "MINIO_PUBLIC_ENDPOINT": {
                      "defaultValue": "https://${{MINIO_PUBLIC_HOST}}:${{MINIO_PUBLIC_PORT}}"
                    },
                    "MINIO_PRIVATE_ENDPOINT": {
                      "defaultValue": "http://${{MINIO_PRIVATE_HOST}}:${{MINIO_PRIVATE_PORT}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>": {}
                    }
                  },
                  "volumeMounts": {
                    "0f775f19-180e-40e2-b86c-b02347c76b6b": {
                      "mountPath": "/data"
                    }
                  }
                },
                "78e21a5b-a3b2-49c5-831b-673c41eda51c": {
                  "icon": "https://devicons.railway.app/i/postgresql.svg",
                  "name": "Interval Postgres",
                  "build": {},
                  "deploy": {},
                  "source": {
                    "image": "ghcr.io/railwayapp-templates/postgres-ssl:16"
                  },
                  "variables": {
                    "PGDATA": {
                      "isOptional": false,
                      "description": "Location where the database will be initialized",
                      "defaultValue": "/var/lib/postgresql/data/pgdata"
                    },
                    "PGHOST": {
                      "isOptional": false,
                      "description": "Railway Private Domain Name.",
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "PGPORT": {
                      "isOptional": false,
                      "description": "Port to connect to Postgres.",
                      "defaultValue": "5432"
                    },
                    "PGUSER": {
                      "isOptional": false,
                      "description": "Required variable for Data panel",
                      "defaultValue": "${{ POSTGRES_USER }}"
                    },
                    "PGDATABASE": {
                      "isOptional": false,
                      "description": "Required variable for the data panel.",
                      "defaultValue": "${{POSTGRES_DB}}"
                    },
                    "PGPASSWORD": {
                      "isOptional": false,
                      "description": "Required variable for Data panel",
                      "defaultValue": "${{POSTGRES_PASSWORD}}"
                    },
                    "POSTGRES_DB": {
                      "isOptional": false,
                      "description": "Default database created when image is started.",
                      "defaultValue": "railway"
                    },
                    "DATABASE_URL": {
                      "isOptional": false,
                      "description": "URL to connect to Postgres database.",
                      "defaultValue": "postgresql://${{PGUSER}}:${{POSTGRES_PASSWORD}}@${{RAILWAY_PRIVATE_DOMAIN}}:5432/${{PGDATABASE}}"
                    },
                    "POSTGRES_USER": {
                      "isOptional": false,
                      "description": "User to connect to Postgres DB",
                      "defaultValue": "postgres"
                    },
                    "SSL_CERT_DAYS": {
                      "isOptional": true,
                      "description": "SSL certificate expiry in days.",
                      "defaultValue": "820"
                    },
                    "POSTGRES_PASSWORD": {
                      "isOptional": false,
                      "description": "Password to connect to DB",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    },
                    "DATABASE_PUBLIC_URL": {
                      "description": "Public URL to connect to Postgres database, used by the Data panel.",
                      "defaultValue": "postgresql://${{PGUSER}}:${{POSTGRES_PASSWORD}}@${{RAILWAY_TCP_PROXY_DOMAIN}}:${{RAILWAY_TCP_PROXY_PORT}}/${{PGDATABASE}}"
                    }
                  },
                  "networking": {
                    "tcpProxies": {
                      "5432": {}
                    },
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "78e21a5b-a3b2-49c5-831b-673c41eda51c": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  },
                  "haTemplateCode": "postgres-ha",
                  "haConversionConfig": {
                    "edge": {
                      "label": "Reverse Proxy",
                      "options": [
                        2,
                        3,
                        4,
                        5
                      ],
                      "nodeLabel": "HAProxy",
                      "description": "Routes traffic to the primary",
                      "defaultValue": 3
                    },
                    "replica": {
                      "label": "Replicas",
                      "options": [
                        2,
                        3,
                        4,
                        5,
                        6,
                        7
                      ],
                      "nodeLabel": "Postgres",
                      "description": "Streaming replicas for automatic failover",
                      "defaultValue": 2
                    },
                    "internal": {
                      "label": "Coordinator Nodes",
                      "options": [
                        3,
                        5,
                        7,
                        9
                      ],
                      "nodeLabel": "etcd",
                      "defaultValue": 3
                    },
                    "description": "This will convert your Postgres database to an HA cluster with Patroni failover and etcd consensus."
                  }
                },
                "83bfb20f-92df-4b76-b6d2-3ddb17e1d14d": {
                  "name": "Interval",
                  "deploy": {
                    "healthcheckPath": "/health-check/"
                  },
                  "source": {
                    "repo": "ThallesP/interval-on-railway",
                    "branch": null,
                    "rootDirectory": null
                  },
                  "variables": {
                    "SECRET": {
                      "description": "A secret that you must provide for use in encrypting passwords. Any string is valid for this value, but you should use something secure!",
                      "defaultValue": "{{SECRET}}"
                    },
                    "APP_URL": {
                      "description": "The URL where your Interval Server instance is running",
                      "defaultValue": "https://${{RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "EMAIL_FROM": {
                      "isOptional": false,
                      "description": "From which email will be sent the emails. format: Some Name <some@domain.com>",
                      "defaultValue": "{{EMAIL_FROM}}"
                    },
                    "DATABASE_URL": {
                      "description": "The Postgres connection string",
                      "defaultValue": "${{Interval Postgres.DATABASE_URL}}"
                    },
                    "WSS_API_SECRET": {
                      "description": "A secret that you must provide. It is used internally by Interval Server for communication between Interval services. Any string is valid for this value, but you should use something secure!",
                      "defaultValue": "{{WSS_API_SECRET}}"
                    },
                    "POSTMARK_API_KEY": {
                      "isOptional": false,
                      "description": "Used for sending application emails. Create an account at postmarkapp.com",
                      "defaultValue": "{{POSTMARK_API_KEY}}"
                    },
                    "AUTH_COOKIE_SECRET": {
                      "description": "A secret that you must provide for use in encrypting session cookies. Any string at least 32 characters in length is valid for this value, but you should use something secure!",
                      "defaultValue": "{{AUTH_COOKIE_SECRET}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>": {}
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "Interval Uploads Storage",
      "method": "GET",
      "path": "/minio/health/ready",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 3,
    "needs_volume": true
  },
  "generated_at": "2026-09-21T22:14:44.200Z",
  "generator_version": "0.1.0"
}
