我有一个 dockerised 的服务器应用程序,但似乎无法按要求将变量从docker-compse.yaml
任何服务传递给它。Dockerfile
因此我找不到任何其他解决方案,只能按照以下方法...
我有两个几乎相同的Dockerfile
s,每个服务器环境一个:
# ./docker/production-server/Dockerfile
FROM rust:latest
WORKDIR /usr/src/rust-scrape-yt
ENV BUILD_FLAGS="--release"
ENV TEST_DOCKER="true"
ENV PRODUCTION="true"
COPY dummy.rs src/main.rs
COPY Cargo.toml .
COPY Cargo.lock .
RUN echo "Dummy build for deps, with flags: $BUILD_FLAGS"
RUN cargo build $BUILD_FLAGS
COPY . .
RUN cargo build $BUILD_FLAGS
对于开发容器:
# ./docker/development-server/Dockerfile
FROM rust:latest
WORKDIR /usr/src/rust-scrape-yt
ENV BUILD_FLAGS=""
ENV TEST_DOCKER="true"
ENV PRODUCTION="false"
COPY dummy.rs src/main.rs
COPY Cargo.toml .
COPY Cargo.lock .
RUN echo "Dummy build for deps, with flags: $BUILD_FLAGS"
RUN cargo build $BUILD_FLAGS
COPY . .
RUN cargo build $BUILD_FLAGS
唯一的区别是生产 Dockerfile 有:
ENV BUILD_FLAGS="--release"
虽然开发服务器镜像已经:
ENV BUILD_FLAGS=""
COPY dummy.rs src/main.rs
COPY Cargo.toml .
COPY Cargo.lock .
RUN echo "Dummy build for deps, with flags: $BUILD_FLAGS"
RUN cargo build $BUILD_FLAGS
COPY . .
RUN cargo build $BUILD_FLAGS
我docker-compose.yaml
的如下:
version: "3.9"
services:
production-db:
image: postgres
restart: always
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: thisisjustSommmePasWorttLaliloo
POSTGRES_DB: rust-yt-scraper
ports:
- 15878:5432
volumes:
- production-rust-yt-scraper:/var/lib/postgresql/data
development-db:
image: postgres
restart: always
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: thisisjustSommmePasWorttLalilooForDev
POSTGRES_DB: rust-yt-scraper
ports:
- 15879:5432
volumes:
- development-rust-yt-scraper:/var/lib/postgresql/data
production-server:
depends_on:
- production-db
build:
context: .
dockerfile: docker/production-server/Dockerfile
image: djfm/rust-yt-scraper-prod:latest
restart: always
environment:
PRODUCTION: "true"
ports:
- "19850:8080"
command: cargo run --release --bin server
development-server:
depends_on:
- development-db
build:
context: .
dockerfile: docker/development-server/Dockerfile
image: djfm/rust-yt-scraper-dev:latest
restart: always
ports:
- "19851:8080"
command: cargo run --bin server
environment:
PRODUCTION: "false"
server-tests:
image: djfm/rust-yt-scraper:latest
restart: never
depends_on:
- development-server
environment:
- PRODUCTION:false
- BUILD_FLAGS:""
command: cargo test
adminer:
image: adminer
restart: always
ports:
- "9280:8080"
volumes:
production-rust-yt-scraper:
driver: local
development-rust-yt-scraper:
driver: local
我试过:
service:
blah:
build:
context: .
dockerfiles: ./conf/server.Dockerfile
args:
PRODUCTION:true
这没希望了吗?我需要维护单独的 Dockerfile 吗?
答案1
嗨。
在安装不同的软件包之前,请仅使用一个 Dockerfile 来构建映像。
或者更好的是,我认为,在这个用例中是多阶段构建,因为你使用的是 rust,并且你不会将源代码与映像一起发送。
对于 ENV 变量,您做对了,但输入有误。下面将进行解释。
只需定义您想要在运行时映像中拥有的 ENV 变量,并用默认值填充它们(如果需要)。
对于 BUILD_FLAGS,我建议使用 ARG
信息:
ENV 随后会保留在图像中,因为环境变量
ARG 仅在图像构建期间可用,并且不会保留在图像中
为了便于阅读,我将跳过一些步骤...
尝试使用多阶段更新你的 Dockerfile:
ARG BUILD_FLAGS="[YOUR DEFAULT FLAGS]"
FROM rust:latest as buildimage
ARG BUILD_FLAGS
ENV CARGO_TARGET_DIR=target
COPY dummy.rs src/main.rs
RUN cargo build $BUILD_FLAGS
在同一个 Dockerfile 中继续:
FROM rust:latest
ARG BUILD_FLAGS
ENV PRODUCTION="false"
COPY --from=buildimage target/ /app/
所以发生了什么事:
- 第一个镜像用于编译你的应用程序,名为 buildimage
- 第二幅图像只会将 buildimage 的结果复制到不包含 main.rs 的新图像中
- 最终图像没有 ENV 变量 BUILD_FLAGS 因为我们将其声明为 ARG
- 最终图像仅设置了 PRODUCTION 环境变量,其默认字符串为“false”
- FROM 之前的 ARG 是全局的,FROM 之后的 ARG 仅在当前构建中本地。要接管默认值,请重新定义它们
- DryRun:我将 CARGO_TARGET_DIR 设置为仅“target”,以摆脱 target/release 和 target/debug 文件夹
注意:
由于我不是 Rust 开发人员,我只能猜测编译后的主文件位于何处。
这是一个完整的试运行,但应该可以解决您的问题。
结合您的撰写文件,您将获得两幅图像。
一幅图像包含可用于生产的内容,
另一幅图像包含调试符号等。
在 Compose 文件中配置你的环境变量。
你可以通过两种方式定义环境变量:
方式一:
environment:
VAR_1: "value_1"
VAR_2: "value_2"
方法二:
environment:
- VAR_1="value_1"
- VAR_2="value_2"
我更喜欢第一种保留完整语法的方式
因此你的撰写文件看起来应该是这样的:
version: "3.9"
services:
production-db:
[...]
development-db:
[...]
production-server:
depends_on:
- production-db
build:
context: .
dockerfile: docker/Dockerfile
args:
BUILD_FLAGS: "--release"
image: djfm/rust-yt-scraper:latest
restart: always
environment:
PRODUCTION: "true"
ports:
- "19850:8080"
command: cargo run --release --bin server
development-server:
depends_on:
- development-db
build:
context: .
dockerfile: docker/Dockerfile
args:
BUILD_FLAGS: ""
image: djfm/rust-yt-scraper-dev:latest
restart: always
environment:
PRODUCTION: "false"
ports:
- "19851:8080"
command: cargo run --bin server
server-tests:
image: djfm/rust-yt-scraper:latest
restart: never
depends_on:
- development-server
environment:
PRODUCTION: "false"
command: cargo test
adminer:
image: adminer
restart: always
ports:
- "9280:8080"
volumes:
production-rust-yt-scraper:
driver: local
development-rust-yt-scraper:
driver: local
高血压