21 min read

Self-Host doco-cd for Docker Compose GitOps

Install and verify doco-cd for Docker Compose GitOps, then expose its webhook endpoint securely through a Localtonet HTTP tunnel.

Git webhooks reach self-hosted doco-cd through a Localtonet tunnel, triggering Docker Compose deployments.
doco-cd connects repository events to Docker Compose deployments while Localtonet provides the public webhook path.
DevOps and Continuous Deployment ยท doco-cd ยท Localtonet ยท 2026

Build a careful Docker Compose GitOps workflow, verify it locally, and publish only the webhook endpoint that needs remote access

doco-cd is a lightweight, self-hosted GitOps service that can deploy Docker Compose projects and Docker Swarm stacks from Git repositories or OCI artifacts. This guide explains the documented deployment model, image selection, configuration decisions, local verification, routine operations, and version-specific concerns. It also identifies an important evidence limitation: the available official material confirms the container image and product capabilities, but does not provide enough installation parameters to reproduce a safe container startup command here. Once a verified doco-cd webhook is working locally, we show how to expose that specific HTTP endpoint with Localtonet without inbound router port forwarding, firewall changes, VPN setup, or a public IP address.

๐Ÿ”’ Keep management interfaces and credentials private ๐ŸŒ Publish a verified webhook through an HTTP tunnel โšก Use webhooks, polling, or both for deployment triggers

What doco-cd does in a Docker Compose GitOps workflow

doco-cd stands for Docker Compose Continuous Deployment. It watches deployment definitions held in Git repositories or OCI artifacts and can update Docker Compose projects and Docker Swarm stacks when their desired state changes. The project describes itself as a simpler alternative for operators who need continuous delivery for Docker without adopting a larger orchestration platform.

A typical workflow has three distinct layers. A Git provider stores the desired deployment configuration. doco-cd runs close to the Docker daemon that performs the deployment. A trigger tells doco-cd when it should reconcile the desired configuration with the running environment. That trigger can come from polling, a webhook, or a combination selected according to the project's documented configuration.

๐Ÿ“ฆ Compose and Swarm deployments doco-cd supports Docker Compose projects and Docker Swarm stacks in Swarm mode. The correct operating model depends on the Docker environment attached to the service.
๐Ÿ”” Webhook and polling triggers Deployments can be triggered through webhooks, polling, or both. Polling avoids a public callback, while webhooks can reduce the delay between a repository change and reconciliation.
๐Ÿ” Secrets integrations The project documents support for external secret-management providers and data encryption with SOPS. The correct provider and key setup must be selected from the version-matched project documentation.
๐Ÿ“Š Observability doco-cd provides notifications and Prometheus metrics. Metrics should normally remain private unless there is a deliberate access-control design for remote monitoring.
โฑ๏ธ Scheduled jobs Job scheduling and cron-style periodic tasks are supported. Scheduled work should be reviewed separately from repository-triggered deployments.
๐Ÿณ Multiple Docker contexts Release 0.113.0 adds multi-context support across deployments, reconciliation, scheduled jobs, certificate rotation, the REST API, and observability.

The network boundary matters. A webhook receiver must be reachable by the Git provider that sends the event, but the Docker control plane, local management endpoints, credentials, and metrics do not automatically need the same exposure. Treat the webhook as a narrowly scoped ingress path rather than publishing every doco-cd endpoint.

A public webhook can initiate deployment activity

Do not expose an assumed port or path. Confirm the exact webhook URL and the authentication or signature-validation requirements in the documentation for the installed doco-cd version and the selected Git provider. Never place repository tokens, webhook secrets, SSH keys, or Localtonet device tokens in a public URL, screenshot, Compose file committed to Git, or article example.

Prerequisites and decisions to make before installation

The official overview confirms that doco-cd is distributed as a minimal container image. A practical installation therefore requires a Docker host capable of pulling and running that image. If the intended target is Docker Swarm, the host and Swarm configuration must already be suitable for that mode. If the target is ordinary Docker Compose, prepare the Docker environment that will own the deployed projects.

