-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add one-click deployment buttons for 12+ cloud providers #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add one-click deployment buttons for 12+ cloud providers #41
Conversation
Add deployment templates and referral links for multiple cloud providers: PaaS: - Railway (with referral code) - Render - Heroku - DigitalOcean App Platform - Koyeb - Zeabur - Northflank - Fly.io Enterprise Cloud: - Google Cloud Run - Azure Container Apps Self-Hosted: - CapRover - Coolify Changes: - Add deploy/ directory with provider-specific templates - Add "Deploy Your Own Instance" section to README with deploy buttons - Add matrix-based template validation in CI - Add Fly.io deployment sync job (requires FLY_API_TOKEN secret)
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds one-click deployment support for 12+ cloud providers, but contains critical configuration bugs that will prevent all deployments from working. The main issue is that all deployment templates use incorrect environment variable names with a PARSE_DMARC_ prefix (e.g., PARSE_DMARC_IMAP_HOST), but the application expects variables without this prefix (e.g., IMAP_HOST), as defined in internal/config/config.go. Additional issues include incorrect GitHub Actions syntax, missing persistent storage configuration for Azure and Google Cloud, and Fly.io TOML syntax errors.
Key Issues:
- Critical: All 9 deployment templates use wrong environment variable names (
PARSE_DMARC_*instead of unprefixed names) - Critical: Azure Container Apps and Google Cloud Run templates lack persistent volume configuration, causing data loss on restarts
- Critical: GitHub Actions workflow has incorrect conditional syntax for checking secrets
- Moderate: Fly.io template has incorrect TOML syntax for mounts and VM configuration
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 26 comments.
Show a summary per file
| File | Description |
|---|---|
deploy/zeabur.json |
Zeabur template with incorrect env var names |
deploy/render.yaml |
Render blueprint with incorrect env var names |
deploy/railway.json |
Railway template with incorrect env var names and unnecessary startCommand |
deploy/northflank.json |
Northflank template (env vars configured via UI) |
deploy/koyeb.yaml |
Koyeb config with incorrect env var names |
deploy/heroku.yml |
Heroku container config with incorrect startCommand |
deploy/fly.toml |
Fly.io config with incorrect env var names and TOML syntax errors |
deploy/digitalocean-app.yaml |
DigitalOcean App Platform spec with incorrect env var names |
deploy/coolify.yaml |
Coolify docker-compose with incorrect env var names |
deploy/cloudbuild.yaml |
Google Cloud Build config with incorrect env var names and missing volumes |
deploy/captain-definition |
CapRover definition (minimal, correct) |
deploy/azure-container-apps.bicep |
Azure Bicep template with incorrect env var names, missing volumes, and outdated API version |
deploy/app.json |
Heroku app manifest with incorrect env var names |
deploy/README.md |
Deployment documentation with incorrect env var names |
README.md |
Main readme with deployment buttons and potentially incorrect template URLs |
.github/workflows/ci.yml |
CI workflow with template validation and incorrect conditional syntax |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| resource environment 'Microsoft.App/managedEnvironments@2023-05-01' = { | ||
| name: environmentName | ||
| location: location | ||
| properties: { | ||
| zoneRedundant: false | ||
| } | ||
| } | ||
|
|
||
| resource containerApp 'Microsoft.App/containerApps@2023-05-01' = { |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API version 2023-05-01 is outdated. As of December 2025, newer stable API versions are available (e.g., 2024-03-01 or later). Consider updating to a more recent API version to access newer features and improvements. You can check the latest stable versions at: https://learn.microsoft.com/en-us/azure/templates/microsoft.app/containerapps
The same API version is used on line 33 for the containerApp resource.
| | **Coolify** | [](https://github.com/meysam81/parse-dmarc) | Open-source Heroku alternative | | ||
| | **Docker** | [](https://github.com/meysam81/parse-dmarc/pkgs/container/parse-dmarc) | Run anywhere | | ||
|
|
||
| > **Note**: All deployments require IMAP credentials. See [Configuration](#configuration-options) for details on setting up Gmail, Outlook, or other email providers. |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The note references [Configuration](#configuration-options) for setting up IMAP credentials, but the Configuration Options section (line 163) only shows JSON configuration file examples, not environment variables. Since all the deployment buttons use environment variables (not config files), consider adding documentation for environment variable configuration or updating the link to point to the deploy/README.md which has the environment variable reference table.
| > **Note**: All deployments require IMAP credentials. See [Configuration](#configuration-options) for details on setting up Gmail, Outlook, or other email providers. | |
| > **Note**: All deployments require IMAP credentials. See [Environment Variables](./deploy/README.md#environment-variables) for details on setting up Gmail, Outlook, or other email providers. |
| "PARSE_DMARC_DATABASE_PATH": { | ||
| "default": "/data/db.sqlite", | ||
| "expose": true | ||
| }, | ||
| "PARSE_DMARC_IMAP_HOST": { | ||
| "default": "", | ||
| "expose": true, | ||
| "required": true | ||
| }, | ||
| "PARSE_DMARC_IMAP_MAILBOX": { | ||
| "default": "INBOX", | ||
| "expose": true | ||
| }, | ||
| "PARSE_DMARC_IMAP_PASSWORD": { | ||
| "default": "", | ||
| "expose": true, | ||
| "required": true | ||
| }, | ||
| "PARSE_DMARC_IMAP_PORT": { | ||
| "default": "993", | ||
| "expose": true | ||
| }, | ||
| "PARSE_DMARC_IMAP_USERNAME": { | ||
| "default": "", | ||
| "expose": true, | ||
| "required": true | ||
| }, | ||
| "PARSE_DMARC_IMAP_USE_TLS": { | ||
| "default": "true", | ||
| "expose": true | ||
| }, | ||
| "PARSE_DMARC_SERVER_HOST": { | ||
| "default": "0.0.0.0", | ||
| "expose": true | ||
| }, | ||
| "PARSE_DMARC_SERVER_PORT": { |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Environment variable names are incorrect. The application expects environment variables WITHOUT the PARSE_DMARC_ prefix (e.g., IMAP_HOST, IMAP_PORT, DATABASE_PATH, SERVER_HOST, SERVER_PORT), as defined in internal/config/config.go. All variables in this template have the wrong prefix:
PARSE_DMARC_DATABASE_PATHshould beDATABASE_PATHPARSE_DMARC_IMAP_HOSTshould beIMAP_HOSTPARSE_DMARC_IMAP_MAILBOXshould beIMAP_MAILBOXPARSE_DMARC_IMAP_PASSWORDshould beIMAP_PASSWORDPARSE_DMARC_IMAP_PORTshould beIMAP_PORTPARSE_DMARC_IMAP_USERNAMEshould beIMAP_USERNAMEPARSE_DMARC_IMAP_USE_TLSshould beIMAP_USE_TLSPARSE_DMARC_SERVER_HOSTshould beSERVER_HOSTPARSE_DMARC_SERVER_PORTshould beSERVER_PORT
Without this fix, the deployment will not work as the application won't be able to read the configuration.
| "PARSE_DMARC_DATABASE_PATH": { | |
| "default": "/data/db.sqlite", | |
| "expose": true | |
| }, | |
| "PARSE_DMARC_IMAP_HOST": { | |
| "default": "", | |
| "expose": true, | |
| "required": true | |
| }, | |
| "PARSE_DMARC_IMAP_MAILBOX": { | |
| "default": "INBOX", | |
| "expose": true | |
| }, | |
| "PARSE_DMARC_IMAP_PASSWORD": { | |
| "default": "", | |
| "expose": true, | |
| "required": true | |
| }, | |
| "PARSE_DMARC_IMAP_PORT": { | |
| "default": "993", | |
| "expose": true | |
| }, | |
| "PARSE_DMARC_IMAP_USERNAME": { | |
| "default": "", | |
| "expose": true, | |
| "required": true | |
| }, | |
| "PARSE_DMARC_IMAP_USE_TLS": { | |
| "default": "true", | |
| "expose": true | |
| }, | |
| "PARSE_DMARC_SERVER_HOST": { | |
| "default": "0.0.0.0", | |
| "expose": true | |
| }, | |
| "PARSE_DMARC_SERVER_PORT": { | |
| "DATABASE_PATH": { | |
| "default": "/data/db.sqlite", | |
| "expose": true | |
| }, | |
| "IMAP_HOST": { | |
| "default": "", | |
| "expose": true, | |
| "required": true | |
| }, | |
| "IMAP_MAILBOX": { | |
| "default": "INBOX", | |
| "expose": true | |
| }, | |
| "IMAP_PASSWORD": { | |
| "default": "", | |
| "expose": true, | |
| "required": true | |
| }, | |
| "IMAP_PORT": { | |
| "default": "993", | |
| "expose": true | |
| }, | |
| "IMAP_USERNAME": { | |
| "default": "", | |
| "expose": true, | |
| "required": true | |
| }, | |
| "IMAP_USE_TLS": { | |
| "default": "true", | |
| "expose": true | |
| }, | |
| "SERVER_HOST": { | |
| "default": "0.0.0.0", | |
| "expose": true | |
| }, | |
| "SERVER_PORT": { |
| - key: PARSE_DMARC_IMAP_HOST | ||
| scope: RUN_TIME | ||
| type: SECRET | ||
| - key: PARSE_DMARC_IMAP_PORT | ||
| scope: RUN_TIME | ||
| value: "993" | ||
| - key: PARSE_DMARC_IMAP_USERNAME | ||
| scope: RUN_TIME | ||
| type: SECRET | ||
| - key: PARSE_DMARC_IMAP_PASSWORD | ||
| scope: RUN_TIME | ||
| type: SECRET | ||
| - key: PARSE_DMARC_IMAP_MAILBOX | ||
| scope: RUN_TIME | ||
| value: "INBOX" | ||
| - key: PARSE_DMARC_IMAP_USE_TLS | ||
| scope: RUN_TIME | ||
| value: "true" | ||
| - key: PARSE_DMARC_DATABASE_PATH | ||
| scope: RUN_TIME | ||
| value: "/data/db.sqlite" | ||
| - key: PARSE_DMARC_SERVER_PORT | ||
| scope: RUN_TIME | ||
| value: "8080" | ||
| - key: PARSE_DMARC_SERVER_HOST |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Environment variable names are incorrect. The application expects environment variables WITHOUT the PARSE_DMARC_ prefix (e.g., IMAP_HOST, IMAP_PORT, DATABASE_PATH, SERVER_HOST, SERVER_PORT), as defined in internal/config/config.go. All variables should be renamed:
PARSE_DMARC_IMAP_HOST→IMAP_HOSTPARSE_DMARC_IMAP_PORT→IMAP_PORTPARSE_DMARC_IMAP_USERNAME→IMAP_USERNAMEPARSE_DMARC_IMAP_PASSWORD→IMAP_PASSWORDPARSE_DMARC_IMAP_MAILBOX→IMAP_MAILBOXPARSE_DMARC_IMAP_USE_TLS→IMAP_USE_TLSPARSE_DMARC_DATABASE_PATH→DATABASE_PATHPARSE_DMARC_SERVER_PORT→SERVER_PORTPARSE_DMARC_SERVER_HOST→SERVER_HOST
Without this fix, the deployment will not work as the application won't be able to read the configuration.
| - key: PARSE_DMARC_IMAP_HOST | |
| scope: RUN_TIME | |
| type: SECRET | |
| - key: PARSE_DMARC_IMAP_PORT | |
| scope: RUN_TIME | |
| value: "993" | |
| - key: PARSE_DMARC_IMAP_USERNAME | |
| scope: RUN_TIME | |
| type: SECRET | |
| - key: PARSE_DMARC_IMAP_PASSWORD | |
| scope: RUN_TIME | |
| type: SECRET | |
| - key: PARSE_DMARC_IMAP_MAILBOX | |
| scope: RUN_TIME | |
| value: "INBOX" | |
| - key: PARSE_DMARC_IMAP_USE_TLS | |
| scope: RUN_TIME | |
| value: "true" | |
| - key: PARSE_DMARC_DATABASE_PATH | |
| scope: RUN_TIME | |
| value: "/data/db.sqlite" | |
| - key: PARSE_DMARC_SERVER_PORT | |
| scope: RUN_TIME | |
| value: "8080" | |
| - key: PARSE_DMARC_SERVER_HOST | |
| - key: IMAP_HOST | |
| scope: RUN_TIME | |
| type: SECRET | |
| - key: IMAP_PORT | |
| scope: RUN_TIME | |
| value: "993" | |
| - key: IMAP_USERNAME | |
| scope: RUN_TIME | |
| type: SECRET | |
| - key: IMAP_PASSWORD | |
| scope: RUN_TIME | |
| type: SECRET | |
| - key: IMAP_MAILBOX | |
| scope: RUN_TIME | |
| value: "INBOX" | |
| - key: IMAP_USE_TLS | |
| scope: RUN_TIME | |
| value: "true" | |
| - key: DATABASE_PATH | |
| scope: RUN_TIME | |
| value: "/data/db.sqlite" | |
| - key: SERVER_PORT | |
| scope: RUN_TIME | |
| value: "8080" | |
| - key: SERVER_HOST |
| docker: | ||
| web: Dockerfile | ||
| run: | ||
| web: /app/parse-dmarc --config=/app/config.json |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The run command specifies --config=/app/config.json, but Heroku deployments using app.json rely on environment variables, not mounted config files. Since the config file won't exist in the container, this command will likely fail.
The Dockerfile's default CMD already includes --config=/app/config.json, and the application will fall back to environment variables when the config file doesn't exist (as seen in internal/config/config.go). Consider removing this line to use the Dockerfile's default ENTRYPOINT and CMD.
| web: /app/parse-dmarc --config=/app/config.json | |
| web: /app/parse-dmarc |
| source = "parse_dmarc_data" | ||
| destination = "/data" | ||
|
|
||
| [[vm]] |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The [[vm]] section uses deprecated syntax. According to Fly.io's current documentation, VM configuration should be specified using [vm] (single brackets) for a single machine, not [[vm]] (double brackets). The configuration should be:
[vm]
size = "shared-cpu-1x"
memory = "256mb"Note: The size and memory fields might also be outdated - Fly.io now uses machine presets like shared-cpu-1x which includes both CPU and memory specifications.
| [[vm]] | |
| [vm] |
| containers: [ | ||
| { | ||
| name: 'parse-dmarc' | ||
| image: 'ghcr.io/meysam81/parse-dmarc:latest' |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using a floating image tag ghcr.io/meysam81/parse-dmarc:latest allows silent supply‑chain compromise: if the upstream image is replaced, future revisions of this template will pull unverified code and run it. Pin the image to an immutable digest or a specific signed version tag (e.g., ghcr.io/meysam81/parse-dmarc:v1.1.0@sha256:<digest>).
| image: 'ghcr.io/meysam81/parse-dmarc:latest' | |
| image: 'ghcr.io/meysam81/parse-dmarc:v1.1.0@sha256:<digest>' |
| -e PARSE_DMARC_IMAP_USERNAME=your-email@gmail.com \ | ||
| -e PARSE_DMARC_IMAP_PASSWORD=your-app-password \ | ||
| -v parse-dmarc-data:/data \ | ||
| ghcr.io/meysam81/parse-dmarc:latest |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Floating image tag ghcr.io/meysam81/parse-dmarc:latest in this Docker run example enables pulling a modified image later without review, leading to potential arbitrary code execution. Use a fixed version tag or digest (e.g., ghcr.io/meysam81/parse-dmarc:v1.1.0@sha256:<digest>) to ensure image integrity.
| ghcr.io/meysam81/parse-dmarc:latest | |
| ghcr.io/meysam81/parse-dmarc:v1.1.0@sha256:<digest> |
|
|
||
| # Or deploy directly | ||
| gcloud run deploy parse-dmarc \ | ||
| --image ghcr.io/meysam81/parse-dmarc:latest \ |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Floating image tag ghcr.io/meysam81/parse-dmarc:latest in this Cloud Run deploy command can pull a tampered image if the tag is overwritten, enabling supply‑chain attacks. Pin to a specific version or image digest (e.g., --image ghcr.io/meysam81/parse-dmarc:v1.1.0@sha256:<digest>) to guarantee integrity.
| | **Koyeb** | [](https://app.koyeb.com/deploy?name=parse-dmarc&type=docker&image=ghcr.io/meysam81/parse-dmarc:latest&ports=8080;http;/) | Global edge deployment | | ||
| | **Zeabur** | [](https://zeabur.com/templates/parse-dmarc) | Asia-Pacific optimized | | ||
| | **Northflank** | [](https://app.northflank.com/s/account/templates/new?externalTemplateId=parse-dmarc) | Developer-focused | | ||
| | **Fly.io** | [](https://fly.io/launch?image=ghcr.io/meysam81/parse-dmarc:latest) | Edge computing | |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unpinned latest image references (ghcr.io/meysam81/parse-dmarc:latest) in these one‑click deploy links mean users may launch an unintended or malicious future build if the tag is updated, leading to unreviewed code execution. Update the links to use a stable version tag or signed digest (e.g., ...parse-dmarc:v1.1.0 or a digest URL) to ensure reproducible, trusted deployments.
| | **Koyeb** | [](https://app.koyeb.com/deploy?name=parse-dmarc&type=docker&image=ghcr.io/meysam81/parse-dmarc:latest&ports=8080;http;/) | Global edge deployment | | |
| | **Zeabur** | [](https://zeabur.com/templates/parse-dmarc) | Asia-Pacific optimized | | |
| | **Northflank** | [](https://app.northflank.com/s/account/templates/new?externalTemplateId=parse-dmarc) | Developer-focused | | |
| | **Fly.io** | [](https://fly.io/launch?image=ghcr.io/meysam81/parse-dmarc:latest) | Edge computing | | |
| | **Koyeb** | [](https://app.koyeb.com/deploy?name=parse-dmarc&type=docker&image=ghcr.io/meysam81/parse-dmarc:v1.1.0&ports=8080;http;/) | Global edge deployment | | |
| | **Zeabur** | [](https://zeabur.com/templates/parse-dmarc) | Asia-Pacific optimized | | |
| | **Northflank** | [](https://app.northflank.com/s/account/templates/new?externalTemplateId=parse-dmarc) | Developer-focused | | |
| | **Fly.io** | [](https://fly.io/launch?image=ghcr.io/meysam81/parse-dmarc:v1.1.0) | Edge computing | |
Add deployment templates and referral links for multiple cloud providers:
PaaS:
Enterprise Cloud:
Self-Hosted:
Changes: