Builds
This guide walks you through setting up CI/CD and containerization for your legacy application. Rather than repeating all the technical details, it focuses on the decisions you need to make and points you to the appropriate reference documentation.
What You'll Learn
- How to assess your current build state and choose a path forward
- What's required vs. optional for platform deployment
- How to adapt existing CI/CD pipelines
- Common migration pitfalls and how to avoid them
Requirements
CI/CD automation is not required to deploy your application. If your container images are already being built and published elsewhere, you can manually update the .platform folder and skip this section initially. However, setting up CI/CD provides automated deployments and a streamlined workflow.
By the end of this section, your repository will have:
- A
Dockerfilethat builds your application - GitHub Actions workflows for build, tag cutting, and promotion
- Registry credentials configured as repository secrets
- Container images publishing to your registry (Artifactory, Azure Container Registry, etc.)
Assess Your Starting Point
Your path through this guide depends on your current state:
| Current State | What You Need |
|---|---|
| No Dockerfile, no CI | Create Dockerfile + set up workflows |
| Has Dockerfile, no CI | Set up GitHub Actions workflows |
| Has Dockerfile + CI (not GitHub Actions) | Adapt existing CI or migrate to GitHub Actions |
| Has Dockerfile + GitHub Actions | Adapt workflows to use p6m-actions |
Read the sections below that apply to your situation.
If You Don't Have a Dockerfile
If your application isn't containerized yet, you'll need to create a Dockerfile. The platform supports any valid Docker image, but following platform patterns ensures compatibility.
Key Requirements
Your Dockerfile must:
- Build a runnable image — Include all runtime dependencies
- Expose the correct port — Match what your application listens on
- Use exec form for CMD — So SIGTERM reaches your process for graceful shutdown
Recommended (but not required initially):
- Multi-stage builds for smaller images
- Non-root user for security
- Pinned base image versions
Where to Start
The Containerization reference provides:
- Multi-stage Dockerfile patterns
- Security best practices (non-root users, minimal base images)
- Language-specific Dockerfiles for Python, Java, .NET, Rust, JavaScript
- Layer caching strategies
- Registry publishing patterns
For language-specific examples, see the Language Reference.
Before setting up CI/CD, verify your Dockerfile works locally:
docker build -t my-app:test .
docker run -p 8080:8080 my-app:test
curl http://localhost:8080/health
If You Don't Have CI/CD
If your repository doesn't have automated builds, you'll set up GitHub Actions workflows following the platform's three-workflow pattern.
The Three-Workflow Pattern
The platform uses three workflows that work together:
| Workflow | Trigger | Purpose |
|---|---|---|
| Build | Push/PR to main | Build, test, publish images, deploy to dev |
| Cut Tag | Manual | Create minor/major releases |
| Promote | Manual | Deploy releases to staging/production |
The Builds Overview explains this pattern in detail.
Setting Up Workflows
The CI/CD Overview provides complete workflow examples you can copy and adapt. It covers:
- Pipeline stages (setup → login → build → publish → deploy)
- Language-specific actions for each stage
- Complete workflow files with tabs for snippet vs. full versions
For your specific language, see:
Contact your platform team for base workflow templates. For new solutions, Ybor Automation typically sets up the initial CI/CD configuration for you.
Configuring Repository Secrets
For new solutions, Ybor Automation typically configures these secrets automatically. Check your repository settings before adding them manually.
If using Artifactory as your registry, configure these in your GitHub repository settings (Settings → Secrets and variables → Actions):
Secrets (for Artifactory):
ARTIFACTORY_USERNAMEARTIFACTORY_IDENTITY_TOKENUPDATE_MANIFEST_TOKEN
Variables (for Artifactory):
ARTIFACTORY_HOSTNAMEARTIFACTORY_PROJECTPLATFORM_DISPATCH_URL
If using a different registry (Azure Container Registry, ECR, etc.), configure the appropriate credentials for that registry instead.
See CI/CD Overview — Required Secrets and Variables for descriptions of each.
These may already be configured at the organization level. Check with your platform team before adding them to individual repositories.
If You Have Existing CI/CD
If you already have CI/CD (Jenkins, GitLab CI, CircleCI, Azure DevOps, or GitHub Actions with custom workflows), you have options.
Option 1: Migrate to Platform Workflows (Recommended)
Replace your existing CI/CD with platform-standard GitHub Actions. This gives you:
- Full integration with platform tooling
- Access to p6m-actions for language-specific tasks
- Automatic dev deployment on merge
- Standard promotion workflows
Migration steps:
- Copy workflow templates from CI/CD Overview
- Adapt for your language using the Language Reference
- Configure repository secrets (see above)
- Test on a feature branch before removing old CI/CD
- Remove or disable old CI/CD configuration
Option 2: Adapt Existing CI/CD
If full migration isn't feasible (complex custom logic, organizational constraints), your existing CI/CD can work with the platform if it:
- Builds and pushes Docker images to your Artifactory registry
- Uses semantic versioning for image tags
- Outputs the image digest for deployment tracking
- Triggers platform manifest updates for deployment
The critical integration point is step 4. You'll need to call the platform dispatch API to trigger deployments. See Platform Dispatch Action for the API details, or contact your platform team.
Option 3: Hybrid Approach
Keep your existing build/test logic but add platform workflows for deployment:
- Keep existing CI for build and test
- Have it push images to Artifactory with proper tags
- Add platform
promote.ymlworkflow that references your images - Use the promote workflow for staging/production deployments
This works well when:
- Your build logic is complex and well-tested
- You want to minimize changes to working pipelines
- You're migrating incrementally
Testing Your Pipeline
After setting up workflows, verify everything works:
Pre-Flight Checklist
- Secrets and variables are configured in repository settings
- Dockerfile builds successfully locally
- You have push access to the repository
Verification Steps
- Create a feature branch and push — This triggers the build workflow on PR
- Check the Actions tab — Verify all steps pass (setup, build, test, docker build)
- Review any failures — Authentication issues are most common initially
- Merge to main — This should:
- Build and push the image to Artifactory
- Auto-cut a patch version
- Dispatch a dev deployment
- Verify in Artifactory — Check that your image appears in the registry
- Check the
.platformrepository — A manifest update should appear
Migration-Specific Troubleshooting
These issues are common when migrating existing applications.
Authentication Failures
Symptom: Build fails immediately with 401/403 errors.
Common causes:
- Secrets not configured or misspelled
- Token expired or revoked
- Service account lacks push permissions
Resolution:
- Verify secret names match exactly (case-sensitive)
- Test credentials locally if possible
- Request new tokens from your platform team
Docker Build Fails in CI but Works Locally
Symptom: docker build succeeds on your machine but fails in GitHub Actions.
Common causes:
- Files excluded by
.dockerignorethat are needed - Dependencies on local environment (env vars, mounted volumes)
- Base image not accessible from GitHub runners
- Architecture mismatch (building on M1 Mac, running on amd64)
Resolution:
- Review
.dockerignorefor accidentally excluded files - Ensure all dependencies are explicitly declared
- Use multi-arch builds or specify
--platform linux/amd64
Existing Tests Fail in New Environment
Symptom: Tests that pass locally or in old CI fail in GitHub Actions.
Common causes:
- Different runtime versions
- Missing test dependencies or fixtures
- Environment variable differences
- Database/service dependencies not available
Resolution:
- Pin runtime versions explicitly in workflow
- Ensure test fixtures are committed or fetched
- Use GitHub Actions services for databases if needed
- Review environment variable requirements
Manifest Dispatch Fails
Symptom: Build succeeds but deployment doesn't trigger.
Common causes:
UPDATE_MANIFEST_TOKENnot set or lacks permissionsPLATFORM_DISPATCH_URLincorrect.platformrepository not set up for your application
Resolution:
- Verify token has dispatch permissions
- Confirm dispatch URL with platform team
- Ensure your app is registered in the platform repository
Version Conflicts
Symptom: Version bumping fails or creates unexpected versions.
Common causes:
- Version file format doesn't match expected pattern
- Git history issues preventing tag creation
- Existing tags conflicting with new versions
Resolution:
- Verify version file matches language expectations (package.json, pyproject.toml, etc.)
- Ensure workflow has
fetch-depth: 0for full git history - Check for and resolve any existing conflicting tags
Next Steps
Once your build pipeline is working:
- Proceed to Deployments to create PlatformApplication manifests
- After deployment is verified, add Observability incrementally
Related Documentation
- Builds Overview — Complete builds reference and build model explanation
- CI/CD Overview — Detailed workflow architecture and examples
- Containerization — Dockerfile patterns and best practices
- Versioning — Semantic versioning and tag cutting
- Promotion — Environment promotion workflows
- Language Reference — Language-specific actions and Dockerfiles