Deploying the Resource Type¶
To properly “deploy” the resource type, your repo should look something like this:
.
|-- Dockerfile
|-- README.md
|-- assets
| |-- check
| |-- in
| |-- out
|-- requirements.txt
|-- concourse.py
|-- tests.py
Resource Module¶
The concourse.py module contains your Version and
ConcourseResource subclasses. It can be called whatever you like, but concourse.py
is the most clear, and is the default for the CLI.
Note
It is possible to split your code into multiple modules, or even packages. This is sometimes useful if you have written a lot of code, or if it naturally splits. However, make sure that this code is also put in the correct place in your Docker image.
Requirements¶
The requirements.txt file should contain a complete list of requirements within your virtual environment (version
pinned) sufficient to reproduce with
$ pip install -r requirements.txt --no-deps
If this is not possible, then rewrite your requirements file. If you have any dependencies which are not public, then you will have to make some adjustments to your Dockerfile.
Assets¶
The contents of each of the files in assets follow the same pattern. For example, here is the contents of
assets/check:
#!/usr/bin/env python3
"""
Check for new versions of the resource.
"""
from concourse import MyResource
if __name__ == "__main__":
MyResource.check_main()
It is these files which get called by Concourse as part of the resource. Note that none of the asset files have any
extensions, but specific their executable at the top of the file. MyResource should correspond to your
ConcourseResource subclass, and resource to the module in which you have
placed it. Replace check_main() with
in_main() and
out_main() for assets/in and assets/out respectively.
Important
Every file in assets need to be executable. This can be done with
$ chmod +x assets/*
Tip
Because this pattern is suitable for almost every resource type, you can automate the creation of the assets
folder with the assets CLI command.
Dockerfile Structure¶
The Dockerfile should look something like:
1FROM python:3.13
2
3RUN python3 -m venv /opt/venv
4# Activate venv
5ENV PATH="/opt/venv/bin:$PATH"
6
7COPY requirements.txt requirements.txt
8
9RUN \
10 python3 -m pip install --upgrade pip && \
11 pip install -r requirements.txt --no-deps
12
13WORKDIR /opt/resource/
14COPY concourse.py ./concourse.py
15RUN python3 -m concoursetools . -r concourse.py
16
17ENTRYPOINT ["python3"]
Tip
You can automate the creation of this file with the dockerfile CLI command.
Base Image¶
1FROM python:3.13
You should adjust the base image according to your requirements. Concourse Tools will default to python:<version>,
where <version> corresponds to the current major/minor version you are running. However, you may wish to specify
a different base image, such as python:3.*-slim or python:3.*-alpine.
Virtual Environment¶
3RUN python3 -m venv /opt/venv
4# Activate venv
5ENV PATH="/opt/venv/bin:$PATH"
There is much debate as to whether or not it is worth creating a virtual environment within a Docker container. Concourse Tools chooses to create one by default in order to maximise the similarity between code running on the image and code running locally.
Installing Requirements¶
7COPY requirements.txt requirements.txt
8
9RUN \
10 python3 -m pip install --upgrade pip && \
11 pip install -r requirements.txt --no-deps
By default, Concourse Tools will copy over the requirements.txt file to use for the resource dependencies.
The installation process is a single command involving two parts:
Updating
pipto ensure the latest available version at build time,Installing the static requirements file without implicit dependencies.
If these were two separate commands then Docker would cache the first one and pip would never be upgraded.
Note
By passing --no-deps we ensure that the requirements.txt file is fully complete, and we are not missing
any implicit dependencies.
Including Certs in your Docker Build¶
Changed in version 0.8: In previous versions the advice was to use multi-stage builds for this. Although that practice is equally secure, it makes sense to use Docker secrets instead.
If any of your requirements are private then you will need to make your private keys available to the image during the
build process, without storing them within the image itself. This can be done by making the following change to the
RUN command from previous section:
7COPY requirements.txt requirements.txt
8
9RUN \
10 --mount=type=secret,id=private_key,target=/root/.ssh/id_rsa,mode=0600,required=true \
11 --mount=type=secret,id=known_hosts,target=/root/.ssh/known_hosts,mode=0644 \
12 python3 -m pip install --upgrade pip && \
13 pip install -r requirements.txt --no-deps
The secrets must then be passed at build time:
$ docker build \
--secret id=private_key,src=~/.ssh/id_rsa \
--secret id=known_hosts,src=~/.ssh/known_hosts \
.
The files are then mounted securely using the correct permissions.
Creating Asset Files¶
13WORKDIR /opt/resource/
14COPY concourse.py ./concourse.py
15RUN python3 -m concoursetools . -r concourse.py
Concourse requires that your asset files are placed in /opt/resource on the container, which is done here using
the Concourse Tools CLI to reduce the required code.
Warning
If you cannot use the CLI to create your assets folder, then you should manually copy your asset
files across to /opt/resource.
If your resource requires additional modules to work, then you need to ensure they are also copied across before the CLI is invoked:
13WORKDIR /opt/resource/
14COPY concourse.py ./concourse.py
15COPY extra.py ./extra.py
16RUN python3 -m concoursetools . -r concourse.py
Entry Point¶
17ENTRYPOINT ["python3"]
Finally, we specify an ENTRYPOINT for the container. This has little bearing on the resource itself as Concourse
will specify the scripts it wishes to invoke via the shebang in the scripts. It isn’t even used when hijacking the
container (the default is bash). However, it is best practice to set something, and this should make it easiest to
debug locally.