---
# System prepended metadata

title: 用最 Simple 的方式建立 Docker Container（不需 DockerFile，可外部 SSH 連線，支援 Cuda 加速）

---

# 用最 Simple 的方式建立 Docker Container（不需 DockerFile，可外部 SSH 連線，支援 Cuda 加速）

## 查看本機現有 images

```bash
docker images
```
images 可用來快速建立某個已有系統的 Container 環境
有些是網路來的，也可以自己建立

## 從網路取得新 images

```bash
docker pull <img_name>:<version>
```

**可以選擇例如：**
* ubuntu:22.04
* pytorch/pytorch: https://hub.docker.com/r/pytorch/pytorch
* nvidia/cuda: https://hub.docker.com/r/nvidia/cuda

可以不先 pull，建立時如果在本機找不到檔案，docker 會自動 pull

## 查看現有 Containers

### 所有 Containers

```bash
docker ps -a
```

### 正在運行的 Containers

```bash
docker ps 
```

## 建立 container 範例（僅建立不啟動）

```bash=
docker create --name <name> \
    -p XXXX:22 -p xxxx:8080 \
    -i -t --gpus all \
    -v <host_path>:<container_path> \
    <img_name>:<version> \
    sh -c "/usr/sbin/sshd 2>/dev/null; bash"
```

目前應該會先嘗試用 ubuntu 22.04 並自己安裝需要套件進行訓練與測試
除非遇到他人程式相依性問題，才會去使用額外 cuda 版本之 image

⚠️**如果有一些功能不需要的話（例如 port mapping 或 sshd），可去除某些 Flags！！**

**Flags：**
* `-p`：Port mapping (you can change the settings on your own)
    * here we map container sshd 22 port to host XXXX **（方便外部連線）**
    * extra container port 8080 to host xxxx **（供其他自定義服務使用）**
    * 注意不要跟其他服務撞 port，可以 `netstat -ntlp` 先確認哪些已被佔用
* `-i`：interactive.  Keep STDIN open even if not attached
* `-t`：Allocate a pseudo-TTY
* `-v`：掛載 <host_path>` 到 container 中 `<container_path>`
* `--gpus`：如果要用 `nvidia-smi` 指令及相關 GPU 服務，必須有此 Flag，可選擇想啟用的 GPU 編號或是用 `all` 啟動全部

**（如果沒有 `-i` `-t` Container 會無法啟動並持續運行）**

**最後一行會 Overwrites Container 啟動時的指令：**
**（如果不寫，預設只啟動 bash 不會啟動 sshd，不需要的話可跳過**）
* 啟動 sshd 服務在背景，並將 stderr map 到 /dev/null（避免首次啟動報錯）
* 啟動 bash（Container 才會持續運行）

系統初始狀態沒有安裝 ssh-server 服務，需進入互動模式進行安裝設定。**（見下個章節）**

## 啟動 container

### 互動模式（進行初次設定等操作）
```bash
docker start -i -a <name>
```
* `-a`：Attach STDOUT/STDERR and forward signals
* `-i`：interactive

### 僅背景啟動（經設定後，可背景運行 ssh-server 服務）

```bash
docker start <name>
```

如果要在 Host 機連接此 Container 進行操作，可以使用：
```bash
docker attach <name>
```

## Configure SSH-Server（可以直接複製貼上）

**不需要的話可以跳過！**

**每一個步驟請參考註解中的說明和指示：**

```bash=
# installation
apt update
apt install -y net-tools openssh-server nano

# set password
passwd # this will prompt you to enter new password

# edit ssh_config
nano /etc/ssh/sshd_config
# **PLEASE MANUALLY MAKE THE FOLLOWING CHANGES!**
# 1. uncomment & edit to "PermitRootLogin yes"
# 2. uncomment & edit to "PasswordAuthentication yes"

# create essential directory
mkdir /run/sshd

# Stop Container
exit
```

## 儲存變更為新 Image

會保存先前安裝過的套件、修改過的設定、以及自訂的 container 啟動命令
```bash
docker commit <container_name> <new_image_name>:<version>
```
即可在本機 images 清單中查看新的 image，且下次可以使用此鏡像建立 container

### 範例
```bash
docker commit workspace ubuntu-sshd:22.04
```
下次建立 Container 只要執行：
```bash=
docker create --name sshd_workspace \
    -p XXXX:22 -p xxxx:8080 \
    -i -t --gpus all \
    -v /data/XXX:/data \
    ubuntu-sshd:22.04
```
新的 workspace 會依照先前的設定，自啟動 ssh-server 服務，並保留密碼等設定。

註：**也可以學習如何編寫 DockerFile，比直接 commit 整個 image 更省空間**

## 其他操作

### 停止 container

可以在 attached 狀態輸入 `exit` 指令，或是：
```bash
docker stop <container_name>
```

### 刪除 container

```bash
docker rm <container_name>
```

### 刪除 image

```bash
docker rmi <image_name>:version
```