{"id":1043,"date":"2026-05-22T13:08:48","date_gmt":"2026-05-22T13:08:48","guid":{"rendered":"https:\/\/www.freethought.uk\/help\/installing-docker-via-the-command-line-on-a-ultra-cloud-server\/"},"modified":"2026-05-22T13:08:49","modified_gmt":"2026-05-22T13:08:49","slug":"installing-docker-via-the-command-line-on-a-ultra-cloud-server","status":"publish","type":"post","link":"https:\/\/www.freethought.uk\/help\/installing-docker-via-the-command-line-on-a-ultra-cloud-server\/","title":{"rendered":"Installing Docker via the command line on a ULTRA Cloud server"},"content":{"rendered":"\n<p>This guide covers installing Docker Community Edition (Docker CE) on a CentOS or RHEL 8 based ULTRA Cloud Panel server, enabling the service, and configuring a Scout site to proxy to a Docker container. It also covers granting a site user the ability to manage Docker with <code>sudo<\/code>.<\/p>\n\n\n\n<p>You will need root (or <code>sudo<\/code>) access to the server to install packages. The commands below assume a CentOS 8 \/ RHEL 8 system using <code>dnf<\/code>. Adjust accordingly for other distributions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Install the prerequisites<\/h2>\n\n\n\n<p>Make sure <code>yum-utils<\/code> is installed. It provides <code>dnf config-manager<\/code>, which we use to add the Docker repository.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dnf install -y yum-utils<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Add the official Docker CE repository<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>dnf config-manager --add-repo https:\/\/download.docker.com\/linux\/centos\/docker-ce.repo<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Install Docker CE and the Compose plugin<\/h2>\n\n\n\n<p>Install the Docker engine, CLI, containerd runtime and the Compose v2 plugin in one go:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin<\/code><\/pre>\n\n\n\n<p>Accept the prompts to install the packages and to import the Docker GPG key when asked.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Enable and start the Docker service<\/h2>\n\n\n\n<p>Enable Docker so it starts automatically on boot, and start it immediately:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl enable --now docker<\/code><\/pre>\n\n\n\n<p>You can confirm the service is running with <code>systemctl status docker<\/code> and that the CLI works with <code>docker ps<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Allow a site user to manage Docker via sudo<\/h2>\n\n\n\n<p>Scout site users do not have root, but you can grant a specific user the ability to run <code>docker<\/code> commands via <code>sudo<\/code> without a password. Edit the sudoers file safely with <code>visudo<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>visudo<\/code><\/pre>\n\n\n\n<p>Add a line in the form below, replacing <code>siteuser<\/code> with the actual Scout site username:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>siteuser ALL=(ALL) NOPASSWD: \/usr\/bin\/docker<\/code><\/pre>\n\n\n\n<p>The site user can now run Docker commands using <code>sudo<\/code>, for example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo docker ps\nsudo docker ps -a --format \"table {{.Names}}\\t{{.Status}}\\t{{.RunningFor}}\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Build and run a container<\/h2>\n\n\n\n<p>From the directory containing your application&#8217;s <code>Dockerfile<\/code>, build an image with a meaningful tag:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker build -t myapp:production .<\/code><\/pre>\n\n\n\n<p>Then run the container, mapping a host port to the container&#8217;s listening port. The example below maps host port <code>8080<\/code> to container port <code>9001<\/code>, mounts two directories for persistent data, sets <code>NODE_ENV=production<\/code>, and uses a restart policy of <code>unless-stopped<\/code> so the container is brought back up automatically after a server reboot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker run -dp 8080:9001 \\\n  -v \/home\/siteuser\/site\/public_html\/client\/reports:\/app\/client\/reports \\\n  -v \/home\/siteuser\/site\/public_html\/server\/data:\/app\/server\/data \\\n  -e NODE_ENV=production \\\n  --restart unless-stopped \\\n  --name myapp-production \\\n  myapp:production<\/code><\/pre>\n\n\n\n<p>The <code>--restart unless-stopped<\/code> policy ensures the container restarts automatically when the Docker service or the server itself is restarted, unless you explicitly stop it.<\/p>\n\n\n\n<p>You can confirm the policy on a running container with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker inspect myapp-production --format '{{.HostConfig.RestartPolicy.Name}}'<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Configure the Scout site to proxy to the container<\/h2>\n\n\n\n<p>Once your container is running and listening on a host port (<code>8080<\/code> in the example above), point the ULTRA Cloud Panel site at it. In the Scout control panel, open the site&#8217;s <strong>Application settings<\/strong> and:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set <strong>Application<\/strong> to <strong>Proxy<\/strong>.<\/li>\n\n\n\n<li>In <strong>Proxy address<\/strong>, enter the full URL including protocol and port, for example <code>http:\/\/127.0.0.1:8080<\/code>.<\/li>\n\n\n\n<li>Click <strong>Update<\/strong> to save.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/kb.freethought.group\/wp-content\/uploads\/2026\/05\/scout-application-proxy-settings.jpg\" alt=\"Scout Application settings dialog with Application set to Proxy and Proxy address http:\/\/127.0.0.1:8080\" class=\"wp-image-5239\"\/><figcaption class=\"wp-element-caption\">Pointing a Scout site at a Docker container by configuring the Application as a Proxy.<\/figcaption><\/figure>\n\n\n\n<p>Scout will then forward all requests for the site through to the container. Test the site to confirm everything is working as expected; you can use a local <code>hosts<\/code> file entry to verify the response before changing public DNS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Useful day-to-day Docker commands<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># List running containers\ndocker ps\n\n# List all containers (including stopped)\ndocker ps -a\n\n# View logs for a container\ndocker logs --tail 200 -f myapp-production\n\n# Restart, stop, start a container\ndocker restart myapp-production\ndocker stop myapp-production\ndocker start myapp-production\n\n# Remove a stopped container\ndocker rm myapp-production\n\n# Remove an image\ndocker rmi myapp:production<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Related guide<\/h2>\n\n\n\n<p>If your application is a plain Node.js app rather than a Dockerised one, you may not need Docker at all. See our companion guide on installing Node.js on a ULTRA Cloud Panel server.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Step-by-step guide to installing Docker CE via the CLI on a CentOS\/RHEL 8 Scout server, allowing a site user to manage Docker with sudo, and proxying a Scout site to a Docker container.<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,17],"tags":[],"class_list":["post-1043","post","type-post","status-publish","format-standard","hentry","category-our-control-panel","category-advanced-techniques"],"_links":{"self":[{"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/posts\/1043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/comments?post=1043"}],"version-history":[{"count":0,"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/posts\/1043\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/media?parent=1043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/categories?post=1043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freethought.uk\/help\/wp-json\/wp\/v2\/tags?post=1043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}