Your own private Docker registry: push, pull and deploy
Create a ByteNests container registry, push your first image, pull it on a VM and run it on App Platform, with scanning and cleanup switched on.
Public registries are fine for open-source images. Your own application images belong somewhere private, close to the servers that run them. This tutorial goes from an empty account to an image that is pushed, scanned, pulled and deployed.
What you need
Docker installed on your computer (Docker Desktop on Windows and macOS, or Docker Engine on Linux).
An image to push. Any docker build result will do, for example my-app:1.0.
A payment method on your ByteNests account.
Step 1: create the registry
Open Container Registry and choose Create registry. Each account has one registry, holding as many repositories as you like.
Name it, for example acme. Use 3 to 63 lowercase letters, numbers and single hyphens, starting with a letter. The name is the first part of every image address and cannot be changed, so pick your company or team name.
Set a storage limit. It is a cap, not a charge: you pay only for the GB you actually store.
Leave Scan on push on.
Create your first access token, for example laptop, and copy its secret. It is shown only once.
From a terminal, the same thing is one command, which also prints the token:
bn registry create acme --token laptop
bn registry get
Step 2: log in with Docker
Use the token’s username and secret. The registry page shows the exact host and commands with your details filled in.
echo "$SECRET" | docker login <registry host> -u 'robot$...' --password-stdin
Token usernames contain a $. In a shell, put the username in single quotes, or the shell will treat part of it as a variable.
Step 3: tag and push
Docker pushes an image to the registry named at the start of its tag, so tag your local image with the full address first: host, registry name, repository and version.
docker tag my-app:1.0 <registry host>/acme/my-app:1.0
docker push <registry host>/acme/my-app:1.0
The repository (my-app) is created on the first push. Use a real version for the tag, such as 1.0 or a Git commit hash, rather than only latest, so you always know what is running and can go back.
Step 4: check the scan
With Scan on push, every new image is checked for known vulnerabilities (CVEs) in its operating system packages and libraries. The repository list shows the worst finding, and each image lists its vulnerabilities and whether a fix exists.
Most findings are fixed by rebuilding on a newer base image, for example moving from an old node or python tag to the current one, and pushing again.
Step 5: pull it on a VM
On any server with Docker, log in with a token and pull. Pulls from your ByteNests VMs and App Platform apps are free.
echo "$SECRET" | docker login <registry host> -u 'robot$...' --password-stdin
docker pull <registry host>/acme/my-app:1.0
docker run -d --restart unless-stopped -p 80:8080 <registry host>/acme/my-app:1.0
For servers that only run images, create a separate pull-only token (bn registry token create --name web-1 --pull-only). If the server is ever compromised, the token cannot push anything, and you can revoke it without touching your own.
Step 6: or let App Platform run it
Instead of managing Docker on a VM, open Apps → Create app, choose Your container registry as the source, and pick the repository and tag. App Platform runs the image, gives it an HTTPS address, and redeploys automatically whenever you push a new image to that tag. See From a Git repository to HTTPS for the rest of the app settings.
Keep storage under control
Every push adds layers, and old tags pile up. Cleanup rules run daily and remove old or untagged images while keeping the newest tags in each repository. Space is freed at the weekly garbage collection on Sunday at 03:00 UTC. An image that an App Platform app is running is never removed until the app deploys another one.