You also need a Git repository or supported OCI artifact containing the deployment definitions. The documented Git providers include GitHub, GitLab, Gitea, Forgejo, Gogs, and Azure DevOps. Azure DevOps has a specific limitation: service hooks are not supported. That limitation can affect whether polling is the appropriate trigger.

Requirement Why it is needed What to verify
Docker environment Runs doco-cd and the workloads it deploys Docker is working and the intended daemon or context is available
Deployment source Stores the desired Compose or Swarm configuration The repository or OCI artifact is reachable using an approved authentication method
Version choice Keeps configuration aligned with documented behavior Choose a tested release instead of assuming that latest is appropriate
Trigger strategy Determines how changes initiate reconciliation Select polling, webhooks, or both based on supported provider behavior
Secret storage Protects repository credentials, webhook secrets, and deployment secrets Use the project-supported mechanism appropriate to the installed version
Rollback plan Limits the impact of an unsuccessful deployment Preserve known-good definitions and understand how the workload itself is recovered

Decide whether the deployment will track a floating image tag or a fixed version. The official image is hosted in GitHub Container Registry. The documentation uses latest for the current image and explains that a fixed release omits the leading v from the release tag. For example, release v0.113.0 maps to image tag 0.113.0.

Pinning a version makes testing and rollback more predictable. A floating tag can be useful in a deliberately managed update process, but it can also introduce changes when the image is pulled again. Always review release notes before changing versions, especially when a release identifies breaking changes.

Install the documented doco-cd container image

The available official evidence establishes the image name and image-tag format. It does not establish the complete production startup contract needed for a trustworthy docker run command or Compose service definition. In particular, it does not provide the required mounts, Docker socket or context configuration, configuration-file location, environment variables, container user, health check, listening port, or restart policy.

We will not invent those values. The safe installation sequence below completes the portion that is documented, then places an explicit verification gate before startup. Use the stable documentation matching your chosen release to obtain the missing runtime parameters.

1

Choose a tested doco-cd release

Review the release notes and select a version compatible with your Docker mode, deployment definitions, labels, keys, and job configuration. Record the selected version in your operational change.

2

Pull the official container image

Pull the documented image from GitHub Container Registry. Use either the current floating tag or, preferably for a controlled deployment, a tested fixed version.

3

Obtain the version-matched runtime configuration

Before creating a container, consult the stable Getting Started and Configuration pages corresponding to the selected release. Copy the documented runtime parameters exactly and review every privilege, mount, credential, endpoint, and Docker access setting.

4

Start doco-cd using only documented parameters

Create the service from the verified configuration. Do not infer a port, mount the Docker socket casually, or add an environment variable because another project uses it. Container access to Docker is security-sensitive and should be limited to the documented requirement.

To pull the floating image documented by the project:

docker pull ghcr.io/kimdre/doco-cd:latest

To pull the specifically evidenced 0.113.0 release:

docker pull ghcr.io/kimdre/doco-cd:0.113.0
Why there is no fabricated Compose file here

A plausible-looking Compose file could start with the wrong permissions, omit required state, publish an unintended interface, or fail to provide the Docker context doco-cd needs. The supplied official overview confirms the image but not a complete runnable service definition. Use the project's version-matched Getting Started configuration for startup, then return to this guide for local verification and Localtonet integration.

After pulling the image, you can confirm that it exists locally without assuming anything about its runtime interface:

docker image inspect ghcr.io/kimdre/doco-cd:0.113.0

If you selected another version, replace 0.113.0 with that exact tag. An image inspection confirms that Docker has the requested image, but it does not prove that doco-cd is configured, running, or able to deploy workloads.

Configure repositories, triggers, Docker contexts, and secrets

doco-cd configuration links repositories and triggers to Docker contexts while keeping secrets referenced separately.
Repository rules determine what runs, Docker contexts determine where it runs, and secret references protect sensitive values.

Configuration should start with one non-critical deployment. Establish a small project whose expected state is easy to observe. This isolates connectivity and configuration problems before doco-cd is entrusted with important services.

