# docker-bitcoind: a Bitcoin node in a container with a verified download

> A Docker image that runs bitcoind, with the chain kept in a named volume so a recreated container keeps its data, and a build that fetches Bitcoin Core from upstream, checks it against the published SHA256SUMS and verifies the signature with pinned keys. The setup is a handful of commands and the storage requirement is large.

**kylemanna/docker-bitcoind** — 💰 Bitcoind Docker image that runs the Bitcoin node in a container for easy deployment

- Repository: https://github.com/kylemanna/docker-bitcoind
- Website: https://hub.docker.com/r/kylemanna/bitcoind/
- Stars: 688 · Forks: 405
- Language: Shell
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/kylemanna-docker-bitcoind

## What the image does, and the host it needs

The project is a Docker image that runs the Bitcoin bitcoind node in a container for easy deployment, published on Docker Hub as kylemanna/bitcoind.

The requirements section is where the real constraints are, and they are specific. You need a physical machine, cloud instance or VPS that supports Docker, with the readme naming Vultr, Digital Ocean, and KVM or XEN based VMs, running Ubuntu 14.04 or later, and it says explicitly not OpenVZ containers.

The OpenVZ exclusion is worth understanding rather than skimming. OpenVZ is a container technology with a shared kernel and restricted syscall and filesystem access, and a container that needs its own mount and network namespace assumptions does not run well inside one. So the requirement is that the Docker host is a VM, not a container itself.

Then there is the storage, and the number is the one that decides whether this is for you. At least 700 GB to store the block chain files, and always growing. Plus at least 1 GB of RAM and a 2 GB swap file. The readme is blunt that this is a lot, and the recommended and tested configuration is an unadvertised Vultr SATA Storage instance with 1024 MB of RAM and a 250 GB disk, listed as ten dollars a month, and it notes that Vultr also accepts Bitcoin payments.

Note the mismatch between the recommended instance disk of 250 GB and the stated 700 GB requirement, which the readme does not reconcile. If you take one thing from this, take that: check the disk on the instance you are actually provisioning against the space the chain will need, because those two numbers are not the same.

## Creating the volume first, so the chain survives a rebuild

The quick start is four steps, and the first one is the one people skip.

You create a bitcoind-data volume to persist the bitcoind blockchain data. The readme says it should exit immediately, and the reason is that the bitcoind-data container will store the blockchain when the node container is recreated, for a software upgrade or a reboot:

```bash
docker volume create --name=bitcoind-data
docker run -v bitcoind-data:/bitcoin/.bitcoin --name=bitcoind-node -d \
    -p 8333:8333 \
    -p 127.0.0.1:8332:8332 \
    kylemanna/bitcoind
```

The volume create and the run are shown as one block because they belong together, but the ordering is what matters. The volume is declared separately so the data has a lifetime independent of the container.

The port mapping is the other thing to notice. Port 8333, the P2P port, is published on all interfaces, because that is how the node participates in the network. Port 8332, the JSON-RPC port, is published against 127.0.0.1 only, so the administrative interface is reachable from the host and not from the internet. That is a deliberate and correct choice, and it is worth preserving if you write your own compose file.

The named volume is mounted at /bitcoin/.bitcoin, which is the chain data directory inside the image, so the node finds its own data where it expects it after a container replacement.

A note on the image tag: the example pulls kylemanna/bitcoind without a tag, which means the latest build, and the readme notes there are no GitHub releases, so the image on Docker Hub is the only release channel to track.

## Checking the sync, and following the log

Verification is one command, and the expected output is shown in full.

You verify that the container is running and bitcoind node is downloading the blockchain with docker ps, and the readme includes the sample output line with the container id, the image, the command btc_oneshot, the uptime, the port mappings and the container name.

```bash
$ docker ps
```

The COMMAND column reading btc_oneshot is the interesting detail in that output. The image's entrypoint is a one-shot script, so the container starts, runs whatever setup is needed, and then the node process takes over inside the same container. It is not a container that exits after a task completes, it is a container whose entrypoint hands off to the daemon.

To watch what the daemon is doing you use the docker logs command:

```bash
docker logs -f bitcoind-node
```

For a first sync this is the command you will live in, because the download is the slow part and the log is where the progress shows up. Seeing the node move through the initial block download is the normal first experience, and it is exactly the phase where a container restart, a volume mistake or a disk shortfall shows up.

