所以我只是为我的学校构建一个小项目,我有一台旧电脑,现在用作服务器。
我的目标是使用ngrok容器公开FTP容器,以便我可以从任何地方使用域访问它。
所以我创建了一个 compose.yaml ,它几乎应该构建所需的服务。
敏感数据(例如用户和密码)使用机密传递到容器。
在 ftp 中: shell 命令创建一个环境变量并存储秘密值,以便 FTP 容器授予访问权限。
在 ngrok 中: 几乎遵循相同的逻辑,但它不是创建环境,而是将 AUTH_TOKEN 的值更改为 ngrok.yml 文件中的实际令牌。
然后我应该能够从任何地方连接并传输文件。
使用 Docker Compose 构建服务时,我收到来自守护进程的警告
WARN[0000] The "AUTH_TOKEN" variable is not set. Defaulting to a blank string.
,但守护进程仍然可以完成构建。docker ps
查看正在运行的容器时,它们总是在重新启动:CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4f4e56f716cc ngrok/ngrok:latest "/nix/store/n98vsmwd…" 6 minutes ago Restarting (1) 26 seconds ago app-ngrok-1
ec97742b74fc delfer/alpine-ftp-server:latest "/sbin/tini -- /bin/…" 6 minutes ago Restarting (0) 28 seconds ago app-ftp-1
检查 ftp 容器后,它会记录以下内容:
deluser: can't find alpineftp in /etc/group
Changing password for alpineftp
New password:
Bad password: similar to username
Retype password:
passwd: password for alpineftp changed by root
同样,在检查 ngrok 时,它会记录以下内容:
ERROR: unknown shorthand flag: 'c' in -c
我正在学习如何使用 Docker,这就是我构建这个小项目的原因。
由于我的知识有限,我不擅长 bash,但我洗耳恭听,真的很期待成长!
version: "3.8"
services:
ftp:
image: delfer/alpine-ftp-server:latest
restart: always
command:
- "/bin/sh"
- "-c"
- "USERS=$(cat /run/secrets/FTP_USERS); export USERS"
environment:
- ADDRESS=some-generated-domain.ngrok-free.app
volumes:
- /mnt/storage/public:/ftp
networks:
- public_web
secrets:
- FTP_USERS
ngrok:
image: ngrok/ngrok:latest
restart: always
command:
- "/bin/sh"
- "-c"
- "AUTH_TOKEN=$(cat /run/secrets/AUTH_TOKEN); sed -i `s/AUTH_TOKEN/$AUTH_TOKEN/g` /etc/ngrok.yml;"
- "start"
- "--all"
- "--config"
- "/etc/ngrok.yml"
volumes:
- /mnt/storage/conf/ngrok.yml:/etc/ngrok.yml
depends_on:
- ftp
networks:
- public_web
ports:
- 21:21
secrets:
- AUTH_TOKEN
networks:
public_web:
secrets:
AUTH_TOKEN:
file: /mnt/storage/.secrets/ngrokToken.txt
FTP_USERS:
file: /mnt/storage/.secrets/ftpUsers.txt
authtoken: AUTH_TOKEN
region: eu
tunnels:
ftp:
labels:
- hostname=Transfer_Files
- service=ftp
proto: tcp
addr: 21
hostname: some-generated-domain.ngrok-free.app
在您的撰写文件(或其他 YAML 文档)中嵌入 shell 脚本时,您几乎在所有情况下都会发现利用 YAML 的各种扩展引用运算符更易于管理。而不是这个:
command:
- "sh"
- "-c"
- "echo this is a test; date > some_file; some_other_command"
使用块文字引号运算符:
command:
- "sh"
- "-c"
- |
echo this is a test
date > some_file
some_other_command"
这既更易于阅读,又避免了嵌套引用问题。
ftp:
image: delfer/alpine-ftp-server:latest
restart: always
command:
- "/bin/sh"
- "-c"
- |
USERS=$(cat /run/secrets/FTP_USERS)
export USERS
它将启动,运行你的 shell 脚本,然后退出(然后无限重复,因为你已经设置了 restart: always
)。
ngrok
容器也无效;当您使用
sh -c "some script"
运行脚本时,只有
-c
的第一个参数是脚本。你有:
command:
- "/bin/sh"
- "-c"
- "AUTH_TOKEN=$(cat /run/secrets/AUTH_TOKEN); sed -i `s/AUTH_TOKEN/$AUTH_TOKEN/g` /etc/ngrok.yml;"
- "start"
- "--all"
- "--config"
- "/etc/ngrok.yml"
所以你实际运行的是:
AUTH_TOKEN=$(cat /run/secrets/AUTH_TOKEN)
sed -i `s/AUTH_TOKEN/$AUTH_TOKEN/g` /etc/ngrok.yml
您还使用反引号来引用字符串,这是一个错误; backtics 用于命令替换。您需要使用双引号 ("
) 来引用该表达式。我看起来像你的意思:
command:
- "/bin/sh"
- "-c"
- |
AUTH_TOKEN=$(cat /run/secrets/AUTH_TOKEN)
sed -i "s/AUTH_TOKEN/$AUTH_TOKEN/g" /etc/ngrok.yml
start --all --config /etc/ngrok.yml
但这不起作用,因为 ngrok
容器默认运行
ngrok
,并将
command
值作为参数,因此这将失败:
ngrok-1 | ERROR: unknown shorthand flag: 'c' in -c
您需要找出其他方法来处理 ngrok 的秘密。例如,您可以在 ngrok 容器之前运行一个容器,该容器读取配置文件,执行变量替换,然后将其写入卷,然后由 ngrok 容器使用。