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.