The readme also points to optional init scripts for upstart and systemd, which are in the init directory. Those are for running the node under a host init system rather than purely under Docker, which matters if you want the node to come back automatically after a reboot on a machine where you are not using a Docker daemon with a restart policy.

Additional documentation is in the docs folder, and the repository tree shows the pieces behind the image: a Dockerfile, a bootstrap-host.sh, a docker-entrypoint.sh, a bin directory, the init directory, a test directory and a .travis.yml.

## The one-liner path, and what it gives up

There is a faster route for a fresh Ubuntu 14.04 LTS machine, and it comes with a warning attached.

The readme calls it a really fast quick start: a one liner for Ubuntu 14.04 LTS machines with JSON-RPC enabled on localhost that adds upstart init script.

```bash
curl https://raw.githubusercontent.com/kylemanna/docker-bitcoind/master/bootstrap-host.sh | sh -s trusty
```

The trusty argument names the Ubuntu release, so the script is version aware, and the file it fetches is bootstrap-host.sh in the repository root, which means you can read it before running it rather than piping an unknown script into a shell.

The trade is explicit. This path assumes a clean Ubuntu 14.04 LTS machine, so it is for the common case of a fresh VPS where you want the node up without assembling the commands yourself. It also means you are executing a shell script over the network as root-adjacent on a machine that will hold a blockchain node, and the readme does not describe what that script does beyond the two things it names.

For a first installation on a machine you care about, running the volume create and the docker run by hand is better. You see each step, you see the port mapping you chose, and you can read the Dockerfile.

The docs folder is where more detail sits, and it is the right place to look if the one liner is going to be your route, since the readme itself is thin on what the bootstrap script configures.

## The build verifies the Bitcoin Core download, and skips the distro package

The Dockerfile is where this image does something better than the obvious thing, and the reasoning is written in the file.

The base image is ubuntu:latest, and there is a comment explaining why Alpine was rejected: Alpine would be nice, but it's linked against musl and breaks the Bitcoin Core download binary. The same reasoning appears again in the requirements section about the base image.

Then there is the verification. The build fetches the Bitcoin Core SHA256SUMS.asc and SHA256SUMS files and the tarball itself from bitcoincore.org, imports the Bitcoin Core signing keys with gpg over the Ubuntu keyserver, and verifies the checksum file with gpg before extracting. The pinned keys are given as build arguments, a set of four fingerprint lines under BITCOIN_CORE_SIGNATURES, and the VERSION argument defaults to 31.1.

The comment explaining why the base image's bitcoin package is not used gives three reasons. Using it would require the ppa/latest repository for the latest release. Some package generates /etc/bitcoin.conf on install, and the readme calls baking that in dangerous for Docker Hub. And verifying the package signature from the main website should inspire confidence and reduce the chance of surprises. Instead, the build fetches, verifies and extracts to the Docker image.

Multi-architecture support is handled with named build stages. There is a builder stage with an ARG for TARGETARCH, and three derived stages that set the ARCH environment variable, builder_amd64 setting x86_64, builder_arm64 setting aarch64, and builder_riscv64 setting riscv64, and the final stage selects builder_${TARGETARCH}.

So the image is built for three architectures, and the version of Bitcoin Core is a build argument rather than something baked into the published image, which means the version and the architecture are both controlled at build time.

## Where this image is the wrong choice

There are several cases where running bitcoind in Docker costs you more than it saves, and they are worth being concrete about.

The first is time to first usable node. A Bitcoin node needs the chain, and the chain download is the slow part. The image does not change that. If you want a node answering queries today, you want a provider or a synced node you can point at, and the 700 GB of storage and the hours of initial sync are the price of doing it yourself.

The second is disk pressure on a small host. The requirement is at least 700 GB and always growing, on an instance shape the readme recommends with a 250 GB disk. On a small VPS the chain fills the disk, and a full disk on a node is a problem you will debug in a hurry.

The third is that a container is not a security boundary for this workload in the way people sometimes assume. The node holds keys and speaks to the network, and the JSON-RPC port is the sensitive one, so the 127.0.0.1 binding in the example is doing real work and must be preserved.

The fourth is reproducibility of the node version. There are no GitHub releases, so the published image tag is the version, and the Dockerfile pins Bitcoin Core at build time rather than at run time, so the version of bitcoind you get depends on when the image was built, not on what you ask for.

