# Installing Linux in Docker

This chapter is a guide to GNU/Linux development environment configuration. You are guided to install a GNU/Linux development environment. All operations after this chapter are done in this environment.

If you are new to GNU/Linux, and you encounter some troubles during the configuration, which are not mentioned in this document (such as "No such file or directory"), that is your fault. Go back to read this lecture note carefully. There is a truth saying: the machine is always right!

{% hint style="danger" %}
注意: 本章大部分内容只会给出简单的操作过程, 不负责解释这些操作相关的细节和原理. 如有需要请自行上网搜索.
{% endhint %}

## Foreword

{% hint style="info" %}
写在前面: 由于本课程是“操作系统”, 而不是“操作系统 (双语)”或者“Linux 操作系统”, 为了确保能够尽快开始配置实验环境, 你可以跳过本节和后两节的内容, 直接使用[已配置好的镜像](https://app.gitbook.com/s/-LnM_MK1Ma3MtweMDTEl/conf-linux/inst-tools#using-pre-configured-image)进行后续搭建.

甚至, 如果你的时间实在宝贵, 我们还为你提供了[已经配置完毕的实验环境](/2019/conf-env/from-source.md#foreword). 这套环境开箱即用, 你可以直接开始使用此环境, 参照教程的后续部分进行操作系统实验.

当然我们建议: 如果时间充裕, 还是请你跟随教程自行配置开发环境, 这样你可能能学到更多东西.
{% endhint %}

## Installing Docker

[Docker](https://www.docker.com) is an implementation of the lightweight virtualization technology. Virtual machines built by this technology is called "container". By using Docker, it is very easy to deploy GNU/Linux applications.

If you already have one copy of GNU/Linux distribution different from which we recommend, and you want to use your copy as the development environment, we still encourage you to install docker on your GNU/Linux distribution to use the same GNU/Linux distribution we recommend over docker to avoid issues brought by platform disparity. Refer to [Docker online Document](https://docs.docker.com) for more information about installing Docker for GNU/Linux. It is OK if you still insist on your GNU/Linux distribution. But if you encounter some troubles because of platform disparity, please search the Internet for trouble-shooting.

It is also OK to use traditional virtual machines, such as VMWare or VirtualBox, instead of Docker. If you decide to do this and you do not have a copy of GNU/Linux, please install Debian 9 distribution in the virtual machine. Also, please search the Internet for trouble-shooting if you have any problems about virtual machines.

{% hint style="danger" %}
保持同步: 如果你打算使用已有的 GNU/Linux 平台, 请确保它是 64 位版本.
{% endhint %}

Download Docker from [this](https://hub.docker.com/search/?type=edition\&offering=community) website according to your host operating system, then install Docker with default settings. Reboot the system if necessary. If your operating system can not meet the requirement of installing Docker, please upgrade your operating system. Do not install Docker Toolbox instead. It seems not very stable in Windows since it is based on VirtualBox.

## Preparing Dockerfile

`Dockerfile` is the configuration file used to build a Docker image. Now we are going to prepare a Dockerfile with proper content by using the terminal working environment.

* If your host is GNU/Linux or macOS, you can use the default terminal in the system.
* If your host is Windows, open `PowerShell`.

Type the following commands after the prompt, one command per line. Every command is issued by pressing the `Enter` key. The contents after a `#` is the comment about the command, and you do not need to type the comment.

```
mkdir mydocker     # create a directory with name "mydocker"
cd mydocker        # enter this directory
```

Now use the text editor in the host to new a file called `Dockerfile`.

* Windows: Type command `notepad Dockerfile` to open Notepad.
* macOS: Type command `open -e Dockerfile` to open TextEdit.
* GNU/Linux: Use your favourite editor to open Dockerfile.

Now copy the following contents into `Dockerfile`:

```bash
# setting base image
FROM debian

# Change APT sources
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian buster main contrib non-free" > /etc/apt/sources.list
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian buster-updates main contrib non-free" >> /etc/apt/sources.list
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free" >> /etc/apt/sources.list
RUN echo "deb http://mirrors.tuna.tsinghua.edu.cn/debian-security/ buster/updates main contrib non-free" >> /etc/apt/sources.list

RUN apt-get update

# Set the locale
RUN apt-get install -y locales
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
RUN dpkg-reconfigure --frontend=noninteractive locales
RUN update-locale LANG=en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

# new a directory for sshd to run
RUN mkdir -p /var/run/sshd
# installing ssh server
RUN apt-get install -y openssh-server

# installing sudo
RUN apt-get install -y sudo

# make ssh services use IPv4 to let X11 forwarding work correctly
RUN echo AddressFamily inet >> /etc/ssh/sshd_config

# defining user account imformation
ARG username=oslab
ARG userpasswd=oslab

# adding user
RUN useradd -ms /bin/bash $username && (echo $username:$userpasswd | chpasswd)

# adding user to sudo group
RUN adduser $username sudo

# setting running application
CMD /usr/sbin/sshd -D
```

We choose the Debian distribution as the base image, since it can be quite small. Change `username` and `userpasswd` above to your favourite account settings. Save the file and exit the editor.

For Windows user, `notepad` will append suffix `.txt` to the saved file. This is unexpected. Use the following command to rename the file.

```
mv Dockerfile.txt Dockerfile     # rename the file to remove the suffix in Windows
```

## Building Docker image

Keep the Internet conntected. Type the following command to build our image:

```
docker build -t oslab-image .
```

This command will build an image with a tag `oslab-image`, using the Dockerfile in the current directory (mydocker). In particular, if your host is GNU/Linux, all Docker commands should be executed with root privilege, or alternatively you can add your account to the group `docker` before executing any docker commands. If it is the first time you run this command, Docker will pull the base image `debian` from [Docker Hub](https://hub.docker.com/). This will cost several minutes to finish.

After the command above finished, type the following command to show Docker images:

```
docker images
```

This command will show information about all Docker images.

```
REPOSITORY           TAG          IMAGE ID          CREATED             SIZE
oslab-image          latest       7d9495d03763      4 minutes ago       210 MB
debian               latest       fb434121fc77      4 hours ago         100 MB
```

If you see a repository with name `oslab-image`, you are done with building image.

Now we can remove the directory mentioned above.

```
cd ..           # go back to the parent directory
rm -r mydocker  # remove the `mydocker` directory
```

## Creating Debian container

After building the image, now we can create a container. Type the following command:

```
docker create --name=oslab-vm -p 20022:22 --tmpfs /dev/shm:exec --privileged=true oslab-image
```

This command will create a container with the following property:

* the name of the container is `oslab-vm`
* the Docker image is `oslab-image`, which we just built
* the default SSH port (`22`) in the container is bound to port `20022` in the docker host
* the container will get extended privileges (for GDB to run)
* mount `/dev/shm` with an executable flag

If the above command fails because a container with the same name already exists, type the following command to remove the existing container:

```
docker rm oslab-vm
```

Then create the container again.

To see whether the container is created successfully, type the following command to show containers:

```
docker ps -a
```

This command will show information about all Docker containers. If you see a container with name `oslab-vm`, you are done with creating container.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ustb-os-lab.gitbook.io/2019/conf-linux/inst-linux.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
