Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ custom:
# Subdirectory holding the Dockerfile, cannot be used with registryImage
directory: container/

# Build arguments to pass when building the container image
buildArgs:
MY_BUILD_ARG: "my-value"

# Name of the registry image, cannot be used with directory
registryImage: nginx:latest

Expand Down
48 changes: 34 additions & 14 deletions deploy/lib/buildAndPushContainers.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,13 @@ function getFilesInBuildContextDirectory(directory) {

module.exports = {
async buildAndPushContainers() {
// used for pushing
const auth = {
username: "any",
password: this.provider.scwToken,
};

// used for building: see https://docs.docker.com/engine/api/v1.37/#tag/Image/operation/ImageBuild
const registryAuth = {};
registryAuth["rg." + this.provider.scwRegion + ".scw.cloud"] = {
username: "any",
password: this.provider.scwToken,
};
// Used for building: see https://docs.docker.com/engine/api/v1.37/#tag/Image/operation/ImageBuild
const registryAuth = { [`rg.${this.provider.region}.scw.cloud`]: auth };

try {
await docker.checkAuth(registryAuth);
Expand All @@ -100,22 +95,47 @@ module.exports = {
if (container["directory"] === undefined) {
return;
}

if (
container["buildArgs"] !== undefined &&
typeof container["buildArgs"] !== "object"
) {
throw new Error(
`Build arguments for container ${containerName} should be an object.

Example:
containers:
${containerName}:
directory: my-container-directory
buildArgs:
MY_BUILD_ARG: "my-value"
`
);
}

const imageName = `${this.namespace.registry_endpoint}/${container.name}:latest`;

this.serverless.cli.log(
`Building and pushing container ${container.name} to: ${imageName} ...`
);

let buildOptions = {
t: imageName,
registryconfig: registryAuth,
};

if (container.buildArgs !== undefined) {
buildOptions.buildargs = container.buildArgs;
}

// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
let files = getFilesInBuildContextDirectory(container.directory);

const buildStream = await docker.buildImage(
{ context: container.directory, src: files },
{
t: imageName,
registryconfig: registryAuth,
}
context: container.directory,
src: getFilesInBuildContextDirectory(container.directory),
},
buildOptions
);
const buildStreamEvents = await extractStreamContents(
buildStream,
Expand Down Expand Up @@ -157,7 +177,7 @@ module.exports = {
return;
}

const pushStream = await image.push(auth);
const pushStream = await image.push({ authconfig: auth });
await extractStreamContents(pushStream, this.provider.options.verbose);

resolve();
Expand Down
16 changes: 14 additions & 2 deletions deploy/lib/createContainers.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@ function adaptScalingOptionToAPI(scalingOption) {
};
}

function enrichReturnedContainerWithBuildInfo(
containerResponse,
containerConfig
) {
// We need to enrich the container object returned by the API with the build information (directory and buildArgs) provided in the serverless.yml file, for the buildAndPush step.
// This is because the API does not return those information, but they are needed for building the container.
return Object.assign(containerResponse, {
directory: containerConfig.directory,
buildArgs: containerConfig.buildArgs,
});
}

module.exports = {
createContainers() {
return BbPromise.bind(this)
Expand Down Expand Up @@ -173,7 +185,7 @@ module.exports = {
this.serverless.cli.log(`Creating container ${container.name}...`);

return this.createContainer(params).then((response) =>
Object.assign(response, { directory: container.directory })
enrichReturnedContainerWithBuildInfo(response, container)
);
},

Expand Down Expand Up @@ -223,7 +235,7 @@ module.exports = {
this.applyDomainsContainer(foundContainer.id, container.custom_domains);

return this.updateContainer(foundContainer.id, params).then((response) =>
Object.assign(response, { directory: container.directory })
enrichReturnedContainerWithBuildInfo(response, container)
);
},
};
2 changes: 2 additions & 0 deletions docs/containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ custom:
containers:
mycontainer:
directory: my-container-directory
buildArgs:
MY_BUILD_ARG: "my-value"
env:
MY_VARIABLE: "my-value"
```
Expand Down
7 changes: 6 additions & 1 deletion examples/container/my-container/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
FROM python:3-alpine

ARG VERSION=development

WORKDIR /usr/src/app

COPY requirements.txt .
RUN pip install -qr requirements.txt
COPY server.py .

CMD ["python3", "./server.py"]
ENV VERSION=${VERSION}

CMD ["python3", "./server.py"]
12 changes: 8 additions & 4 deletions examples/container/my-container/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
DEFAULT_PORT = "8080"
MESSAGE = "Hello, World from Scaleway Container !"

VERSION = os.getenv("VERSION", "unspecified")
# Scaleway's system will inject a PORT environment variable on which your application should start the server.
PORT = os.getenv("PORT", DEFAULT_PORT)

app = Flask(__name__)

@app.route("/")
Expand All @@ -16,10 +20,10 @@ def root():
def health():
# You could add more complex logic here, for example checking the health of a database...
return jsonify({
"status": "UP"
"status": "UP",
"version": VERSION
})

if __name__ == "__main__":
# Scaleway's system will inject a PORT environment variable on which your application should start the server.
port = os.getenv("PORT", DEFAULT_PORT)
app.run(host="0.0.0.0", port=int(port))
print(f"Starting server on port {PORT} with version: {VERSION}")
app.run(host="0.0.0.0", port=int(PORT))
2 changes: 2 additions & 0 deletions examples/container/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ custom:
containers:
first:
directory: my-container
buildArgs:
VERSION: "1.0"
# registryImage: ""
# port: 8080
# description: ""
Expand Down
Loading