Select a deployment source

doco-cd supports Git repositories and OCI artifacts for deployment configurations. When using Git, provide access through the authentication mechanism documented for the selected provider and release. Grant only the repository permissions required by the workflow. Avoid broad organization-wide tokens when repository-specific access is sufficient.

Choose polling, webhooks, or both

Trigger Network requirement Operational consideration
Polling Outbound access from doco-cd to the source No inbound webhook is required, but deployment detection follows the configured polling behavior
Webhook The provider must reach the verified callback endpoint Requires careful endpoint exposure and the project-supported request validation
Webhook plus polling Outbound source access and inbound callback reachability Can combine event-driven updates with periodic reconciliation when supported by the chosen configuration

Do not assume that every provider uses the same event payload, secret field, or callback path. Configure the provider according to doco-cd's provider-specific webhook instructions. Azure DevOps service hooks are documented as unsupported, so do not promise a webhook workflow for that provider without newer version-specific evidence.

Account for release 0.113.0 changes

Version 0.113.0 removes the deprecated one_shot job execution alias. Job definitions must use one_off. It also retires legacy auto-discovery label names in favor of cd.doco.deployment.auto_discovery and the JSON configuration label cd.doco.deployment.auto_discovery.config. Existing deployments using the old labels are described as automatically migrated, but new configuration should use the current labels.

The same release removes support for PKCS#1 encrypted private keys because the underlying Go API was deprecated. Use a modern OpenSSH key or another supported format confirmed by the project documentation. Never remove key protection merely as an improvised production fix without assessing the resulting risk.

Version 0.113.0 also introduces the service label cd.doco.deployment.autostart. It defaults to true. Setting it to false allows an external tool to control the lifecycle of a service: a service without a container is created but not started, and a stopped service remains stopped when recreated or updated. A running service is restarted normally when recreated or updated, while a service that remains stopped is excluded from deployment readiness checks.

services:
  on-demand:
    image: example/on-demand:latest
    labels:
      cd.doco.deployment.autostart: "false"

Treat that snippet only as an illustration of the documented label. It is not a complete application or doco-cd installation file.

Review Docker context selection

Multi-context support in 0.113.0 extends to deployments, reconciliation, job scheduling, certificate rotation for external secrets, REST API behavior, and Prometheus metrics. Named contexts must exist in the Docker CLI context store available to doco-cd. Project, stack, and scheduled-job endpoints accept an optional context query parameter in this release. If the parameter is omitted or set to default, the default Docker context is used.

Verify context selection before a deployment. A valid configuration aimed at the wrong Docker context can affect the wrong host even when every repository and Compose setting is otherwise correct.

Start carefully and verify doco-cd locally

Local verification checks that the doco-cd container is running and its configured webhook endpoint responds.
Verify the container, logs, and local webhook response before exposing the service publicly.

Local verification must happen before remote exposure. First confirm that the container remains running and inspect its logs using standard Docker commands. Replace the placeholder with the actual container or service name from the official installation configuration.

docker ps
docker logs <doco-cd-container-name>

If doco-cd is deployed as a Swarm service, use the appropriate Docker service inspection and service-log workflow for the actual service name. Do not copy a container-oriented command and assume it describes Swarm behavior.

A complete local acceptance test should prove more than process availability:

1

Confirm a stable process

Verify that the doco-cd container or service remains active rather than repeatedly restarting. Read startup logs for configuration, credential, repository, and Docker connectivity errors.

2

Confirm access to the intended source

Verify that doco-cd can read the selected Git repository or OCI artifact without exposing the credential in logs or command history.

3

Confirm the Docker target

Check that the intended daemon and Docker context are selected. With multi-context configuration, verify this explicitly for every managed project.

4

Perform a controlled deployment

Change a harmless test workload, trigger reconciliation through the selected method, and verify that the resulting Compose project or Swarm stack matches the expected state.

5

Verify the webhook locally

Obtain the exact local webhook scheme, address, port, path, and validation method from the installed version's documentation and configuration. Test it locally using a provider-compatible request. A generic GET request is not sufficient evidence that an authenticated webhook event will work.

