A custom Docker image for Rust and Python
Tags: rust, python, docker
Published: 2020-04-27 00:05:09

If you're planning to deploy your Rust and Python project to Heroku or other cloud platform, you will require a Docker image, that you can also use for your local development environment, as Heroku doesn't support Python built with shared libraries, required to integrate it with Rust.

There are official Docker images of Rust and Python available from [Docker Hub](https://hub.docker.com), [here](https://hub.docker.com/_/rust) and [here](https://hub.docker.com/_/python). None of them comes with all the required tools, so a custom Docker image must be created.

The Debian Buster based Docker image will be used for the custom one, as it is already configured for Rust, Poetry and pyenv should be installed. At first a **Dockerfile** is created.

Create a directory and change to it.

```bash
mkdir rust-python && cd rust-python
```

Create an empty Dockerfile and then edit it with your favorite text editor.

```bash
touch Dockerfile
```

The Dockerfile must contain the following:

```docker
FROM rust:slim-buster
RUN apt-get -y update
RUN apt-get install -y sudo

RUN adduser --disabled-password --gecos '' admin
RUN adduser admin sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN chown -R admin /home/admin

USER admin

RUN sudo apt-get install -y python3 make build-essential libssl-dev zlib1g-dev libbz2-dev \
    libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
    xz-utils tk-dev libffi-dev liblzma-dev python-openssl git && \
    curl https://pyenv.run | bash && \
    curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3

ENV HOME /home/admin
ENV PYENV_ROOT $HOME/.pyenv
ENV POETRY_ROOT $HOME/.poetry
ENV CARGO_ROOT /usr/local/cargo
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
ENV PATH $POETRY_ROOT/bin:$PATH
ENV PATH $CARGO_ROOT/bin:$PATH
```

This custom image is based on `rust:slim-buster`. Then update the list of packages in the repositories and install `sudo`.

A new user `admin` without password is created and added to the `/etc/sudoers` file and change to this new user.

The Poetry and pyenv are installed along with their dependencies, then Poetry, Pyenv and Cargo's directories are added to the PATH environment variable.

## Build and Publish to Docker Hub
Now it's time to build the new image by running the following command:

```bash
docker build -t rust-python .
```

`rust-python` is the name of the new image created.

After the build operation is finished, list the new image and get the ID:

```bash
docker images
```

It will show something similar to the following:

```
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
rust-python            latest              7c06f720d1d3        3 hours ago         1.23GB
rust                   slim-buster         dbeae51214f7        3 weeks ago         582MB
```

Before publishing the image to Docker Hub, tag it as follows:

```
docker tag 7c06f720d1d3 username/rust-python:latest
```

Where `username` is your user at Docker Hub, `rust-python` is the name of the image as it will be listed on the account and `latest` is the tag assigned to this image.

Login to your Docker Hub account:

```bash
docker login
```

It will ask your user and password.

And finally publish to Docker Hub:

```bash
docker push username/rust-python
```

Your new image is ready to be used.