Install Docker & Docker Compose on Ubuntu for Production
A practical guide to installing Docker Engine and Docker Compose on an Ubuntu VPS, verifying the installation, and preparing a dedicated deployment user for production workloads.
1. Before You Install Docker
Once your Ubuntu VPS has been updated, secured and configured for SSH key access, the next step for many modern deployments is installing Docker.
Docker gives you a consistent way to package your application and its dependencies into containers. Docker Compose then lets you define and operate multiple services, such as your web application, API, Redis or PostgreSQL, from a single configuration.
This guide installs Docker using Docker's official repository-based installation method, verifies Docker Compose and prepares the server for application deployment.
This article assumes you have already completed the basic Ubuntu VPS setup from the first article in this series.
By the end of this guide, your VPS should have:
- Docker Engine installed
- Docker CLI installed
- containerd installed
- Docker Buildx installed
- Docker Compose plugin installed
- Docker enabled at startup
- a dedicated deploy user
- Docker access for the deployment user
- a production application directory under /opt
The production model we are preparing for is roughly:
We are only setting up the Docker layer in this article. Application deployment, GitHub access and reverse-proxy configuration should be handled in later steps.
2. Connect to the VPS
Connect using the administrator account created in the first guide.
ssh youradmin@YOUR_VPS_IPIf you configured a local SSH alias, use that instead:
ssh myvpsVerify the current user:
whoamiYou should be working through your normal administrator account rather than using direct root SSH for everyday administration.
3. Prepare Docker's Apt Repository
Before installing Docker packages, update the package index and install the base packages required for repository setup.
sudo apt update
sudo apt install -y ca-certificates curlCreate the directory Ubuntu will use for repository signing keys:
sudo install -m 0755 -d /etc/apt/keyringsDownload Docker's official signing key and make it readable by the package manager:
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.ascAdd Docker's apt repository using the current Docker sources format:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOFThen refresh the package index:
sudo apt updateUbuntu can now install Docker packages from Docker's configured repository.
4. Install Docker Engine and Compose
Install the Docker Engine, Docker CLI, container runtime, Buildx and Compose plugin packages:
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-pluginThis gives you the primary components needed for a Docker-based deployment workflow.
- docker-ce: Docker Engine
- docker-ce-cli: Docker command-line interface
- containerd.io: container runtime
- docker-buildx-plugin: extended Docker build functionality
- docker-compose-plugin: Docker Compose
Modern Compose commands use docker compose rather than the older docker-compose standalone command.
5. Enable and Start Docker
Enable Docker so it starts automatically when the VPS reboots, then start the service now:
sudo systemctl enable docker
sudo systemctl start dockerCheck the service status:
sudo systemctl status dockerYou should see Docker reported as running. Exit the status screen with q.
6. Verify Docker and Compose
Run Docker's test container:
sudo docker run hello-worldDocker should download the test image, create a container, run it and print the Docker welcome message. If that works, the Docker Engine installation is functional.
Check the Compose version:
docker compose versionYou should receive version information rather than a command not found error. You can also confirm Docker itself:
docker --version7. Create a Deployment User
Your administrator account has sudo access because it manages the server. Your application deployment account does not necessarily need the same level of access.
A cleaner model separates responsibilities:
Create the deploy account:
sudo adduser deployFollow the prompts to complete account creation. Do not automatically add this user to the sudo group if it is intended only for application deployment.
If password SSH login is disabled, install an SSH public key for the deploy account before trying to connect directly as that user. One simple approach is to reuse the administrator account's authorized key:
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo cp ~/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
sudo chown deploy:deploy /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keysFor stricter separation, generate and install a dedicated deployment SSH key instead of reusing the administrator key.
Add deploy to the Docker group:
sudo usermod -aG docker deployDocker group membership is powerful. Only give Docker access to accounts that are trusted to perform deployments on that VPS.
Group membership changes normally require a new login session before they take effect.
8. Test Docker Access as Deploy
Log into the deployment account in a new session:
ssh deploy@YOUR_VPS_IPThen run:
docker psYou should receive the Docker container list without a permission denied error. The list may be empty because you have not deployed anything yet. That is fine.
If the deployment user sees a Docker socket permission error, confirm that it belongs to the Docker group:
groups deployThe list should contain docker. If it does not, run the Docker group command again from your administrator account and reconnect before testing.
9. Create a Production Application Directory
Production applications should have a predictable location. A common deployment model uses /opt for application code rather than placing production projects inside somebody's personal home directory.
For a generic application, create the directory:
sudo mkdir -p /opt/myappGive ownership to the deploy user and check the result:
sudo chown -R deploy:deploy /opt/myapp
ls -ld /opt/myappLater, your repository can live inside this directory alongside its Docker Compose file, configuration and application source.
10. Run Final Verification
Switch to or reconnect as deploy, then verify the account, Docker, Compose and directory access.
whoami
docker ps
docker compose version
cd /opt/myapp
pwd
touch test-file
ls -la
rm test-fileIf all of these work, your basic deployment environment is ready.
Quick Checklist
11. Useful Docker Commands
You do not need many commands yet. These are enough to begin inspecting the server:
docker ps
docker ps -a
docker system df
docker statsLater, when your project has a Compose file, this command will show the services belonging to that project:
docker compose psIf you use UFW, remember that Docker-published container ports can interact with firewall rules in surprising ways. Keep databases private and expose only the web ports you actually intend to serve.
12. What Comes Next?
Your VPS can now run Docker workloads, but it does not yet know anything about your application.
We have intentionally not configured GitHub repository access, production source code, environment variables, databases, reverse proxy, domain, HTTPS, CI/CD or backups yet. Those deserve their own focused guides.
Continue the Ubuntu VPS Series
Also Coming