Hello,
I'm buidling a personal project of web application for which I need to create a little REST API service. I chose to use Rust but it's my first experience with Rust on a web server, I'm more used to things like Python PHP, etc.
I also chose to containerize my API with docker and I can't figure out how am I suppose to do to have a fluid development workflow and a efficient deployment process.
Most of the tutorials I read says that it's a good practice to use a multistage building of the docker image in order to compile the code in an intermediate docker layer and then create the final image only with the compile binary. But I don't understand how am I supposed to do to update the code without having to recreate the entire image or at least stopping the container.
So for now I tried a temporary solution: I have a full rust:buster-slim image, my source code is bound into the container with a volume and I compile and execute the binary into the container wih cargo run
the same way I would do it ouside the container. It takes way less time than rebuilding the image because I don't lose the compilation cache and the container remains the same.
This solution is working for now because I'm only developing locally. But I don't think I could use that in production because I have to stop and restart the container for each upgrade of my api.
So my request for help is about which concepts and type of architecture should I look after in order to have a dynamic development and deployment workflow.
This is my current docker-compose and Dockerfile:
# docker-compose.yml
version: "3.9"
services:
rust_api:
build: .
depends_on:
- mentalodb
container_name: "rust-api-container"
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./src:/usr/src/rust_api/src
command: cargo run --release
mentalodb:
image: "mongo"
container_name: "mongo-test-container"
environment:
- MONGO_INITDB_DATABASE=mentalodb
- MONGO_INITDB_ROOT_USERNAME=********
- MONGO_INITDB_ROOT_PASSWORD=*********
volumes:
- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
- /var/mongo-volume:/data/db
ports:
- "27017-27019:27017-27019"
# Dockerfile
FROM rust:1.50-slim-buster
WORKDIR /usr/src/rust_api
COPY ./Cargo.toml ./Cargo.toml
COPY ./src ./src
And I reload the api if I make changes in the code simply by doing docker-compose stop rust_api && docker-compose up rust_api
, wich triggers the cargo run
command.
So this is a simplistic temporary solution but I don't understand how I should do it the right way.