{"id":478,"date":"2024-10-07T14:47:41","date_gmt":"2024-10-07T14:47:41","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=478"},"modified":"2024-10-07T14:47:41","modified_gmt":"2024-10-07T14:47:41","slug":"run-docker-containers-as-non-root-user","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=478","title":{"rendered":"How to Run Docker Containers as Non-Root User?"},"content":{"rendered":"<p>In this blog, I have explained detailed steps to run <a href=\"https:\/\/devopscube.com\/what-is-docker\/\" rel=\"noreferrer noopener\">Docker<\/a> containers as non-root user by creating a custom user in the Dockerfile.<\/p><h2 id=\"what-is-a-non-root-user\">What is a Non-Root User?<\/h2><p>A non-root user is a standard user with limited permissions on system resources. They have no privileges other than the permissions given to them.<\/p><p>For example, unlike a root user, a non-root user cannot create, modify, or delete files and folders in another user&#8217;s home directory once they have permission on their home directory.<\/p><p>By default, the non-root users cannot use <code>sudo<\/code> , but can be configured to use <code>sudo<\/code> for specific commands.<\/p><h2 id=\"running-applications-with-non-root-user\">Running Applications with Non-Root User<\/h2><p>Before we look at the hands-on example, let&#8217;s understand the requirements and configurations for running applications inside the container using a non-root user.<\/p><p>When we say applications, it could be Java, Node.js, Ruby, Python, etc<\/p><p>One key thing to remember is the non-root user <strong>should have access to the application code <\/strong>and related files. It is similar to running an application as a non-root user in a Linux system.<\/p><p>For example, let&#8217;s say you want to run a Java application in a Docker container and the Java application code and related configurations will be placed in the <code>\/app<\/code> directory.<\/p><p>In this case, the non-root user you create should have the necessary read\/write permissions to the&nbsp;<strong>app<\/strong>&nbsp;directly.<\/p><p>The non-root user will not have any other privileged access to system-related files unless you specifically add permissions.<\/p><p>Now that we understand the basics, let&#8217;s look at a practical hands-on example of creating a Docker image with a non-root user.<\/p><h2 id=\"create-a-docker-image-with-a-non-root-user\">Create a Docker Image with a Non-Root User<\/h2><p>To demonstrate non-root users, we will create a Nginx <a href=\"https:\/\/devopscube.com\/build-docker-image\/\" rel=\"noreferrer noopener\">Docker image<\/a> from scratch.<\/p><p>We will <a href=\"https:\/\/devopscube.com\/create-dockerfile-using-docker-init\/\">create a Dockerfile <\/a>with a custom non-root user and add the necessary permissions for that user to run the Nginx service in the container.<\/p><p>Create a <code>Dockerfile<\/code> and copy the below Dockerfile content<\/p><pre><code>FROM nginx:alpine\n\nRUN addgroup -g 1001 -S nginxgroup &amp;&amp; adduser -u 1001 -S -G nginxgroup nginxuser\n\nRUN mkdir -p \/var\/run\/nginx \/var\/cache\/nginx\/client_temp \/var\/cache\/nginx\/proxy_temp \/var\/cache\/nginx\/fastcgi_temp \/var\/cache\/nginx\/scgi_temp \/var\/cache\/nginx\/uwsgi_temp \\\n    &amp;&amp; chown -R nginxuser:nginxgroup \/run \/var\/cache\/nginx \/var\/run\/nginx \/var\/log\/nginx \/etc\/nginx \/usr\/share\/nginx\/html\n\nRUN sed -i 's\/listen       80;\/listen       8080;\/g' \/etc\/nginx\/conf.d\/default.conf\nRUN sed -i 's\/\\\/var\\\/run\\\/nginx.pid\/\\\/var\\\/run\\\/nginx\\\/nginx.pid\/g' \/etc\/nginx\/nginx.conf\n\nUSER nginxuser\n\nEXPOSE 8080\n\nCMD [\"nginx\", \"-g\", \"daemon off;\"]<\/code><\/pre><p>Let&#8217;s understand this Dockerfile and the key configurations involved in creating a non-root user.<\/p>\n<!--kg-card-begin: html-->\n<ol class=\"wp-block-list is-style-cnvs-list-styled\">\n<li>This Dockerfile uses <strong>nginx<\/strong> as the base image.<\/li>\n\n\n<li>It creates a group <code>nginxgroup<\/code> with GID <strong><code>1001<\/code><\/strong> and a user <code>nginxuser<\/code> with UID <strong><code>1001<\/code><\/strong> and give the non-root user ownership of Nginx directories. Creating user and group with IDs is particularly useful when you run this image on <a href=\"https:\/\/devopscube.com\/kubernetes-tutorials-beginners\/\" data-type=\"post\" data-id=\"1426\">Kubernetes<\/a>. By explicitly setting the UID and GID in the Docker image, you can align these IDs with the <code><strong>securityContext<\/strong><\/code> settings in Kubernetes.<\/li>\n\n\n<li>Then, it creates the required temporary directories for Nginx and assigns them to the non-root user so that Nginx can write its data on the required directories.<\/li>\n\n\n<li>For example, <!--kg-card-begin: html--><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">the <strong><code>\/var\/cache\/nginx\/client_temp<\/code><\/strong>&nbsp;directory stores<\/span><!--kg-card-end: html--> temporary HTTP request data sent and received by Nginx.<strong> <code>\/var\/run\/nginx<\/code> <\/strong>will hold the PID created by Nignx during its startup (explained in step 6) .<\/li>\n\n\n<li>The SED command changes Nginx to listen on port <strong><code>8080<\/code><\/strong> because the ports below <strong><code>1024<\/code><\/strong> are <strong>privileged ports<\/strong>, which means only users with root permission can use them by default. <\/li>\n\n\n<li>During startup, Nginx writes its PID to <code><strong>\/var\/run<\/strong> <\/code>directory by default. <!--kg-card-begin: html--><span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">The second SED command chan<\/span><!--kg-card-end: html-->ges the PID file location to&nbsp;<strong><code>\/var\/run\/nginx<\/code><\/strong>&nbsp;because the non-root user has no permission on the<strong><code>\/var\/run<\/code><\/strong>&nbsp;directory. By creating and changing <strong><code>\/var\/run\/nginx<\/code><\/strong> directory permission to a non-root user, Nginx can save the PID file in it.<\/li>\n\n\n<li>Then, it switches the user to a non-root user <code><strong>nginxuser<\/strong><\/code> because if we don&#8217;t switch to the non-user, it will run as a root user by default.<\/li>\n\n\n<li>And it exposes port <code><strong>8080<\/strong><\/code> for external access.<\/li>\n\n\n<li>Finally, the&nbsp;<code>CMD<\/code>&nbsp;command tells Docker to start Nginx in the foreground. It&nbsp;<code>daemon off<\/code> keeps Nginx running and makes sure it doesn\u2019t go into the background, which would cause the container to stop.<\/li>\n<\/ol>\n<!--kg-card-end: html-->\n<p>Now, use the following command to build the Docker image.<\/p><pre><code>docker build -t nginx-non-root:1.0.0 .<\/code><\/pre><blockquote><strong>Note:<\/strong> Assigning a specific ID to user and group is typically helpful if you want to run this container in Kubernetes as non root user using <strong><code>securityContext<\/code><\/strong>.<br><br>Also, there are ways like setcap to make use of <strong>privileged<\/strong> ports by non-root users by assigning the <code>CAP_NET_BIND_SERVICE<\/code> capability to an executable, but it is not recomended due to security concerns.<\/blockquote><h2 id=\"run-docker-container-as-non-root-user\">Run Docker Container as non-root User<\/h2><p>Now that the image is built, we will run the container and test it to see if it is running as a non-user user.<\/p><p>Use the below command to run the Docker image in a container.<\/p><pre><code>docker run -d -p 8080:8080 nginx-non-root:1.0.0<\/code><\/pre><p>Run the following command to check if the container is running<\/p><pre><code>docker ps<\/code><\/pre><p>If your container is running, check the current user using the <strong><code>docker inspect<\/code><\/strong> command<\/p><pre><code>docker inspect -f '{{.Config.User}}' f5510bccfd39<\/code><\/pre><p>Replace <code>f5510bccfd39<\/code> with your Docker container ID.<\/p><p>This command will show you the current user of the container<\/p><figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-22-13.png\" class=\"kg-image\" alt=\"checking the current user using docker inspect command\" loading=\"lazy\" width=\"472\" height=\"195\"><\/figure><p>Or you can also use the <strong><code>exec<\/code><\/strong> command to access the shell of the container<\/p><pre><code>docker exec -it f5510bccfd39<\/code><\/pre><p>Then use the <strong><code>whoami<\/code><\/strong> command to check the current user as shown below<\/p><figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-18-18.png\" class=\"kg-image\" alt=\"checking the current user using whoami command\" loading=\"lazy\" width=\"361\" height=\"235\"><\/figure><p>You can see the container is running as a non-root user <strong><code>nginxuser<\/code><\/strong><\/p><p>Now, If you want to <strong>run the non-root container as a root user<\/strong>, run the following command<\/p><p>For this, we will run the Docker image in a container in interactive mode<\/p><pre><code>docker run -u 0 -it nginx-non-root:1.0.0 \/bin\/sh<\/code><\/pre><p>The <strong><code>-u 0<\/code><\/strong> option tells the container to run as the root user, <strong><code>0<\/code> is the UID of the root user<\/strong>.<\/p><figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-19-11.png\" class=\"kg-image\" alt=\"checking the current user\" loading=\"lazy\" width=\"450\" height=\"210\"><\/figure><blockquote><strong>UID 0<\/strong> (User ID 0) is reserved for the <strong>root user<\/strong>, who is the superuser or administrator with full access to all commands and files on the system<\/blockquote><h2 id=\"conclusion\">Conclusion<\/h2><p>In this blog, you have learned about non-root user and how to create a non-root user for an application.<\/p><p>This is particularly useful when using these image to run a <a href=\"https:\/\/devopscube.com\/kubernetes-pod\/\">Kubernetes pod<\/a>.<\/p><p>If you are using Kunernetes and you wan to run Pods as non root users, you can specify the user used in the Dockerfile under <strong><code>securityContext<\/code><\/strong> <strong><code>runAsUser<\/code><\/strong> parameter.<\/p><p>We have published a detailed guide on running <a href=\"https:\/\/devopscube.com\/run-kubernetes-pod-as-non-root-user\/\" rel=\"noreferrer noopener\">Kubernetes Pods as Non-Root User.<\/a><\/p>\n<hr><p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/run-docker-containers-as-non-root-user\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to Run Docker Containers as Non-Root User? \u2014 DevOpsCube<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/run-docker-containers-as-non-root-user\/<\/p>\n","protected":false},"author":1,"featured_media":479,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-478","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/478","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=478"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/478\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/479"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=478"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=478"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=478"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}