| 195 | The following examples show how to create various Ubuntu containers from an Ubuntu host OS as a non root user. The steps will vary a bit on other host Operating Systems. |
| 196 | |
| 197 | The examples create a local user with sudo access using variables (USER, UID, GID) that can be specified when you build the image to make it easier to share files on your host when using a bind mount. |
| 198 | |
| 199 | We pass arguments via the 'docker build' command passing in your USER, UID, GID and the Dockerfile uses these to create an image with a user matching these args such that if you run a container with this image you can bind-mount directories from your host and have the same file ownership and permissions as the user on the host. |
| 200 | |
| 201 | We show an example of launching a container binding your home directory and a /tftpboot directory to take advantage of this. |
| 202 | |
| 203 | The docker-run '--it' option is a shortcut for '--interactive' and '--tty' which allocates a pseudo-TTY terminal and keeps STDIN open even if not attached. These options allow the bash process to start in the container, attaches the host OS console to the processes standard input/output/error, and allocates a text-only console. |
| 204 | |
| 205 | The docker-run '--rm' option automatically removes the container when it exits so that you don't accidentally leave a bunch of unused containers that allocate resources. If instead you wish to create a container that you can detach from and come back to later you can remove the '--rm' option and attach to it again later with the 'docker attach <containerid>' command after using 'docker container ls' to show available containers. |
| 206 | |
| 207 | The docker-run '--privileged' option will allow accessing host devices from the container in case you want to access a removable storage device for example. |
| 208 | |
| 209 | The docker-run '--hostname' option provides a custom hostname that helps you remember you are in a docker container. By default /etc/hostname will contain the container ID. Often the hostname is included in your prompt as is the case with Ubuntu so providing a custom hostname helps you keep track of what you are doing. |
| 210 | |
236 | | docker build --tag ubuntu-22.04 --build-arg USER=$USER --build-arg UID=$(id -u) --build-arg GID=$(id -g) ubuntu-focal/ |
237 | | }}} |
238 | | * the '--build-arg' options above are optional but show how you can use your host Linux OS user/group to replace the default ones specified in the DockerFile. This can be very useful if you mount a filesystem from your host OS into your container and want to share user permissions |
239 | | * building the 'image' is a one-time operation. You only need to repeat it if you change the DockerFile specifying the image |
240 | | * if wanted you can add additional 'RUN apt-get install -y <packages>' steps before the 'USER $USER' command (which switches the user from root to a non-root user, otherwise you would need to use sudo) to install additional packages so that you don't have to do that every time you create a new container from the image |
| 243 | docker build --tag ubuntu-focal --build-arg USER=$USER --build-arg UID=$(id -u) --build-arg GID=$(id -g) ubuntu-focal/ |
| 244 | }}} |
| 245 | |
| 251 | --hostname docker-focal \ |
| 252 | --name focal ubuntu-focal |
| 253 | }}} |
| 254 | |
| 255 | |
| 256 | === Ubuntu 22.04 Jammy container |
| 257 | 1. Create a docker 'image' based on Ubuntu 22.04: |
| 258 | - On a Linux host, docker images are created from a Dockerfile that provides details and commands used to build the image |
| 259 | {{{#!bash |
| 260 | mkdir ubuntu-jammy |
| 261 | cat << \EOF > ubuntu-jammy/Dockerfile |
| 262 | # from base image ubuntu 22.04 |
| 263 | FROM ubuntu:22.04 |
| 264 | |
| 265 | # Disable Prompt During Packages Installation |
| 266 | ARG DEBIAN_FRONTEND=noninteractive |
| 267 | |
| 268 | # update list of available packages |
| 269 | RUN apt-get update |
| 270 | |
| 271 | # add a non-root user |
| 272 | ARG USER=build |
| 273 | ARG UID=1000 |
| 274 | ARG GID=1000 |
| 275 | RUN groupadd -g $GID $USER && useradd -g $GID -m -s /bin/bash -u $UID $USER |
| 276 | |
| 277 | # and give that user permission to use sudo |
| 278 | RUN apt-get install -y sudo |
| 279 | RUN echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers |
| 280 | |
| 281 | # switch to this user |
| 282 | USER $USER |
| 283 | WORKDIR /home/$USER |
| 284 | EOF |
| 285 | }}} |
| 286 | - use the 'docker build' command to build the OS image passing in args for your USER, UID, GID |
| 287 | {{{#!bash |
| 288 | docker build --tag ubuntu-jammy --build-arg USER=$USER --build-arg UID=$(id -u) --build-arg GID=$(id -g) ubuntu-jammy/ |
| 289 | }}} |
| 290 | |
| 291 | 1. Create and start docker container |
| 292 | {{{#!bash |
| 293 | docker run --rm -it --privileged \ |
| 294 | --volume /home/$USER:/home/$USER \ |
| 295 | --volume /tftpboot/tftpboot \ |
| 296 | --hostname docker-jammy \ |
248 | | * the '--volume' options are optional but show how you can bind mount directories from your host OS to the container's OS. In this case we have mounted /tftpboot so we can copy files from the container to the hosts's tftpboot directory where a TFTP server may be running. We also mount your home director from the host OS to allow our host OS to get to source files we use |
249 | | * Note that once you 'run' a container it remains present even if you have detached from it meaning you can later re-attach to it |
250 | | * The '--it' option is a shortcut for '--interactive' and '--tty' which allocates a pseudo-TTY terminal and keeps STDIN open even if not attached. These options allow the bash process to start in the container, attaches the host OS console to the processes standard input/output/error, and allocates a text-only console. |
251 | | |
252 | | If you at some point exit your docker container you can attach to it again later with the 'docker attach <containerid>' command after using 'docker container ls' to show available containers. |
253 | | |
254 | | |
| 299 | |
| 300 | |
| 301 | === Ubuntu 24.04 Noble container |
| 302 | 1. Create a docker 'image' based on Ubuntu 24.04: |
| 303 | - On a Linux host, docker images are created from a Dockerfile that provides details and commands used to build the image |
| 304 | {{{#!bash |
| 305 | mkdir ubuntu-noble |
| 306 | cat << \EOF > ubuntu-noble/Dockerfile |
| 307 | # from base image ubuntu 24.04 |
| 308 | FROM ubuntu:24.04 |
| 309 | # Ubuntu 24.04 official docker image creates an 'ubuntu' user with uid/gid 1000 that we want to use here - remove it |
| 310 | RUN userdel -r ubuntu |
| 311 | |
| 312 | # Disable Prompt During Packages Installation |
| 313 | ARG DEBIAN_FRONTEND=noninteractive |
| 314 | |
| 315 | # update list of available packages |
| 316 | RUN apt-get update |
| 317 | |
| 318 | # add a non-root user |
| 319 | ARG USER=build |
| 320 | ARG UID=1000 |
| 321 | ARG GID=1000 |
| 322 | RUN groupadd -g $GID $USER && useradd -g $GID -m -s /bin/bash -u $UID $USER |
| 323 | |
| 324 | # and give that user permission to use sudo |
| 325 | RUN apt-get install -y sudo |
| 326 | RUN echo "$USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers |
| 327 | |
| 328 | # switch to this user |
| 329 | USER $USER |
| 330 | WORKDIR /home/$USER |
| 331 | EOF |
| 332 | }}} |
| 333 | - use the 'docker build' command to build the OS image passing in args for your USER, UID, GID |
| 334 | {{{#!bash |
| 335 | docker build --tag ubuntu-noble --build-arg USER=$USER --build-arg UID=$(id -u) --build-arg GID=$(id -g) ubuntu-noble/ |
| 336 | }}} |
| 337 | |
| 338 | 1. Create and start docker container |
| 339 | {{{#!bash |
| 340 | docker run --rm -it --privileged \ |
| 341 | --volume /home/$USER:/home/$USER \ |
| 342 | --volume /tftpboot/tftpboot \ |
| 343 | --hostname docker-noble \ |
| 344 | --name noble ubuntu-noble |
| 345 | }}} |
| 346 | |