Docker 教程
Docker 的应用场景
- **微服务架构:**每个服务独立容器化,便于管理和扩展。
- **CI/CD流水线:**与 Jenkins/GitLab CI 集成,实现自动化构建和测试。
- **开发环境标准化:**新成员一键启动全套依赖服务(如数据库、消息队列)。
- **云原生基础:**Kubernetes 等编排工具基于 Docker 管理容器集群。
基本命令
# 拉取镜像(如官方Nginx镜像)
docker pull nginx
# 运行容器(-d 后台运行,-p 映射端口)
docker run -d -p 80:80 nginx
# 查看运行中的容器
docker ps
# 构建镜像(基于当前目录的Dockerfile)
docker build -t my-app .
# 进入容器内部
docker exec -it <容器ID> /bin/bash相关链接
Docker 官网:https://www.docker.com
Github Docker 源码:https://github.com/docker
Docker安装
Ubuntu Docker 安装
使用官方安装脚本自动安装
安装命令如下:
# 下载并执行Docker官方安装脚本
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable dockerDebian Docker安装
卸载旧版本
如果你之前安装过 Docker Engine 之前,你需要卸载旧版本,避免冲突:
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done使用官方安装脚本自动安装
安装命令如下:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.shDocker Compose
Compose 简介
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
如果你还不了解 YML 文件配置,可以先阅读 YAML 入门教程。
Compose 使用的三个步骤:
- 使用 Dockerfile 定义应用程序的环境。
- 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
- 最后,执行 docker-compose up 命令来启动并运行整个应用程序。
docker-compose.yml 的配置案例如下(配置参数参考下文):
# yaml 配置实例
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}Compose 安装
Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。
运行以下命令以下载 Docker Compose 的当前稳定版本:
$ sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose要安装其他版本的 Compose,请替换 v2.2.2。
Docker Compose 存放在 GitHub,不太稳定。
你可以也通过执行下面的命令,高速安装 Docker Compose。
shcurl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
将可执行权限应用于二进制文件:
$ sudo chmod +x /usr/local/bin/docker-compose创建软链:
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose测试是否安装成功:
$ docker-compose version
cker-compose version 1.24.1, build 4667896b注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。
macOS
Mac 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Mac 用户不需要单独安装 Compose。Docker 安装说明可以参阅 MacOS Docker 安装。
windows PC
Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Windows 用户不需要单独安装 Compose。Docker 安装说明可以参阅 Windows Docker 安装。
docker-compose常用命令
# 构建建启动nignx容器
docker-compose up -d nginx
# 登录到nginx容器中
docker-compose exec nginx bash
# 删除所有nginx容器,镜像
docker-compose down
# 显示所有容器
docker-compose ps
# 重新启动nginx容器
docker-compose restart nginx
# 在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器
docker-compose run --no-deps --rm php-fpm php -v
# 构建镜像
docker-compose build nginx
# 不带缓存的构建
docker-compose build --no-cache nginx
# 查看nginx的日志
docker-compose logs nginx
# 查看nginx的实时日志
docker-compose logs -f nginx
# 验证(docker-compose.yml)文件配置,当配置正确时,不输出任何内容,当文件配置错误,输出错误信息。
docker-compose config -q
# 以json的形式输出nginx的docker日志
docker-compose events --json nginx
# 暂停nignx容器
docker-compose pause nginx
# 恢复ningx容器
docker-compose unpause nginx
# 删除容器(删除前必须关闭容器)
docker-compose rm nginx
# 停止nignx容器
docker-compose stop nginx
# 启动nignx容器
docker-compose start nginx
# 查看容器ip
docker inspect <容器ID或名称> | grep "IPAddress"docker-compose搭建一个专属的密码管理工具——Vaultwarden
创建安装目录
sudo -i
mkdir vaultwarden && cd vaultwarden
vim docker-compose.ymlservices:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
ports:
- "8070:80"
environment:
WEBSOCKET_ENABLED: 'true'
SIGNUPS_ALLOWED: 'true' # 此设置控制新用户是否可以在没有邀请的情况下注册账户。可能的值:true/false。
WEB_VAULT_ENABLED: 'true' # 此设置决定了网络保险库是否可访问。一旦您配置了您的账户和客户端,停止您的容器,然后将此值切换为false并重启Vaultwarden,可以用来防止未授权访问。可能的值:true/false。
ADMIN_TOKEN: 'YourReallyStrongAdminTokenHere' # 此值是Vaultwarden管理员面板的令牌(一种密码)。为了安全起见,这应该是一个长的随机字符串。如果未设置此值,则管理员面板将被禁用。建议openssl rand -base64 48 生成ADMIN_TOKEN确保安全
DOMAIN: 'https://subdomain.yourdomain.com' # 这是您希望与您的Vaultwarden实例关联的域名
volumes:
- ./data:/dataDOMAIN改成最后你要用的域名形式 ADMIN_TOKEN可以在ssh里面输入openssl rand -base64 48生成 SIGNUPS_ALLOWED等你注册好之后,如果你只是想自己用,可以把这边改成false
docker-compose up -d打开服务器防火墙并访问网页
打开服务器防火墙的端口 8080
更新 vaultwarden
cd vaultwarden
docker-compose pull
docker-compose up -d # 请不要使用 docker-compose stop 来停止容器,因为这么做需要额外的时间等待容器停止;docker-compose up -d 直接升级容器时会自动停止并立刻重建新的容器,完全没有必要浪费那些时间。
docker image prune # prune 命令用来删除不再使用的 docker 对象。删除所有未被 tag 标记和未被容器使用的镜像提示:
shWARNING! This will remove all dangling images. Are you sure you want to continue? [y/N]
卸载 vaultwarden
进入安装页面,先停止所有容器。
cd vaultwarden
docker-compose down
cd ..
rm -rf vaultwarden # 完全删除docker-compose搭建it-tools
GitHub官方仓库:https://github.com/CorentinTh/it-tools 官方Demo:https://it-tools.tech/
docker-compose.yaml:
services:
it-tools:
container_name: it-tools
restart: unless-stopped
ports:
- '8380:80' #8380可以修改成服务器上未使用过的其他端口
image: 'corentinth/it-tools:latest'打开服务器防火墙并访问网页
查看端口是否被占用(以 8380 为例),输入:
lsof -i:8380 #查看 8380 端口是否被占用,如果被占用,重新自定义一个端口
-bash: lsof: command not found #出现这段代码
apt install lsof #安装 lsof如果啥也没出现,表示端口未被占用
docker-compose搭建一个小而美的网站流量监控——umami
docker-compose.yaml:
services:
umami:
image: docker.umami.dev/umami-software/umami:postgresql-latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: replace-me-with-a-random-string
depends_on:
- db
restart: always
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami
volumes:
- ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro
- ./umami-db-data:/var/lib/postgresql/data
restart: always【好玩的Docker项目】搭建一个小而美的网站流量监控——Umami-我不是咕咕鸽 (laoda.de)
docker-compose搭建一个又小又快的文本、代码粘贴工具—— Hasty Paste
docker-compose.yaml:
services:
paste-bin:
image: ghcr.io/enchant97/hasty-paste:latest
container_name: hasty-paste
restart: unless-stopped
ports:
- 8000:8000 # 左边的8000可以自行修改成服务器上没有使用的端口
volumes:
- ./data:/app/data给data文件夹777权限
chmod 777 data参考资料
GitHub官方仓库:https://github.com/enchant97/hasty-paste
官方文档地址:https://enchantedcode.co.uk/hasty-paste/
用Docker创建Nginx,自动申请免费的域名证书,并且配置重定向或反向代理
搭建nginx
创建nginx目录结构
mkdir -p /home/nginx
touch /home/nginx/nginx.conf
mkdir -p /home/nginx/certs申请证书
curl https://get.acme.sh | sh
~/.acme.sh/acme.sh --register-account -m [email protected]
~/.acme.sh/acme.sh --issue -d 自己的域名 --standalone下载证书
~/.acme.sh/acme.sh --install-cert -d www.shiyunhao.cn \
> --key-file /home/nginx/ssl/private.key \
> --fullchain-file /home/nginx/ssl/cert.crt进入目录编辑文件
cd /home/nginx/ && vim nginx.conf重定向配置,跳转到域名
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name a.**kjlion.gq**;
return 301 https://**www.baidu.com**$request_uri;
}
server {
listen 443 ssl http2;
server_name a.**kjlion.gq**;
ssl_certificate /etc/nginx/certs/cert.pem;
ssl_certificate_key /etc/nginx/certs/key.pem;
return 301 https://**www.baidu.com**$request_uri;
}
}
**反向代理配置,代理指定IP加端口**
events {
worker_connections 1024;
}
http {
client_max_body_size 1000m;
server {
listen 80;
server_name b.**kjlion.gq**;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name b.**kjlion.gq**;
ssl_certificate /etc/nginx/certs/cert.crt;
ssl_certificate_key /etc/nginx/certs/private.key;
location / {
proxy_pass http://**127.0.0.1:5212**;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
**代理静态网页的配置方式**
events {
worker_connections 1024;
}
server {
listen 80;
server_name c.**kjlion.gq**;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name c.**kjlion.gq**;
ssl_certificate /etc/nginx/certs/cert.pem;
ssl_certificate_key /etc/nginx/certs/key.pem;
charset utf-8; # 添加这行来指定编码
location / {
root /usr/share/nginx/html;
index index.html;
}
}部署容器
docker run -d --name nginx -p 80:80 -p 443:443 -v /home/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/nginx/certs:/etc/nginx/certs -v /home/nginx/html:/usr/share/nginx/html nginx:latest查看运行状态
docker ps -a开机自启动
docker update --restart=always nginxDocker-compose搭建一个功能强大的开源问卷考试系统-卷王
admin 123456
创建docker-compose.yml文件
services:
surveyking:
image: surveyking/surveyking #镜像名
volumes:
- './logs:/surveyking/logs' #目录映射
- './files:/surveyking/files' #目录映射
- './surveyking.mv.db:/surveyking/surveyking.mv.db' #文件映射
ports:
- '1991:1991' #端口映射,:左侧的1991可以自定义
environment:
- PUID=0 # 用户ID,在终端输入id可以查看当前用户的id
- PGID=0 # 组ID同上
- TZ=Asia/Shanghai #时区,可以自定义
restart: always #总是启动docker-compose搭建ddns-go
docker-compose.yaml:
services:
ddns-go:
image: jeessy/ddns-go:latest
container_name: ddns-go
restart: always
network_mode: host
volumes:
- ./ddns-go/data:/root # 配置文件持久化目录
environment:
- NET_INTERFACE=ens192
- TZ=Asia/Shanghai # 设置时区(可选)docker-compose搭建easyimage
docker-compose.yaml:
services:
easyimage:
image: ddsderek/easyimage:latest
container_name: easyimage
ports:
- '3578:80'
environment:
- TZ=Asia/Shanghai
- PUID=0
- PGID=0
volumes:
- './config:/app/web/config'
- './images:/app/web/images'
restart: unless-stoppeddocker-compose搭建halo
docker-compose.yaml:
services:
halo:
image: halohub/halo:2.20
container_name: halo
restart: always
depends_on:
halodb:
condition: service_healthy
networks:
halo_network:
volumes:
- ./:/root/.halo2
ports:
- "8090:8090"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8090/actuator/health/readiness"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
command:
- --spring.r2dbc.url=r2dbc:pool:mysql://halodb:3306/halo
- --spring.r2dbc.username=root
# MySQL 的密码,请保证与下方 MYSQL_ROOT_PASSWORD 的变量值一致。
- --spring.r2dbc.password=o#DwN&JSa56
- --spring.sql.init.platform=mysql
# 外部访问地址,请根据实际需要修改
- --halo.external-url=https://www.shiyunhao.cn/
# 初始化的超级管理员用户名
- --halo.security.initializer.superadminusername=admin
# 初始化的超级管理员密码
- --halo.security.initializer.superadminpassword=shi13579
halodb:
image: mysql:8.0.31
container_name: halodb
restart: always
networks:
halo_network:
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_general_ci
- --explicit_defaults_for_timestamp=true
volumes:
- ./mysql:/var/lib/mysql
- ./mysqlBackup:/data/mysqlBackup
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 3s
retries: 5
start_period: 30s
environment:
# 请修改此密码,并对应修改上方 Halo 服务的 SPRING_R2DBC_PASSWORD 变量值
- MYSQL_ROOT_PASSWORD=o#DwN&JSa56
- MYSQL_DATABASE=halo
networks:
halo_network:docker-compose搭建linux-command
docker-compose.yaml:
services:
linux-command:
container_name: linux-command
ports:
- '3002:3000'
environment:
- PUID=0
- PGID=0
- TZ=Asia/Shanghai
restart: always
image: wcjiang/linux-command:latestdocker-compose搭建nextcloud
docker-compose.yaml:
version: '3.8'
services:
db:
image: docker.1ms.run/library/mariadb:10.6
container_name: nextcloud-db
restart: always
environment:
MYSQL_ROOT_PASSWORD: shi13579
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: nextcloud
volumes:
- ./db_data:/var/lib/mysql
networks:
- nextcloud-net
# 👇 添加健康检查
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pshi13579"]
timeout: 20s
retries: 10
interval: 5s
start_period: 15s
nextcloud:
image: docker.1ms.run/library/nextcloud:27-apache
container_name: nextcloud-app
restart: always
ports:
- "8080:80"
# 👇 修改为等待 db 完全健康
depends_on:
db:
condition: service_healthy # ✅ 关键修复
redis:
condition: service_started
environment:
MYSQL_HOST: db
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: nextcloud
NEXTCLOUD_ADMIN_USER: shilith
NEXTCLOUD_ADMIN_PASSWORD: shi13579
REDIS_HOST: redis
REDIS_HOST_PORT: 6379
volumes:
- ./nextcloud_data:/var/www/html
networks:
- nextcloud-net
redis:
image: docker.1ms.run/library/redis:alpine
container_name: nextcloud-redis
restart: always
networks:
- nextcloud-net
volumes:
db_data:
nextcloud_data:
networks:
nextcloud-net:
driver: bridgedocker-compose搭建uptime-kuma
docker-compose.yaml:
services:
uptime-kuma:
image: louislam/uptime-kuma
container_name: uptime-kuma
restart: unless-stopped
volumes:
- ./data:/app/data
ports:
- 3001:3001docker-compose搭建stirling-pdf
docker-compose.yaml:
services:
stirling-pdf:
image: frooodle/s-pdf:latest
ports:
- '8092:8080'
volumes:
- ./trainingData:/usr/share/tessdata #Required for extra OCR languages
- ./extraConfigs:/configs
# - ./customFiles:/customFiles/
# - ./logs:/logs/
environment:
- DOCKER_ENABLE_SECURITY=false
- INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false
restart: alwaysdocker-compose搭建wordpress
docker-compose.yaml:
services:
db:
image: mysql:8.0 # 使用mysql镜像,不建议修改版本号,后续如果要升级,千万记得备份数据库
container_name: wordpress-db
restart: unless-stopped
command: --max-binlog-size=200M --expire-logs-days=2
environment:
MYSQL_ROOT_PASSWORD: shi13579 # 这里是上面的root密码
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress # 这里是原来的密码
volumes:
- './db:/var/lib/mysql'
networks:
- default
app:
image: wordpress:latest
container_name: wordpress-app
restart: unless-stopped
ports:
- 8086:80 # 按需修改,左边的8080可以改成服务器上没有用过的端口
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress # 按需修改
volumes:
- './app:/var/www/html'
links:
- db:db
depends_on:
- redis
- db
networks:
- default
redis:
image: redis:alpine
container_name: wordpress-redis
restart: unless-stopped
volumes:
- ./redis-data:/data
networks:
- default
networks:
default:
name: wordpressdocker-compose搭建yourls
docker-compose.yaml:
services:
mysql:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
- MYSQL_DATABASE=yourls
- MYSQL_USER=yourls
- MYSQL_PASSWORD=yourls
volumes:
- ./mysql/db/:/var/lib/mysql
- ./mysql/conf/:/etc/mysql/conf.d
restart: always
container_name: mysql
yourls:
image: yourls
restart: always
ports:
- "8200:80"
environment:
YOURLS_DB_HOST: mysql
YOURLS_DB_USER: yourls
YOURLS_DB_PASS: yourls
YOURLS_DB_NAME: yourls
YOURLS_USER: admin
YOURLS_PASS: admin
YOURLS_SITE: https://shil.top
YOURLS_HOURS_OFFSET: 8
volumes:
- ./yourls_data/:/var/www/html
container_name: yourls_service
links:
- mysql:mysqldocker-compose搭建nginx-proxy-manager
docker-compose.yaml:
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: always
ports:
# These ports are in format <host-port>:<container-port>
- '30021:80' # Public HTTP Port
- '30022:443' # Public HTTPS Port
- '30020:81' # Admin Web Port
# Add any other Stream port you want to expose
# - '21:21' # FTP
environment:
TZ: "Asia/Shanghai"
# Mysql/Maria connection parameters:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm"
DB_MYSQL_NAME: "npm"
# Optional SSL (see section below)
# DB_MYSQL_SSL: 'true'
# DB_MYSQL_SSL_REJECT_UNAUTHORIZED: 'true'
# DB_MYSQL_SSL_VERIFY_IDENTITY: 'true'
# Uncomment this if IPv6 is not enabled on your host
# DISABLE_IPV6: 'true'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: 'jc21/mariadb-aria:latest'
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'npm'
MYSQL_DATABASE: 'npm'
MYSQL_USER: 'npm'
MYSQL_PASSWORD: 'npm'
MARIADB_AUTO_UPGRADE: '1'
volumes:
- ./mysql:/var/lib/mysql