EpicMicrodev
Back to Blog
GUIDE · Linux & Servers

Install Docker & Docker Compose on Ubuntu for Production

Epic Microdev8 min read

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:

Internet
Domain / HTTPS
Reverse Proxy
Docker Compose
Application Services
Database / Redis / Other Services

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.

bash
ssh youradmin@YOUR_VPS_IP

If you configured a local SSH alias, use that instead:

bash
ssh myvps

Verify the current user:

bash
whoami

You 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.

bash
sudo apt update
sudo apt install -y ca-certificates curl

Create the directory Ubuntu will use for repository signing keys:

bash
sudo install -m 0755 -d /etc/apt/keyrings

Download Docker's official signing key and make it readable by the package manager:

bash
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

Add Docker's apt repository using the current Docker sources format:

bash
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
EOF

Then refresh the package index:

bash
sudo apt update

Ubuntu 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:

bash
sudo apt install -y \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-buildx-plugin \
  docker-compose-plugin

This 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:

bash
sudo systemctl enable docker
sudo systemctl start docker

Check the service status:

bash
sudo systemctl status docker

You should see Docker reported as running. Exit the status screen with q.

6. Verify Docker and Compose

Run Docker's test container:

bash
sudo docker run hello-world

Docker 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:

bash
docker compose version

You should receive version information rather than a command not found error. You can also confirm Docker itself:

bash
docker --version
Docker Engine works
Docker CLI works
Docker Compose works
containerd is installed
Buildx is installed

7. 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:

youradmin: server administration with sudo access
deploy: application deployment, Docker access and application directory ownership

Create the deploy account:

bash
sudo adduser deploy

Follow 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:

bash
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_keys

For stricter separation, generate and install a dedicated deployment SSH key instead of reusing the administrator key.

Add deploy to the Docker group:

bash
sudo usermod -aG docker deploy

Docker 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:

bash
ssh deploy@YOUR_VPS_IP

Then run:

bash
docker ps

You 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:

bash
groups deploy

The 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:

bash
sudo mkdir -p /opt/myapp

Give ownership to the deploy user and check the result:

bash
sudo chown -R deploy:deploy /opt/myapp
ls -ld /opt/myapp

Later, 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.

bash
whoami
docker ps
docker compose version
cd /opt/myapp
pwd
touch test-file
ls -la
rm test-file

If all of these work, your basic deployment environment is ready.

Quick Checklist

Docker repository configured
Docker signing key installed
docker-ce installed
docker-ce-cli installed
containerd installed
Buildx installed
Docker Compose plugin installed
Docker service running
Docker enabled at startup
hello-world container works
docker compose version works
deploy user created
deploy user is not unnecessarily given full sudo
deploy user belongs to Docker group
deploy user can run docker ps
/opt/myapp created
deploy owns application directory

11. Useful Docker Commands

You do not need many commands yet. These are enough to begin inspecting the server:

bash
docker ps
docker ps -a
docker system df
docker stats

Later, when your project has a Compose file, this command will show the services belonging to that project:

bash
docker compose ps

If 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.

Prepare and secure Ubuntu
Install Docker, Docker Compose and a deployment account
Connect VPS to GitHub and clone the application
Restore production environment and database
Run the production stack
Configure domain, Caddy and HTTPS
Add GitHub Actions CI/CD
Set up backups and maintenance

Continue the Ubuntu VPS Series

Previous Article

New Ubuntu VPS? 10 Things You Should Do First

Read article

Next Article

Deploy a Private GitHub Repository to an Ubuntu VPS

Read article

Also Coming

Caddy on Ubuntu: Reverse Proxy, Domain & Automatic HTTPS

Coming Soon