The webhook URL and port are intentionally not guessed

The available evidence confirms that doco-cd supports webhooks and Prometheus metrics, but it does not specify their listening addresses, ports, paths, authentication requirements, or TLS behavior. Record those values from the actual version-matched configuration before creating a Localtonet tunnel. Do not substitute a common application port.

Keep a written verification record containing the installed image tag, configuration revision, selected Docker context, repository tested, trigger tested, resulting workload version, and rollback result. This makes later upgrades and incident investigation substantially easier.

Expose the verified webhook with a Localtonet HTTP tunnel

A Git webhook travels through a Localtonet HTTP tunnel to the local doco-cd webhook endpoint.
The Localtonet route exposes the verified local webhook without a direct inbound route to the Docker host.

Once the webhook works locally, Localtonet can provide its public HTTPS address. The Localtonet client on the device that can reach doco-cd establishes an outbound connection to one of our relay servers. This means the workflow does not require inbound router port forwarding, firewall changes, VPN setup, or a public IP address.

Use an HTTP tunnel for the HTTP webhook service. The local target is the verified IP address and port on the same machine as the Localtonet client or on another service reachable from that device. The tunnel is available only while the selected client is connected and the tunnel is running.

1

Install and run the Localtonet client

Install our client on the doco-cd host or another device that can reach the verified local webhook service. Keep the client running for as long as the webhook must remain reachable.

2

Authenticate the correct device

Select the device-specific authentication token associated with the client that can reach doco-cd. Never guess, publish, or reuse a token as sample content.

3

Select an available relay server

Choose a currently available server or region from the Localtonet dashboard. Available values can vary, so they should be selected from the current product rather than copied from an article.

4

Create the HTTP tunnel

Point the tunnel at the exact local IP address and port established during doco-cd verification. The path normally remains part of the URL used by the Git provider, so preserve the documented webhook path when entering the final callback URL.

5

Start the tunnel

Creating a tunnel does not start it. Use the Start button and confirm that the selected client is connected. The assigned public HTTPS address becomes usable only while the tunnel and client remain active.

6

Configure and test the provider webhook

Combine the assigned public address with doco-cd's verified webhook path. Configure the provider's supported secret or validation mechanism, send a controlled event, and confirm the expected deployment behavior and logs.

Expose only what the integration needs

The Localtonet tunnel forwards requests to the configured local HTTP target. It does not replace doco-cd's webhook authentication or request validation. Keep Prometheus metrics, management endpoints, and unrelated local services outside the public path unless each one has a separate, justified access design.

HTTP and File Server tunnels can use a generated subdomain, a selected subdomain where supported, or a custom domain. Exact custom-domain DNS requirements should be checked against current Localtonet documentation before configuring DNS. A generated public address is usually sufficient for an initial controlled webhook test.

Operate and update the deployment safely

A GitOps service has the authority to modify running workloads, so routine maintenance should be treated as a controlled production change. Back up the configuration and any persistent state identified by the project documentation. Preserve the exact image tag and a known-good configuration so that rollback does not depend on reconstructing old settings from memory.

Review releases before upgrading

Read every release between the installed version and the target version. Version 0.113.0 illustrates why this matters: it rejects the removed one_shot alias, changes auto-discovery labels, drops support for PKCS#1 encrypted private keys, and adds multi-context behavior. An image pull alone does not identify which local definitions need migration.

Test changes on a low-risk workload

Validate repository access, webhook processing, polling, Docker context selection, scheduled jobs, notification delivery, and metrics collection where those capabilities are used. A successful container startup does not prove that reconciliation is safe.

Control tunnel lifecycle

Stop the Localtonet tunnel when the webhook is not needed, or delete it when the integration is retired. Remember that the provider cannot deliver events while the Localtonet client is disconnected or the tunnel is stopped. If polling is configured, determine whether it provides an acceptable fallback for your workflow rather than assuming that it does.

Rotate credentials deliberately

