Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions cabotage/celery/tasks/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,25 +539,25 @@ def file_path(filename):
return os.path.join(image.application.subdirectory, filename)
return filename

dockerfile_candidates = ["Dockerfile.cabotage", "Dockerfile"]
if image.application.dockerfile_path:
dockerfile_candidates = [image.application.dockerfile_path]

dockerfile_name = None
dockerfile_body = _fetch_github_file(
image.application.github_repository,
image.commit_sha,
access_token=access_token,
filename=file_path("Dockerfile.cabotage"),
)
dockerfile_name = "Dockerfile.cabotage"
if dockerfile_body is None:
dockerfile_body = None
for candidate in dockerfile_candidates:
dockerfile_body = _fetch_github_file(
image.application.github_repository,
image.commit_sha,
access_token=access_token,
filename=file_path("Dockerfile"),
filename=file_path(candidate),
)
dockerfile_name = "Dockerfile"
if dockerfile_body is not None:
dockerfile_name = candidate
break
if dockerfile_body is None:
raise BuildError(
"No Dockerfile.cabotage or Dockerfile found in root of "
f"No Dockerfile found in "
f"{git_ref(image.application.github_repository, image.commit_sha)}"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ <h2>Deployment Automation</h2>
{{ form_field(form.github_repository) }}
{{ form_field(form.auto_deploy_branch) }}
{{ form_field(form.subdirectory) }}
{{ form_field(form.dockerfile_path) }}
{{ form_field(form.github_repository_is_private) }}
{{ form_field(form.github_app_installation_id) }}
{{ form_field(form.github_environment_name ) }}
Expand Down
5 changes: 5 additions & 0 deletions cabotage/server/models/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ class Application(db.Model, Timestamp):
nullable=True,
)

dockerfile_path = db.Column(
db.Text(),
nullable=True,
)

auto_deploy_branch = db.Column(
db.Text(),
nullable=True,
Expand Down
8 changes: 8 additions & 0 deletions cabotage/server/user/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ class EditApplicationSettingsForm(FlaskForm):
"Subdirectory",
description="Subdirectory to build out of",
)
dockerfile_path = StringField(
"Dockerfile Path",
description="Custom path to Dockerfile (e.g. docker/Dockerfile), falls back to Dockerfile.cabotage then Dockerfile",
filters=[
(lambda x: x.strip() if (x and isinstance(x, str)) else x),
(lambda x: x if x else None),
],
)
github_app_installation_id = StringField(
"GitHub Application Installation ID",
description="Application Installation ID from GitHub",
Expand Down
30 changes: 30 additions & 0 deletions migrations/versions/a1b2c3d4e5f6_add_dockerfile_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Add configurable dockerfile_path to applications

Revision ID: a1b2c3d4e5f6
Revises: c2ae2e19e1f2
Create Date: 2026-02-17 20:30:00.000000

"""

from alembic import op
import sqlalchemy as sa

revision = "a1b2c3d4e5f6"
down_revision = "c2ae2e19e1f2"
branch_labels = None
depends_on = None


def upgrade():
op.add_column(
"project_applications", sa.Column("dockerfile_path", sa.Text(), nullable=True)
)
op.add_column(
"project_applications_version",
sa.Column("dockerfile_path", sa.Text(), autoincrement=False, nullable=True),
)


def downgrade():
op.drop_column("project_applications_version", "dockerfile_path")
op.drop_column("project_applications", "dockerfile_path")