# Update your package index
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">update # Install Docker's official GPG key and repository, then -weight: 500;">install Docker
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y ca-certificates -weight: 500;">curl gnupg
-weight: 600;">sudo -weight: 500;">install -m 0755 -d /etc/-weight: 500;">apt/keyrings
-weight: 500;">curl -fsSL [https://download.-weight: 500;">docker.com/linux/ubuntu/gpg](https://download.-weight: 500;">docker.com/linux/ubuntu/gpg) | -weight: 600;">sudo gpg --dearmor -o /etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg
-weight: 600;">sudo chmod a+r /etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg] [https://download.-weight: 500;">docker.com/linux/ubuntu](https://download.-weight: 500;">docker.com/linux/ubuntu) \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ -weight: 600;">sudo tee /etc/-weight: 500;">apt/sources.list.d/-weight: 500;">docker.list > /dev/null -weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">update
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y -weight: 500;">docker-ce -weight: 500;">docker-ce-cli containerd.io
# Update your package index
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">update # Install Docker's official GPG key and repository, then -weight: 500;">install Docker
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y ca-certificates -weight: 500;">curl gnupg
-weight: 600;">sudo -weight: 500;">install -m 0755 -d /etc/-weight: 500;">apt/keyrings
-weight: 500;">curl -fsSL [https://download.-weight: 500;">docker.com/linux/ubuntu/gpg](https://download.-weight: 500;">docker.com/linux/ubuntu/gpg) | -weight: 600;">sudo gpg --dearmor -o /etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg
-weight: 600;">sudo chmod a+r /etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg] [https://download.-weight: 500;">docker.com/linux/ubuntu](https://download.-weight: 500;">docker.com/linux/ubuntu) \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ -weight: 600;">sudo tee /etc/-weight: 500;">apt/sources.list.d/-weight: 500;">docker.list > /dev/null -weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">update
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y -weight: 500;">docker-ce -weight: 500;">docker-ce-cli containerd.io
# Update your package index
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">update # Install Docker's official GPG key and repository, then -weight: 500;">install Docker
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y ca-certificates -weight: 500;">curl gnupg
-weight: 600;">sudo -weight: 500;">install -m 0755 -d /etc/-weight: 500;">apt/keyrings
-weight: 500;">curl -fsSL [https://download.-weight: 500;">docker.com/linux/ubuntu/gpg](https://download.-weight: 500;">docker.com/linux/ubuntu/gpg) | -weight: 600;">sudo gpg --dearmor -o /etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg
-weight: 600;">sudo chmod a+r /etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg echo \ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/-weight: 500;">apt/keyrings/-weight: 500;">docker.gpg] [https://download.-weight: 500;">docker.com/linux/ubuntu](https://download.-weight: 500;">docker.com/linux/ubuntu) \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ -weight: 600;">sudo tee /etc/-weight: 500;">apt/sources.list.d/-weight: 500;">docker.list > /dev/null -weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">update
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y -weight: 500;">docker-ce -weight: 500;">docker-ce-cli containerd.io
# Install apache2-utils for the htpasswd command
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y apache2-utils # Create a directory to store your registry data and passwords
mkdir -p /opt/registry/auth # Create a user (replace 'admin' with your preferred username)
# You will be prompted to type a password.
htpasswd -Bc /opt/registry/auth/htpasswd admin
# Install apache2-utils for the htpasswd command
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y apache2-utils # Create a directory to store your registry data and passwords
mkdir -p /opt/registry/auth # Create a user (replace 'admin' with your preferred username)
# You will be prompted to type a password.
htpasswd -Bc /opt/registry/auth/htpasswd admin
# Install apache2-utils for the htpasswd command
-weight: 600;">sudo -weight: 500;">apt-get -weight: 500;">install -y apache2-utils # Create a directory to store your registry data and passwords
mkdir -p /opt/registry/auth # Create a user (replace 'admin' with your preferred username)
# You will be prompted to type a password.
htpasswd -Bc /opt/registry/auth/htpasswd admin
-weight: 500;">docker run -d \ -p 5000:5000 \ ---weight: 500;">restart=always \ --name my-private-registry \ -v /opt/registry/auth:/auth \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -v /opt/registry/data:/var/lib/registry \ registry:2
-weight: 500;">docker run -d \ -p 5000:5000 \ ---weight: 500;">restart=always \ --name my-private-registry \ -v /opt/registry/auth:/auth \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -v /opt/registry/data:/var/lib/registry \ registry:2
-weight: 500;">docker run -d \ -p 5000:5000 \ ---weight: 500;">restart=always \ --name my-private-registry \ -v /opt/registry/auth:/auth \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -v /opt/registry/data:/var/lib/registry \ registry:2
# Replace <PRIVATE_IP> with your manager server's internal IP address
-weight: 500;">docker swarm init --advertise-addr <PRIVATE_IP>
# Replace <PRIVATE_IP> with your manager server's internal IP address
-weight: 500;">docker swarm init --advertise-addr <PRIVATE_IP>
# Replace <PRIVATE_IP> with your manager server's internal IP address
-weight: 500;">docker swarm init --advertise-addr <PRIVATE_IP>
-weight: 500;">docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxx <MANAGER_PRIVATE_IP>:2377
-weight: 500;">docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxx <MANAGER_PRIVATE_IP>:2377
-weight: 500;">docker swarm join --token SWMTKN-1-xxxxxxxxxxxxxxxxxxxx <MANAGER_PRIVATE_IP>:2377
-weight: 500;">docker node ls
-weight: 500;">docker node ls
-weight: 500;">docker node ls
# Replace with the IP or domain of your Registry server
-weight: 500;">docker login <REGISTRY_SERVER_IP>:5000
# Replace with the IP or domain of your Registry server
-weight: 500;">docker login <REGISTRY_SERVER_IP>:5000
# Replace with the IP or domain of your Registry server
-weight: 500;">docker login <REGISTRY_SERVER_IP>:5000
{ "insecure-registries" : ["<REGISTRY_SERVER_IP>:5000"]
}
{ "insecure-registries" : ["<REGISTRY_SERVER_IP>:5000"]
}
{ "insecure-registries" : ["<REGISTRY_SERVER_IP>:5000"]
}
# Pull standard nginx
-weight: 500;">docker pull nginx:latest # Tag it to point to your private registry
-weight: 500;">docker tag nginx:latest <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1 # Push it to your dedicated registry server
-weight: 500;">docker push <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1
# Pull standard nginx
-weight: 500;">docker pull nginx:latest # Tag it to point to your private registry
-weight: 500;">docker tag nginx:latest <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1 # Push it to your dedicated registry server
-weight: 500;">docker push <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1
# Pull standard nginx
-weight: 500;">docker pull nginx:latest # Tag it to point to your private registry
-weight: 500;">docker tag nginx:latest <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1 # Push it to your dedicated registry server
-weight: 500;">docker push <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1
-weight: 500;">docker -weight: 500;">service create \ --name web-app \ --replicas 3 \ --publish published=8080,target=80 \ --with-registry-auth \ <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1
-weight: 500;">docker -weight: 500;">service create \ --name web-app \ --replicas 3 \ --publish published=8080,target=80 \ --with-registry-auth \ <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1
-weight: 500;">docker -weight: 500;">service create \ --name web-app \ --replicas 3 \ --publish published=8080,target=80 \ --with-registry-auth \ <REGISTRY_SERVER_IP>:5000/my-custom-nginx:v1 - Security & Control: Public registries are great for open-source, but proprietary code belongs on hardware you control. A private registry on a dedicated server ensures your intellectual property never leaves your private network.
- Lightning-Fast Deployments: Pulling container images over a local, private Gigabit network (like the internal networks provided with BytesRack servers) is vastly faster than pulling them over the public internet.
- No Vendor Lock-in: Docker Swarm is built natively into Docker. It is drastically simpler to manage than Kubernetes, requires less overhead, and runs brilliantly on bare metal. - Server 1 (The Registry Node): An Ubuntu 22.04 or 24.04 server. Needs decent storage space (NVMe preferred) to store your container images.
- Server 2 & 3 (The Swarm Nodes): Two Ubuntu servers to act as your manager and worker nodes.
- Full Root Access: You need -weight: 600;">sudo or root privileges on all machines.
- Private Networking: Ideally, these servers should be able to communicate via private IPs to keep traffic secure and fast.