Fork of phusion/baseimage-docker
Current version was based on ubuntu:22.04
Table of contents
- Docker
- Docker-compose
- SSH service
- Container administration
- References
docker build -f image/Dockerfile1 -t viix:22.04 .
docker run -d --name new_container viix:22.04
docker run -d --name new_container -p 2222:22 viix:22.04
winpty docker exec -it new_container bash
docker stop $(docker ps -q)
docker-compose up -d --build
docker-compose down --volumes
service ssh status
Location, where all SSH keys are automatically generated by script 00_regen_ssh_host_keys.sh (if SSH enabled):
cd /etc/ssh
cat /etc/ssh/sshd_config
One of the ideas behind Docker is that containers should be stateless, easily restartable, and behave like a black box. However, you may occasionally encounter situations where you want to login to a container, or to run a command inside a container, for development, inspection and debugging purposes. This section describes how you can administer the container for those purposes.
Note: This section describes how to run a command insider a -new- container. To run a command inside an existing running container, see Running a command in an existing, running container.
Normally, when you want to create a new container in order to run a single command inside it, and immediately exit after the command exits, you invoke Docker like this:
docker run YOUR_IMAGE COMMAND ARGUMENTS...
However the downside of this approach is that the init system is not started. That is, while invoking COMMAND
, important daemons such as cron and syslog are not running. Also, orphaned child processes are not properly reaped, because COMMAND
is PID 1.
Baseimage-docker provides a facility to run a single one-shot command, while solving all of the aforementioned problems. Run a single command in the following manner:
docker run YOUR_IMAGE /sbin/my_init -- COMMAND ARGUMENTS ...
This will perform the following:
- Runs all system startup files, such as /etc/my_init.d/* and /etc/rc.local.
- Starts all runit services.
- Runs the specified command.
- When the specified command exits, stops all runit services.
For example:
$ docker run phusion/baseimage:<VERSION> /sbin/my_init -- ls
*** Running /etc/rc.local...
*** Booting runit daemon...
*** Runit started as PID 80
*** Running ls...
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
*** ls exited with exit code 0.
*** Shutting down runit daemon (PID 80)...
*** Killing all processes...
You may find that the default invocation is too noisy. Or perhaps you don't want to run the startup files. You can customize all this by passing arguments to my_init
. Invoke docker run YOUR_IMAGE /sbin/my_init --help
for more information.
The following example runs ls
without running the startup files and with less messages, while running all runit services:
$ docker run phusion/baseimage:<VERSION> /sbin/my_init --skip-startup-files --quiet -- ls
bin boot dev etc home image lib lib64 media mnt opt proc root run sbin selinux srv sys tmp usr var
There are two ways to run a command inside an existing, running container.
- Through the
docker exec
tool. This is builtin Docker tool, available since Docker 1.4. Internally, it uses Linux kernel system calls in order to execute a command within the context of a container. Learn more in Login to the container, or running a command inside it, viadocker exec
. - Through SSH. This approach requires running an SSH daemon inside the container, and requires you to setup SSH keys. Learn more in Login to the container, or running a command inside it, via SSH.
Both way have their own pros and cons, which you can learn in their respective subsections.
You can use SSH to login to any container that is based on baseimage-docker. You can also use it to run a command inside a running container.
Here's how it compares to using docker exec
to login to the container or to run a command inside it:
- Pros
- Does not require root privileges on the Docker host.
- Allows you to let users login to the container, without letting them login to the Docker host. However, this is not enabled by default because baseimage-docker does not expose the SSH server to the public Internet by default.
- Cons
- Requires setting up SSH keys. However, baseimage-docker makes this easy for many cases through a pregenerated, insecure key. Read on to learn more.
Baseimage-docker disables the SSH server by default. Add the following to your Dockerfile to enable it:
RUN rm -f /etc/service/sshd/down
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
# have to do that yourself. You may also comment out this instruction; the
# init system will auto-generate one during boot.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
Alternatively, to enable sshd only for a single instance of your container, create a folder with a startup script. The contents of that should be
### In myfolder/enable_ssh.sh (make sure this file is chmod +x):
#!/bin/sh
rm -f /etc/service/sshd/down
ssh-keygen -P "" -t dsa -f /etc/ssh/ssh_host_dsa_key
Then, you can start your container with
docker run -d -v `pwd`/myfolder:/etc/my_init.d my/dockerimage
This will initialize sshd on container boot. You can then access it with the insecure key as below, or using the methods to add a secure key. Further, you can publish the port to your machine with -p 2222:22 allowing you to ssh to 127.0.0.1:2222 instead of looking up the ip address of the container.
First, you must ensure that you have the right SSH keys installed inside the container. By default, no keys are installed, so nobody can login. For convenience reasons, we provide a pregenerated, insecure key (PuTTY format) that you can easily enable. However, please be aware that using this key is for convenience only. It does not provide any security because this key (both the public and the private side) is publicly available. In production environments, you should use your own keys.
You can temporarily enable the insecure key for one container only. This means that the insecure key is installed at container boot. If you docker stop
and docker start
the container, the insecure key will still be there, but if you use docker run
to start a new container then that container will not contain the insecure key.
Start a container with --enable-insecure-key
:
docker run YOUR_IMAGE /sbin/my_init --enable-insecure-key
Find out the ID of the container that you just ran:
docker ps
Once you have the ID, look for its IP address with:
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
Now that you have the IP address, you can use SSH to login to the container, or to execute a command inside it:
# Download the insecure private key
curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/services/sshd/keys/insecure_key
chmod 600 insecure_key
# Login to the container
ssh -i insecure_key root@<IP address>
# Running a command inside the container
ssh -i insecure_key root@<IP address> echo hello world
It is also possible to enable the insecure key in the image permanently. This is not generally recommended, but is suitable for e.g. temporary development or demo environments where security does not matter.
Edit your Dockerfile to install the insecure key permanently:
RUN /usr/sbin/enable_insecure_key
Instructions for logging into the container is the same as in section Using the insecure key for one container only.
Edit your Dockerfile to install an SSH public key:
## Install an SSH of your choice.
COPY your_key.pub /tmp/your_key.pub
RUN cat /tmp/your_key.pub >> /root/.ssh/authorized_keys && rm -f /tmp/your_key.pub
Then rebuild your image. Once you have that, start a container based on that image:
docker run your-image-name
Find out the ID of the container that you just ran:
docker ps
Once you have the ID, look for its IP address with:
docker inspect -f "{{ .NetworkSettings.IPAddress }}" <ID>
Now that you have the IP address, you can use SSH to login to the container, or to execute a command inside it:
# Login to the container
ssh -i /path-to/your_key root@<IP address>
# Running a command inside the container
ssh -i /path-to/your_key root@<IP address> echo hello world
Ubuntu is not designed to be run inside Docker. Its init system, Upstart, assumes that it's running on either real hardware or virtualized hardware, but not inside a Docker container. But inside a container you don't want a full system anyway, you want a minimal system. But configuring that minimal system for use within a container has many strange corner cases that are hard to get right if you are not intimately familiar with the Unix system model. This can cause a lot of strange problems.
Baseimage-docker gets everything right. The "Contents" section describes all the things that it modifies.
You can configure the stock ubuntu image yourself from your Dockerfile, so why bother using baseimage-docker?
Configuring the base system for Docker-friendliness is no easy task. As stated before, there are many corner cases. By the time that you've gotten all that right, you've reinvented baseimage-docker. Using baseimage-docker will save you from this effort.
- It sets up the base system correctly. Many people may not think so, but Unix has many corner cases caused by decades of cruft. Getting them wrong can result in very strange problems. This image does everything correctly. Learn more.
- It reduces the time needed to run docker build, allowing you to iterate your Dockerfile more quickly.
- It reduces download time during redeploys. Docker only needs to download the base image once: during the first deploy. On every subsequent deploys, only the changes you make on top of the base image are downloaded.
Baseimage-docker only contains essential components. Learn more about the rationale.
Ubuntu 22.04 LTS as base system.
- A correct init process learn more.
- Fixes APT incompatibilities with Docker.
- syslog-ng.
- The cron daemon.
- An optional SSH server (disabled by default), for those use cases where docker exec is inappropriate. Password and challenge-response authentication are disabled by default. Only key authentication is allowed.
- It allows an predefined key by default to make debugging easy. You should replace this ASAP. See instructions.
- Runit for service supervision and management.
-
Source: https://github.com/phusion/baseimage-docker/releases?page=3
-
Source: https://registry.hub.docker.com/r/phusion/baseimage/
-
Dockerfile.txt is from https://github.com/diixo/docker-sge/Dockerfile