And the fifth is that the readme is not a full operations manual. It gives you the requirements, the quick start, the log command, the init scripts and a docs folder. It does not cover upgrading the node, backing up the wallet, pruning the chain, or handling a corrupted database, and those are the operations that matter once the initial sync is done. The chain in a named volume is persistent, which also means it is your problem to manage.

## Against a native install, and against a hosted node

Two comparisons make the decision clear.

The first is against installing bitcoind natively on the host. The difference in approach is that the native install gives you one process managed by your init system, one copy of the chain, and no image layer in between, with the Bitcoin Core release you downloaded and verified yourself. The container gives you isolation and a reproducible image definition, and it gives the chain a lifecycle managed by Docker volumes, with the data surviving a container replacement.

The real question is operational. If you already run a fleet of machines with configuration management and a service supervisor, a native install and a unit file is often less to maintain than a Docker image plus a volume, because the volume introduces a second thing to back up and a second thing to go wrong. If you want to try a node on a throwaway VPS, or you want several nodes with different configurations on one host, the image is the faster route.

The second is against using a hosted node. A provider gives you a node without the disk, without the sync and without the uptime responsibility, and you pay per month for the privilege. This image gives you the opposite: you keep the data, you can point other services at it over JSON-RPC, and there is no third party between you and the chain. For a business that needs a node for verification or for a service that talks to one, that difference is the whole point.

The middle case is a synced node on your own hardware, and the choice there is between the image and the native package, decided by how your machines are managed rather than by the software.

## Conclusion

Adopt docker-bitcoind if you want to run your own Bitcoin node for analysis, for a service that talks to a node, or for reasons of verification, and you have the disk and the patience for an initial chain sync. Skip it if you need a node that is up and serving within minutes, since a full sync is the slow part and the image cannot change that. Verify first that you have the stated 700 GB of storage and 1 GB of RAM plus 2 GB of swap, that your host is not an OpenVZ container as the readme warns, and that the RPC port is bound to localhost as the example does rather than exposed.

## FAQ

### How do I run a Bitcoin node with docker-bitcoind?

Create a named volume with docker volume create --name=bitcoind-data, then run the container with that volume mounted at /bitcoin/.bitcoin, publishing port 8333 on all interfaces and port 8332 bound to 127.0.0.1 only. The readme shows the full docker run command with the -p mappings and the kylemanna/bitcoind image.

### What are the host requirements for running bitcoind in Docker?

A physical machine, cloud instance or VPS that supports Docker, running Ubuntu 14.04 or later, and not OpenVZ containers. You need at least 700 GB of storage for the block chain files, which are always growing, plus at least 1 GB of RAM and a 2 GB swap file.

### How do I check that the Bitcoin node is syncing?

Run docker ps to confirm the container is up, and then use docker logs -f bitcoind-node to follow the daemon's output and watch the initial chain download progress. The readme's sample docker ps output shows the command as btc_oneshot and the port mappings.

### Does the docker-bitcoind image verify the Bitcoin Core download?

Yes. The Dockerfile fetches the SHA256SUMS.asc and SHA256SUMS files and the tarball from bitcoincore.org, imports the pinned Bitcoin Core signing keys with gpg, and verifies the signature before extracting. The VERSION build argument defaults to 31.1, and the image is built for x86_64, aarch64 and riscv64.

### Why does docker-bitcoind use Ubuntu rather than Alpine?

The Dockerfile comments say Alpine would be nice, but it is linked against musl and breaks the Bitcoin Core download binary. The build also avoids the base image's bitcoin package, because it would need the ppa/latest repository, and because some package generates /etc/bitcoin.conf on install, which is dangerous to bake into a Docker Hub image.

### How current is docker-bitcoind?

The repository is not archived and the last push was on 2026-08-30, and there are no GitHub releases, so the Docker Hub image is the only release channel to track. The image homepage is on Docker Hub as kylemanna/bitcoind, and the licence is MIT with the LICENSE file at the root of the repository.

## Sources

- [Issues](https://github.com/kylemanna/docker-bitcoind/issues)
- [kylemanna/docker-bitcoind on GitHub](https://github.com/kylemanna/docker-bitcoind)
- [License: MIT](https://github.com/kylemanna/docker-bitcoind/blob/master/LICENSE)
- [Project website](https://hub.docker.com/r/kylemanna/bitcoind/)
- [README](https://github.com/kylemanna/docker-bitcoind/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kylemanna-docker-bitcoind
