###### tags: `Plus` `Docker` # Docker 學習筆記 ```yaml docker info #版本號 docker image #顯示掛載鏡像 #-a 列出local #-q 僅列出image id #--digests 顯示鏡像摘要訊息(sha256) #--no-trunc 顯示完整鏡像 docker search 鏡像名稱 #-s 顯示評價星數大於該值之鏡像 #--no-trunc 顯示完整鏡像 #--automated 只列出具備Automated Build功能之鏡像 docker pull 下載鏡像 docker rmi 刪除鏡像1 刪除鏡像2 ... -f 強制刪除 docker rmi -f $(docker images -qa) #刪除全部images docker run [OPTIONS] 鏡像名稱或ID #-i 設置容器使用終端溝通(pseudo-tty) #-t 為容器開啟cmd模式(STDIN) #--name 為容器命名 #-P 隨機Port #-d 背景運行下如果無任何進程執行則自動關閉 #Ctrl+P+Q跳出容器終端 docker ps #列出現在運行容器 #-a 查詢之前執行的容器 #-l 查詢最後執行的容器 #-n 查詢最後執行前n個容器 #-q 容器編號 docker start docker stop docker kill #強制關閉容器 docker rm #關閉容器 docker logs -ft --tail 10 容器ID #顯示執行時間log,最後10個訊息 docker logs --since="2016-07-01" #顯示執行時間log,由2016-07-01到現在之log docker top 容器ID #顯示該容器正在process docker inspect 容器ID #查看容器DockerFile設定檔 docker attach 容器ID #進入容器終端 docker exec -t 容器ID 命令... #讓該容器執行該命令 docker exec -it 容器ID 命令... #讓該容器執行該命令後並進入終端 docker cp 容器ID:容器檔案路徑 主機檔案路徑 #複製容器內的檔案到主機上 docker cp 主機檔案路徑 容器ID:容器檔案路徑 #複製主機上的檔案到容器內 docker images commit #上傳成為新的鏡像 docker run -i 容器名稱 /bin/bash #執行容器後並進入命令/bin/bash(將會覆蓋設定檔CMD的指令) docker run -it -p 80:8888 --net=host #容器內的 8888 連接埠,映射到主機上的 80 連接埠,並且使用'host'虛擬網卡 docker run -it -v /主機共享目錄:/容器上的目錄 鏡像名稱--privileged=true #將主機內目錄與容器內目錄共享 --privileged=true 開啟docker 防火牆權限 docker run -it -v /主機共享目錄:/容器上的目錄:ro 鏡像名稱 #將主機內目錄與容器內目錄共享但限讀 docker run -it --volumes-from 容器名稱 #將新容器繼承舊容器之volume docker run --rm --volumes-from storage -v $(pwd):/容器上的目錄 容器名稱 #將容器掛載volume於主機現有目錄下,並於容器關閉後刪除該volume docker build -f 鏡像設定檔目錄 -t 鏡像倉庫目錄 ifconfig #可查看docker0~9網卡區域ip docker network #查看該機docker虛擬網卡設定 docker container prune #將刪除所有停止的容器,並且應在所有平臺上以相同的方式工作。 docker system prune -a #清理磁碟,刪除關閉的容器、無用的資料卷和網路,以及dangling映象(即無tag的映象)。 ``` # 安裝Docker與Docker-compose ### CentOS: ```bash sudo yum remove docker docker-common container-selinux docker-selinux docker-engine sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo ##添加yum源 sudo yum clean all ##推荐先清空索引,特别是新版本docker需要换成老版本docker的时候 sudo yum makecache fast yum list docker-ce --showduplicates | sort -r ##查看下自己能安装的版本都有哪些 sudo yum install -y docker-ce-18.09.9-3.el7 ##此处也可以安装指定版本的docker.... sudo yum install docker-ce ##不指定版本,安装最新版本的docker sudo groupadd docker sudo gpasswd -a $USER docker #將user加入可執行docker權限 newgrp docker sudo systemctl restart docker sudo systemctl enable docker #设置开机启动 docker info ##验证是否安装成功 curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose docker-compose --version ``` ### Ubuntu: ```bash sudo apt-get update sudo apt-get install apt-transport-https ca-certificates curl software-properties-common wget https://download.docker.com/linux/ubuntu/gpg sudo apt-key add gpg rm gpg sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" sudo apt-get install docker-ce sudo gpasswd -a ${USER} docker sudo usermod -aG docker $USER #需要登出後才能使用 docker version #docker-compose sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --version ``` # 什麼是Dockerfile ? * 是一個文字檔,由一行一行的指令所組成,用來描述這個映像檔應該長成怎麼樣 * 利用Dockerfile可以建構/客製化出自己獨一無二的映像檔 * 由於Dockerfile中可以清楚的知道映像檔的組成,因此,在安全性上會有所提升 * 因為是純文字檔,所以檔案很小、很容易分享 ## Dockerfile 的組成 基本上Dockerfile是由一行一行的指令列所組成,一行指令對Image來說就是一層的資料層(Layer),一個Image就是靠這樣一層一層的資料累加上去,最後才編譯出自己想要的映像檔,就像蓋房子一樣。 常見Dockerfile內容中的指令如下: ## 開頭代表註解 文件中可使用#符號來進行註解。 ## FROM 基底映像檔,必需是「第一個」指令行,指定這個映像檔要以哪一個Image為基底來建構,格式為 ==FROM <image>== 或 ==FROM <image>:<tag>==,範例如下: ```dockerfile FROM ubuntu:15.04 或 FROM ubuntu ``` ## MAINTAINER 映像檔維護者,把它想成是作者即可,格式為 ==MAINTAINER <name>== ,範例如下: ```dockerfile MAINTAINER John 或 MAINTAINER john@myemail.com 或 MAINTAINER John john@myemail.com ``` ## LABEL 設定映像檔的Metadata資訊,例如:作者、EMail、映像檔的說明等,格式為: ==LABEL <key>=<value> <key>=<value> <key>=<value> …== 簡單的來說就是以Key、Value來組成,它可以一行一組,也可以把全部合在一行撰寫,若多組合在一行,則每一組設定中間用空白鍵隔開即可,範例如下: ```dockerfile LABEL description="這是LABEL的範例" version="1.0" owner="靖技場" ``` 和MAINTAINER相比,建議使用LABEL來設定會比較方便,另外,如果要查詢LABEL的資訊,則可以下 ``docker inspect`` 來查詢 ## RUN 執行指定的指令,每加一個RUN,就會在基底映像層加上一層資料層,以此類推,一層一層的建構起我們最後想要的映像檔,例如我們可以利用RUN來安裝套件,其格式分為二種: 1. ==RUN <command>==:以shell的形式執行,Linux的預設是/bin/sh -c,而Windows上的預設環境則是cmd /S /C 2. `RUN ["executable", "param1", "param2"]`:以exec的形式執行指令,例如Linux上不想用預設的shell執行指令,那麼就可以透過 `RUN ["/bin/bash", "-c", "echo hello"]` 指定想要的shell shell形式與exec形式有什麼不同呢?官方有提到: ``` Unlike the shell form, the exec form does not invoke a command shell. This means that normal shell processing does not happen. For example, RUN [ "echo", "$HOME" ] will not do variable substitution on $HOME ``` 意思是說exec執行的方式不會使用command shell,所以執行 `RUN [ "echo", "$HOME" ]` 這樣的指令列, `$HOME` 這個變數是不會被替代(填入值)的,也就是直接輸出「`$HOME`」,但如果你想要有Shell處理的功能,則可以自行指定shell來達成:``RUN [ "sh", "-c", "echo $HOME" ]`` 在使用RUN指令時,有以下注意要點: 如果想要執行的指令很長,可以利用\符號來換行,比較容易閱讀 使用exec形式執行時,必需使用JSON array的格式,因此,請使用雙引號 每一個RUN就會新增一層資料層,為了減少不必要的資料層,可以利用&&來串連多個命令 簡單的RUN指令範例如下: ``` # install packages, only for demo RUN mkdir -p /home/demo/docker RUN ["apt-get", "install", "python3"] RUN apt-get update && apt-get install -y --force-yes apache2 \ firefox \ php5 ``` ## CMD 設定映像檔啟動為Container時預設要執行的指令,其指令共支援三種格式: 1. ==CMD ["executable","param1″,"param2″]== :exec形式,官方推薦此種方式 2. ``CMD ["param1″,"param2"]`` :適用於有定義ENTRYPOINT指令的時候,CMD中的參數會做為ENTRYPOINT的預設參數 3. ``CMD command param1 param2`` :會以shell的形式執行,預設是在「/bin/sh -c」下執行,適合在需要互動的指令時使用CMD的注意事項: Dockerfile中只能有一行CMD,若有多行CMD,則只有最後一行會生效 若在建立Container時有帶執行的命令,則CMD的指令會被蓋掉,例如:執行 ``docker run <image id>`` 時,CMD所定義的指令會被執行,但當執行 ``docker run <image id> bash`` 時,Container就會執行bash,而原本CMD中定義的值就會覆蓋 CMD範例如下: ```dockerfile CMD echo "This is a test." | wc - CMD ["/usr/bin/wc","--help"] CMD [ "sh", "-c", "echo $HOME" ] #作為ENTRYPOINT的參數使用 CMD ["Hello"] ``` ## ENTRYPOINT 和CMD一樣,用來設定映像檔啟動Container時要執行的指令,但不同的是,ENTRYPOINT一定會被執行,而不會有像CMD覆蓋的情況發生,支援二種格式: ``ENTRYPOINT ["executable", "param1", "param2"]``:exec形式,官方推薦此種方式 ``ENTRYPOINT command param1 param2:shell`` 的形式 使用ENTRYPOINT的注意事項: Dockerfile中只能有一行ENTRYPOINT,若有多行ENTRYPOINT,則只有最後一行會生效 若在建立Container時有帶執行的命令,ENTRYPOINT的指令不會被覆蓋,也就是一定會執行 如果想要覆蓋ENTRYPOINT的預設值,則在啟動Container時,可以加上「–entrypoint」的參數,例如:docker run –entrypoint 舉個實例,來看看ENTRYPOINT與CMD的關係,假設Dockerfile中的定義如下: ``` ENTRYPOINT ["/bin/echo", "Hello"] CMD ["World"] ``` 如果是使用 ``docker run -it <image>`` 來啟動Container,那麼輸出的結果為「Hello World」,但如果是用 ``docker run -it <image> Docker`` 來啟動,則輸出結果會變成「Hello Docker」,因為CMD的值被覆蓋掉了 ## COPY 複製本地端的檔案/目錄到映像檔的指定位置中,其格式為: * ``COPY [–chown=<user>:<group>] <src>… <dest>`` * ``COPY [–chown=<user>:<group>] ["<src>",… "<dest>"]`` 使用COPY的注意事項: 指令的來源位置可以多個 如果目的位置是目錄的話,記得最後要以/結尾,例如:/mypath/ 目的位置可以是絕對路徑或者相對於WORKDIR定義值的相對路徑 若目的位置不存在,會自動建立 COPY的範例如下: * ``COPY file1.txt file2.js file3.json ./`` * ``COPY ["file1.txt", "file2.js", "file3.json" "./"]`` ## ADD 和COPY一樣,可將本地端的檔案/目錄加到映像檔的指定位置內,其格式為: * ``ADD [–chown=<user>:<group>] <src>… <dest>`` * ``ADD [–chown=<user>:<group>] ["<src>",… "<dest>"]`` 雖然ADD和CMD功能類似,但有二點最大的不同: ADD的來源路徑支援URL,也就是說可以加入遠端的檔案,COPY則不支援URL 若來源檔案是壓縮檔(副檔名為gzip、bzip2、xz), 則使用ADD加入檔案時會自動解壓縮,而COPY不會 ADD的範例如下: ```dockerfile ADD file1.txt file2.js file3.json ./ # ENV_DEMO_VALUE 是用ENV指令所設定的環境變數 ADD https://www.google.com/demo.gzip $ENV_DEMO_VALUE ``` 除非你有自動解壓的需求,不然一般建議會使用「COPY」來加入檔案 ## EXPOSE 宣告在映像檔中預設要使用(對外)的連接埠,格式如下: * ``EXPOSE <port> [<port>/<protocol>…]`` EXPOSE預設的協定是TCP,但如果不是要TCP的話,可以自行指定,範例如下: ```dockerfile EXPOSE 80/tcp EXPOSE 80/udp ``` 使用EXPOSE所定義的連接埠並不會自動的啟用,而只是做提示的作用而已,要將連接埠啟用需要在執行docker run時,搭配-p或-P的參數來啟用。 小寫的-p可以自行指定與主機關聯的連接埠,例如: ``` docker run -p 80:80/tcp -p 80:80/udp demo ``` 大寫的-P則會啟用所有EXPOSE所定義的連接埠,並動態(隨機)的關聯到主機的連接埠,例如:EXPOSE 80 可能隨機關聯到主機的 45123 連接埠,其範例如下: ``` docker run -P demo ``` ## ENV 設定環境變數,支援二種格式: 1. ``ENV <key> <value>``:Key後面的第一個空白鍵後會視為Value 2. ``ENV <key>=<value> …``:用等於符號來定義,每一組中間以空白鍵隔開,我個人比較喜歡這種形式,不容易搞混 ENV範例如下: ```dockerfile ENV demoPATH="/var/log" demoVer="1.0" # 設置「/tmp/test.txt」給demoFile變數 ENV demoFile /tmp/test.txt # 使用環境變數的例子,有沒有用大括號都可以 COPY debug.log ${demoPATH} ADD $demoFile /foo ``` 使用ENV設置環境變數後,在Dockerfile中其他的指令就可以利用,之後在建起來的Container裡也可以使用該變數 ## VOLUME 建立本機或來自其他容器的掛載點,指令格式如下: * ``VOLUME ["/data"]`` VOLUME的值可以是JSON的Array格式,也可以是純文字,例如下以範例: ```dockerfile VOLUME ["/var/log/"] 或 VOLUME ["/demo1","/demo2"] 或 VOLUME /var/log 或 VOLUME /var/log /var/db ``` 要特別注意的是使用VOLUME來定義掛載點時,是無法指定本機對應的目錄的,對應到哪個目錄是自動產生,我們可以透過docker inspect來查詢目錄資訊 ## WORKDIR 設定工作目錄,其格式如下: * ``WORKDIR /path/to/workdir`` 當設定WORKDIR後,Dockerfile中的RUN、CMD、ENTRYPOINT、COPY、ADD等指令就會在該工作目錄下執行,以下是官方的示範: ```dockerfile WORKDIR /a WORKDIR b WORKDIR c RUN pwd ``` 在上面的範例中,`pwd`最後會在 `/a/b/c` 目錄下執行,如果目錄不存在,系統會幫忙自動建立 ## USER 指定運行Container時的用戶名稱或UID,其格式如下: ```dockerfile USER <user>[:<group>] USER <UID>[:<gid>] ``` 在定義了USER後,則Dockerfile中的RUN、CMD、ENTRYPOINT等指令便會以USER指定的用戶來執行,前提條件是該用戶必需是已存在的,否則指定會失敗,範例如下: ```dockerfile RUN groupadd -r tester && useradd -r -g tester tester # 指定用戶名稱 USER tester # 或使用UID來指定 USER 1000 ``` ## ARG 設定在建置映像檔時可傳入的參數,即定義變數名稱以及變數的預設值,其格式為: * ``ARG <name>[=<default value>]`` ARG和ENV的功能類似,都可以設定變數,但是ARG設定的值是供建置映像檔時使用(搭配docker build指令),在Container中是無法使用這些變數的,相反地,ENV的值則可以在Container中存取,例如ARG的定義如下: ```dockerfile ARG Param1 ARG Param2=somevalue ``` 建構映像檔案,可利用 ``–build-arg <varname>=<value>`` 來指定參數,例如: ```dockerfile docker build --build-arg Param1=demo -t myimage:v1 . ``` 在上面的例子中,我們在docker build中利用 ``–build-arg <varname>=<value>`` 參數將Param1的值變更為「demo」,而Param2的值並沒有指定,所以保留預設值「somevalue」 ## ONBUILD 若這個映像檔是作為其他映像檔的基底時,便需要定義ONBUILD指令,格式為: * ``ONBUILD [INSTRUCTION]`` ONBUILD後面接的指令在自建的映像檔中不會被執行,只有當這個映像檔是作為其他映像檔的基底時才會被觸發,例如A映像檔的Dockerfile定義如下(假設名稱為A-Image): ```dockerfile ...(以上略) ONBUILD ADD . /home/tmp ONBUILD mkdir -p /home/demo/docker ...(以下略) ``` 如果B映像檔是以A映像檔為基底,則A映像檔中的ONBUILD指令會被觸發,等於是以下指令: ```dockerfile # 以A映像檔為基底 FROM A-Image # 觸發A映像檔ONBUILD的指令,即會自動執行下面二個指令行 # 下面二行指令不用自己加,Docker會自動去執行,這邊寫出只是方便做說明 ADD . /home/tmp mkdir -p /home/demo/docker ``` # 如何使用Dockerfile ? 介紹了那麼多的指令,最終的目的就是利用Dockerfile來建立我們自己的映像檔,其指令為docker build,範例如下: ```dockerfile # 在目前目錄尋找Dockerfile或dockerfile docker build -t myimage:v1 . ``` ``-t`` :Name and optionally a tag in the ‘name:tag’ format,指定映像檔名稱、標籤 在上面的範例中,是假設Dockerfile在當前目錄下,因此會以.結尾,若是在不同目錄,則可以直接接Dockerfile所在目錄或用-f來指定Dockerfile位置,例如: ```dockerfile # 後面接Dockerfile的所在目錄 docker build -t myimage:v2 ./docker docker build -f /path/to/a/Dockerfile -t myimage:v3 . ``` 用 ``-f`` 來指定Dockerfile的位置時,後面接的目錄(及其子目錄)需要能夠找到Dockerfile,否則會出現context錯誤 小結:Dockerfile裡面的指令也不少,但因篇幅的關係這邊沒有列出所有的指令,但應該也足夠滿足大部分的需求,想要更深入研究的話,建議可以參考官方的文件,但我個人認為最快的學習方法可以自己動手做做看,比較能夠體會每個指令到底有什麼功用 ### Dockerfile實例 ```dockerfile= FROM centos ENV WKDIR="/tmp" WORKDIR $WKDIR RUN mkdir "中文目錄測試" ## UTF-8雖能正常輸入,但無法正常顯示非lang-en.UTF-8 RUN yum -y install nano RUN yum -y install net-tools EXPOSE 80 CMD echo --------------------- Setup Sucessed! ## CMD會在安裝過程中逐步執行等同RUN,但只有最後一行會被docker run 執行 CMD /bin/bash ``` ```shell docker build -f ./dockerfile -t centos_plus:1.0 . ``` ```shell docker run -it centos_plus:1.0 ``` # Docker Compose ```yaml version: '3.8' services: # db: # image: mariadb # working_dir: #預設工作目錄 # /root/ # environment: # MYSQL_ROOT_PASSWORD: example example-01: image: golang:1.15.13-stretch #鏡像名稱與版本,可參考https://hub.docker.com/layers/golang/library/golang/1.15.13-stretch/images/sha256-3c251a7c830aa6bcf0fe57a71d39dc4ba59d4d65775407d989c7f459da3ac207?context=explore container_name: go_API #為容器命名 restart: always volumes: #HOST:CONTAINER:ro - ./API:/root/:ro #限讀模式 - /dev/shm/API:/dev/shm/ #抓取主機RamDisk working_dir: #預設工作目錄 /root/ command: #容器內服務啟動指令 > sh -c " echo 目錄/dev/shm/:&& ls -la /dev/shm/ && echo 目錄./:&& ls -la ./ " #↑批次指令範例 ports: #對外Port:容器內Port - "8080:8080" networks: - default - outside ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000 #limit設置範例 environment: - TZ=Asia/Taipei #環境變數設置範例 networks: outside: external: true # version: "3.5": 選定 docker-compose 的版本,每個版本提供的 API 方法有所差異。 # services: 此欄位底下會有所有的容器,以下分別有server與db兩個 容器。 # build: 說明此容器要使用特定 Dockerfile 來 build,context為檔案目錄,dockerfile為 Dockerfile 的名字。 # working_dir: 指定 docker 啟動時所在的目錄,如果目錄不存在會自動創建一個。 # volumes: 將本機檔案掛載至 docker 內部,本機檔案更新時 docker 內部的掛載檔案也會更新。 # ports: 將本機的 port 做 mapping 與 docker 內部的 poart。 # depends_on: 說明 a 容器與 b 容器有相關,會等到 b 容器啟動完畢後,再啟動 a 容器。 # entrypoint: 指定 docker 啟動時的預設指令。 # restart: 當容器不正常關閉時,會重新啟動容器。 # image: 如果不使用 Dockerfile 來建立容器,你可以直接使用 docker image 來啟動容器。 # environment: 指定容器內的環境變數。 ``` # Docker Compose - 範例 ### Chrome Debug with Boswer Remote ```yaml version: '3' services: alpine-chrome: image: zenika/alpine-chrome:89 command: [chromium-browser, "--headless", "--disable-gpu", "--no-sandbox","--disable-software-rasterizer", "--remote-debugging-address=0.0.0.0","--shm-size=1gb", "--remote-debugging-port=9090"] ports: - "9090:9090" ``` ### Code-Server with Golang ```yaml version: '3.8' services: API.code-server: image: linuxserver/code-server:amd64-version-v3.10.2 container_name: code-server privileged: true #開啟root權限 volumes: - ./Code-Server:/config - ./workspace:/config/workspace environment: - PUID=1000 - PGID=1000 - TZ=Asia/Taipei #時區 - PASSWORD=qwerty #雲端vscode登入密碼 - HASHED_PASSWORD= #optional - SUDO_PASSWORD=qwerty #雲端環境sudo密碼 - SUDO_PASSWORD_HASH= #optional #- PROXY_DOMAIN=code-server.my.domain #optional - GO111MODULE=on #強制開啟go.mod版控 - GOPATH=/config/DevOpt/go-1.15.13/GoPath #GoPath絕對路徑 - GOROOT=/config/DevOpt/go-1.15.13/GoRoot #GoRoot絕對路徑 - GOTOOLDIR=/config/DevOpt/go-1.15.13/GoRoot/pkg/tool/linux_amd64 #GOTOOLDIR絕對路徑 - PATH=/config/DevOpt/go-1.15.13/GoPath/bin:/config/DevOpt/go-1.15.13/GoRoot/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin #設定go編譯器路徑 ports: - 8080:8080 #API子程式專用port - 8081:8443 #code-server外部用port command: #容器內服務啟動指令 > sh -c " echo 目錄./:&& ls -la ./config && echo $PATH && code-server --port 18080 --host 0.0.0.0 " #API子程式專用port必須與code-server port分開 #code-server為啟動雲端IDE的指令 restart: unless-stopped ulimits: nproc: 65535 nofile: soft: 20000 hard: 40000 # networks: # outside: # external: true ``` ### Firefox with VNC ```yaml version: '3' services: firefox: container_name: Firefox_for_Code-Server image: ich777/firefox:amd64 ports: - "9090:8080" environment: - FIREFOX_V=latest - FIREFOX_LANG=zh-TW - CUSTOM_RES_W=1600 #VNC解析度 - CUSTOM_RES_H=900 - UID=99 - GID=100 - UMASK=000 - DATA_PERM=770 volumes: - "./appdata:/firefox:rw" #存放firefox目錄 ``` ### Redis-Server ```yaml version: '3.8' services: # db: # image: mariadb # working_dir: #預設工作目錄 # /root/ # environment: # MYSQL_ROOT_PASSWORD: example Redis-Server: restart: always container_name: redis image: redis:6.2.4-alpine ports: - 16379:6379 volumes: - ./Redis/data:/data networks: outsite: external: true ``` ### VNC-xfce ```yaml version: '3.8' services: ubuntu-xfce-vnc: container_name: xfce image: imlala/ubuntu-xfce-vnc-novnc:latest shm_size: "1gb" # 防止高分辨率下Chromium崩溃 ports: - 5900:5900 - 9090:6080 environment: - VNC_PASSWD=qwerty - GEOMETRY=1600x900 - DEPTH=24 volumes: - ./Downloads:/root/Downloads restart: unless-stopped ``` ### Hedgedoc(hackmd社群版) ```yaml= # Using version 3 to provide play-with-docker badge # You can change to version 2 without breaking. #version: '2' version: '3' services: database: # Don't upgrade PostgreSQL by simply changing the version number # You need to migrate the Database to the new PostgreSQL version image: postgres:13.4-alpine #mem_limit: 256mb # version 2 only #memswap_limit: 512mb # version 2 only #read_only: true # not supported in swarm mode please enable along with tmpfs #tmpfs: # - /run/postgresql:size=512K # - /tmp:size=256K environment: - POSTGRES_USER=dbuser - POSTGRES_PASSWORD=dbpassword - POSTGRES_DB=dbName volumes: - ./postgresql/data:/var/lib/postgresql/data networks: backend: restart: always # MySQL example # Most of the documentation that applies to PostgreSQL applies also to MySQL #database: # # You should be able to upgrade MySQL without problems # # but to make sure no even when a problem appears you # # should have a backup # image: mariadb:10 # environment: # - MYSQL_USER=dbuser # - MYSQL_PASSWORD=dbpassword # - MYSQL_DATABASE=dbName # - MYSQL_ALLOW_EMPTY_PASSWORD=true # volumes: # - ./db/data:/var/lib/mysql # # This config provides UTF-8 support to the database by default # # If this config is not used, HedgeDoc breaks as it tries to write # # UTF-8 to a latin database. # - ./resources/utf8.cnf:/etc/mysql/conf.d/utf8.cnf # networks: # backend: # restart: always app: # Uncomment the following section to build the image yourself: #build: # context: . # dockerfile: debian/Dockerfile # args: # - "VERSION=master" # - "HEDGEDOC_REPOSITORY=https://github.com/hedgedoc/hedgedoc.git" image: quay.io/hedgedoc/hedgedoc:1.9.2 #mem_limit: 256mb # version 2 only #memswap_limit: 512mb # version 2 only #read_only: true # not supported in swarm mode, enable along with tmpfs #tmpfs: # - /tmp:size=10M # # Make sure you remove this when you use filesystem as upload type # - /hedgedoc/public/uploads:size=10M environment: # **DB_URL** is formatted like: <databasetype>://<username>:<password>@<hostname>:<port>/<database> # Other examples are: # - mysql://hedgedoc:password@database:3306/hedgedoc # - sqlite:///data/sqlite.db (NOT RECOMMENDED) # - For details see the official sequelize docs: http://docs.sequelizejs.com/en/v3/ - CMD_DB_URL=postgres://dbuser:dbpassword@database:5432/dbName # **DOMAIN** is the domain under which HedgeDoc will be available. Just the (sub)domain, no protocol or paths. # You MUST change this if your instance should be available under another domain than "localhost", otherwise your # instance may be broken. # You can define only ONE domain. - CMD_DOMAIN=localhost # **PROTOCOL_USESSL** defines if generated links should be HTTPS URLs. # This variable won't activate encryption on the listen port. # Set this to true if your reverse proxy exposes your instance via HTTPS. - CMD_PROTOCOL_USESSL=false # **HSTS_ENABLE** defines if HSTS headers should be sent. Set this to true if you use HTTPS. - CMD_HSTS_ENABLE=false # **URL_ADDPORT** defines if generated links should contain the port. # Set this to false if your reverse uses the default ports (443 for HTTPS or 80 for HTTP). - CMD_URL_ADDPORT=true volumes: - ./uploads:/hedgedoc/public/uploads ports: # Ports that are published to the outside. # The latter port is the port inside the container. It should always stay on 3000 # If you only specify a port it'll published on all interfaces. If you want to use a # local reverse proxy, you may want to listen on 127.0.0.1. # Example: # - "127.0.0.1:3000:3000" - "3000:3000" networks: backend: restart: always depends_on: - database # Define networks to allow best isolation networks: # Internal network for communication with PostgreSQL/MySQL backend: ```