Repository tokens, SSH keys, webhook secrets, and external secret-provider credentials should be rotated according to your security policy. Test the replacement before revoking the old credential where your process permits overlap. A Localtonet device token identifies the client device and must also remain private.

Troubleshooting doco-cd and webhook delivery

Symptom Likely boundary to inspect Safe diagnostic action
The image will not pull Registry access, image name, or tag Confirm access to ghcr.io and verify the exact release tag without a leading v
The container exits immediately Runtime configuration Read container logs and compare mounts, permissions, and settings with the matching stable documentation
The repository cannot be read Provider URL, token, SSH key, or permissions Validate the supported authentication method and least-privilege repository access without printing secrets
The wrong host is updated Docker context selection Inspect the default or named context available to doco-cd before allowing another reconciliation
Local webhook tests fail Path, port, payload, or validation Recheck the installed version's webhook documentation and use a provider-compatible test event
Local tests pass but public delivery fails Localtonet client, tunnel state, or provider callback URL Confirm the client is connected, the tunnel is started, and the public URL includes the exact webhook path
Events arrive but no deployment occurs Event filtering, repository mapping, credentials, or reconciliation Correlate provider delivery status with doco-cd logs and test one harmless commit
Jobs fail after upgrading to 0.113.0 Removed job alias Replace one_shot with one_off in affected job definitions

Troubleshoot from the inside out. First prove that doco-cd is healthy. Then prove that it can reach the repository and intended Docker context. Next prove that the webhook works locally with the correct payload and validation. Only after those checks should you investigate the public tunnel and provider delivery.

This sequence prevents a Localtonet tunnel from being blamed for a local application error and prevents an application configuration change from masking a tunnel lifecycle issue. Change one boundary at a time and retain timestamps that let you correlate provider delivery records, doco-cd logs, Docker events, and deployment results.

Frequently asked questions

What is doco-cd used for?

doco-cd is a lightweight GitOps continuous delivery service for automatically deploying and updating Docker Compose projects and Docker Swarm stacks. It can consume deployment configuration from Git repositories or OCI artifacts and can react through polling, webhooks, or both.

Why does this guide not provide a complete docker run command?

The available official evidence confirms the image name and tag format but does not establish all required runtime parameters, such as mounts, ports, configuration paths, Docker access, environment variables, or the container user. Guessing those details could create an insecure or nonfunctional deployment, so startup must follow the stable documentation matching the selected version.

Must doco-cd have a public webhook?

No. doco-cd supports polling as well as webhooks. Polling may be preferable where inbound callbacks are not required. If webhooks are selected, the provider needs a reachable endpoint and the request should use the validation mechanism supported by doco-cd and that provider.

Which local port should the Localtonet HTTP tunnel use?

Use the exact local port confirmed by the installed doco-cd version's configuration and your successful local webhook test. The supplied evidence does not establish a default port, so a port should not be inferred from unrelated examples.

Does Localtonet replace webhook authentication?

No. Our HTTP tunnel provides public reachability to the configured local target. doco-cd and the Git provider must still use their supported webhook secret, signature validation, event filtering, and authorization controls.

Does the Localtonet tunnel remain available if the client disconnects?

No. The tunnel is available only while the selected Localtonet client is connected and the tunnel is running. Creating the tunnel is not enough; it must also be started.

Can doco-cd manage more than one Docker context?

Release 0.113.0 adds multi-context support across deployments, reconciliation, scheduled jobs, certificate rotation, REST API behavior, and observability. Named contexts must exist in the Docker CLI context store available to doco-cd. Verify context selection carefully before deployment.

Should Prometheus metrics use the same public tunnel as the webhook?

Not by default. A Git provider needs the webhook callback, not general access to monitoring or management endpoints. Keep metrics private unless remote access is explicitly required and protected by a separate access-control design.

Connect your verified doco-cd webhook with Localtonet

After doco-cd is running, a controlled deployment succeeds, and the exact webhook endpoint works locally, create a Localtonet HTTP tunnel to give that endpoint a public HTTPS address without opening an inbound router port.

Get Started Free โ†’

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support