我是 docker 的新手,并尝试使用最简单的 docker-compose.yml 显示一个 hello world 页面,并在此基础上构建最终完整的 LEMP 堆栈,其配置与我的服务器相同。然而,大多数教程都已过时,并且使用 docker 的方法有很多,我找不到一种仅使用 Docker compose v3 仍然有效的方法。我检查了文档,对于初学者来说这也非常令人困惑,在过去的 5 个小时里一直试图让它工作,所以我想我应该问一下。
docker-compose.yml
version: '3'
services:
web:
image: bitnami/nginx:1.10.3-r0 #using this version as it's the same on my server
volumes:
- "./test.conf:/etc/nginx/sites-available/test.local"
- "./test.conf:/etc/nginx/sites-enabled/test.local"
- "./code:/var/www/html" #code contains only a basic index.html file
ports:
- "80:80"
测试.conf
server {
listen 80;
listen [::]:80;
server_name test.local;
index index.html; #Only a basic helloworld index.html file
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html;
}
我需要一个 Dockerfile 吗?教程似乎没有提到它是必要的。
注意:
尝试增加音量
- "./default.conf:/etc/nginx/conf.d/default.conf"
但没有任何变化,欢迎页面仍然加载,而使用 nginx:latest 我收到一个非常详细的错误,其中包含以下短语:“未知:您是否正在尝试将目录挂载到文件上(或反之亦然)?检查是否指定的主机路径存在并且是预期的类型”。
有关 docker-compose.yml 的更新:
"./code:/usr/share/nginx/html"
行,/usr/share/nginx/html
文件夹包含默认的index.html文件(预期)"./code:/usr/share/nginx/html"
行,/usr/share/nginx/html
文件夹为 EMPTY!"./:/usr/share/nginx/html"
行,/usr/share/nginx/html
文件夹有一个空的“code”文件夹和一堆我不久前删除的随机测试文件。在尝试之间,我运行重置脚本以确保重新开始:
docker rm $(docker ps -a -q)
docker rmi $(docker images -q) --force
docker volume rm $(docker volume ls -q)
运行
docker inspect <container>
返回该卷,不确定类型为“绑定”作为 bind mount 而不是 volume 是否正常。
"Mounts": [
{
"Type": "bind",
"Source": "/e/DEV/sandbox/docker",
"Destination": "/usr/share/nginx/html",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
安装您自己的 hello world 页面很容易。我将使用官方
nginx:latest
图像进行解释,但如果您愿意,您可以使用 bitnami 图像自行完成。
首先是非常基本的。只需运行 nginx 容器(无需 docker-compose)。我将详细和基本地解释它,当然我可以尝试执行更高级或更快的命令来读取容器内的文件,但这对于初学者来说可能会感到困惑。因此,只需运行容器并将其命名为
my-nginx
:
$ docker run --rm -d -p 80:80 --name my-nginx nginx
转到
localhost:80
,您将看到默认的nginx页面。
现在您可以使用容器的名称在容器内执行。 exec 会将您带入“容器内部”,以便您可以检查其文件。
$ docker exec -it my-nginx bash
root@2888fdb672a1:/# cd /etc/nginx/
root@2888fdb672a1:/etc/nginx# ls
conf.d koi-utf mime.types nginx.conf uwsgi_params
fastcgi_params koi-win modules scgi_params win-utf
现在使用
nginx.conf
阅读 cat
。
该文件中最重要的行是:
include /etc/nginx/conf.d/*.conf;
这意味着该目录中的所有
confs
都被使用/读取。
所以进入/etc/nginx/conf.d/
。
root@2888fdb672a1:~# cd /etc/nginx/conf.d/
root@2888fdb672a1:/etc/nginx/conf.d# ls
default.conf
default.conf
是唯一的文件。在这个文件中您可以看到配置:
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
服务器是本地主机,端口是80,将显示的文件在目录中
/usr/share/nginx/html/
现在检查容器中的该文件:
root@2888fdb672a1:/etc/nginx/conf.d# cat /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
...
这是预期的文件。我们可以看到“Welcome to Nginx”页面。 那么我们怎样才能展示自己的
index.html
呢?只需将其安装在 /usr/share/nginx/html
中即可。
你会
docker-compose.yaml
看起来像这样。
version: '3'
services:
web:
image: nginx:latest
volumes:
- ./code:/usr/share/nginx/html
ports:
- "80:80"
代码目录只包含一个带有 hello world 的
index.html
。
运行docker-compose up -d --build
,当你卷曲localhost:80
时,你会看到你自己的index.html
。
如果您确实想将代码放入
/var/www/html
而不是 /usr/share/nginx
中,您可以这样做。
使用您的
test.conf
。在这里您定义将文件放入 /var/www/html/
:
server {
listen 80;
listen [::]:80;
server_name test.local;
index index.html; #Only a basic helloworld index.html file
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html;
}
在撰写中,您将用您自己的conf覆盖
default.conf
,告诉nginx查看/var/www/html
。
您的撰写可能如下所示:
version: '3'
services:
web:
image: nginx:latest
volumes:
- "./test.conf:/etc/nginx/conf.d/default.conf"
- "./code:/var/www/html"
ports:
- "80:80"
现在,当您自己的
index.html
位于您自己的指定位置时,您还会看到它。答案很长,但我希望这会有所帮助。
在这个问题上苦苦挣扎之后,我找到了使我的 docker-compose 部署工作正常进行的三个因素。
我用nodejs做了一个网站。
nodejs 的 Dockerfile :[重要的一行是 -> EXPOSE 80 ]
FROM node:14-alpine
WORKDIR /
COPY package.json ./
EXPOSE 80
RUN npm install
COPY . .
CMD ["node", "bin/www"]
Nginx.conf for nginx : [重要的一行是 -> Listen 80; ]
events {
}
http {
server {
listen 80;
location / {
proxy_pass http://nodejs:3000;
}
}
}
docker-compose.yaml:
[重要的一行是 -> image: nodejs ] 这是网络图像的名称
和
[重要的一行是 -> ports: -"3000:3000" ] 这是运行 Web 部分的端口
version: "3.7"
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
restart: unless-stopped
networks:
- app-network
ports:
- "3000:3000"
webserver:
image: nginx
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/:/etc/nginx/conf.d
depends_on:
- nodejs
networks:
- app-network
networks:
app-network:
driver: bridge
Nginx.conf for nginx : [重要的一行是 -> proxy_pass http://nodejs:3000; ]
events {
}
http {
server {
listen 80;
location / {
proxy_pass http://nodejs:3000;
}
}
}
树:
mainfolder
.
|_____nginx
| |______nginx.conf
|
|_____Dockerfile
|
|_____docker-compose.yaml
docker-compose.yaml:
[重要的一行是 -> ./nginx/nginx.conf:/etc/nginx/nginx.conf ] 替换配置文件
version: "3.7"
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
restart: unless-stopped
networks:
- app-network
ports:
- "3000:3000"
webserver:
image: nginx
container_name: webserver
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- nodejs
networks:
- app-network
networks:
app-network:
driver: bridge
这是 Docker Compose 文件。如果您将 /var/www/html 文件夹挂载到包含您的设计 index.html 的另一个文件夹,它将覆盖默认文件夹。
services:
nginxproxymanager:
cpu_shares: 90
command: []
container_name: nginxproxymanager
deploy:
resources:
limits:
memory: 29779M
reservations:
memory: "134217728"
hostname: nginxproxymanager
image: jc21/nginx-proxy-manager:2.11.2
labels:
icon: https://cdn.jsdelivr.net/gh/IceWhaleTech/CasaOS-AppStore@main/Apps/NginxProxyManager/icon.png
ports:
- target: 80
published: "80"
protocol: tcp
- target: 443
published: "443"
protocol: tcp
- target: 81
published: "81"
protocol: tcp
restart: unless-stopped
volumes:
- type: bind
source: /DATA/AppData/nginxproxymanager/data
target: /data
- type: bind
source: /DATA/AppData/nginxproxymanager/etc/letsencrypt
target: /etc/letsencrypt
- type: bind
source: /DATA/AppData/nginxproxymanager/www <========
target: /var/www/html <========