envfile support

envfile
Ximo Guanter 3 years ago
parent 9184475e68
commit 9fc9de28db

@ -1,12 +1,11 @@
# Dockerfile+
This project provides Dockerfile syntax extensions that have been rejected by the moby project or haven't been addressed in a long time.
Currently, the project adds an `INCLUDE+` Dockerfile directive that allows you to import the content of another file into your Dockerfile. There are plans to add more features in the near future.
This project provides useful Dockerfile syntax extensions that have been rejected by the moby project or haven't been addressed in a long time.
- [Getting started](#getting-started)
- [Features](#features)
- [INCLUDE+](#include)
- [ENVFILE+](#envfile)
- [Roadmap](#roadmap)
- [Feedback](#feedback)
@ -27,9 +26,9 @@ That's it!
## Features
### INCLUDE+
Note: All Dockerfile+ commands will end up with a `+` sign to avoid any potential future collisions with Dockerfile commands.
Right now there is just one extra instruction: `INCLUDE+`. All Dockerfile+ commands will end up with a `+` sign to avoid any potential future collisions with Dockerfile commands.
### INCLUDE+
`INCLUDE+` will import the verbatim contents of another file into your Dockerfile. Here's an example Dockerfile which uses the `INCLUDE+` instruction:
@ -54,11 +53,45 @@ RUN echo "Hello World"
ENTRYPOINT [ "mybin" ]
```
### ENVFILE+
docker-compose has had support for envfiles for a while now, but Dockerfile hasn't. The `ENVFILE+` instruction brings that support to Dockerfile! If you `ENVFILE+` a .env file, each line will be treated as an `ENV` definition. Here's an example:
```Dockerfile
# syntax = edrevo/dockerfile-plus
FROM alpine
ENVFILE+ prod.env
ENTRYPOINT [ "mybin" ]
```
If prod.env has the following:
```env
FOO=Hello
BAR=World
```
The resulting Docker image would be equivalent to the one generated by this standard Dockerfile:
```Dockerfile
# syntax = edrevo/dockerfile-plus
FROM alpine
ENV FOO=Hello
ENV BAR=World
ENTRYPOINT [ "mybin" ]
```
## Roadmap
The next features in line would be:
- `ENVFILE+` command, which would read a .env file and import all of those environment variable definitions into the Dockerfile
- `RUN+ --no-cache`, which would disable the cache only for a specific RUN step (useful for non-idempotent commands, for example those that clone git repos)
- `TAG` command
- improvements to .dockerignore, like recursive dockerignore files

@ -0,0 +1,9 @@
# syntax = edrevo/dockerfile-plus:0.2
FROM alpine
ENVFILE+ dev.env
WORKDIR /
RUN echo "Hello World"

@ -0,0 +1,3 @@
MEAN_STORE_PORT = 4200
MEAN_STORE_SECRET = "dummy_secret"
MEAN_STORE_DATABASE = "dummy_connection"

@ -104,6 +104,7 @@ struct DockerfileOptions {
}
const INCLUDE_COMMAND: &str = "INCLUDE+";
const ENVFILE_COMMAND: &str = "ENVFILE+";
async fn dockerfile_trap(
mut client: LlbBridgeClient<Channel>,
@ -114,11 +115,19 @@ async fn dockerfile_trap(
let context_source = Source::local("context");
let context_layer = solve(&mut client, Terminal::with(context_source.output())).await?;
for line in dockerfile_contents.lines() {
if let Some(file_path) = line.trim().strip_prefix(INCLUDE_COMMAND) {
let trimmed_line = line.trim();
if let Some(file_path) = trimmed_line.strip_prefix(INCLUDE_COMMAND) {
let bytes = read_file(&mut client, &context_layer, file_path.trim_start().to_string(), None)
.await
.with_context(|| format!("Could not read file \"{}\". Remember that the file path is relative to the build context, not the Dockerfile path.", file_path))?;
result.push(std::str::from_utf8(&bytes)?.to_string());
} else if let Some(file_path) = trimmed_line.strip_prefix(ENVFILE_COMMAND) {
let bytes = read_file(&mut client, &context_layer, file_path.trim_start().to_string(), None)
.await
.with_context(|| format!("Could not read file \"{}\". Remember that the file path is relative to the build context, not the Dockerfile path.", file_path))?;
for env_line in std::str::from_utf8(&bytes)?.lines() {
result.push(format!("ENV {}", env_line));
}
} else {
result.push(line.to_string());
}

Loading…
Cancel
Save