» Rust: Make Web Chat App with Socket.IO » 3. Deployment » 3.1 Dockerfile

Dockerfile

Docker allows developers to package their applications along with all dependencies into a single unit called a container. This ensures consistency across different environments, such as development, testing, and production, reducing the "it works on my machine" problem.

Add Makefile

A Makefile is a special file used in software development projects, particularly in Unix-like operating systems, to automate the compilation and building of executable programs or libraries from source code.

Add Makefile:

# Binary name
BINARY_NAME=lr_webchat_rs

.PHONY: lint

lint:
	@echo "Linting..."
	cargo clippy

build:
	@echo "Building $(BINARY_NAME)..."
	cargo build --release --bin $(BINARY_NAME)

Clippy is a well-known linting tool for the Rust.

Run make build to build a binary:

make build

This is equivalent to cargo build --release --bin lr_webchat_rs. It will create a binary file named lr_webchat_rs in your project's target/release folder.

Then, you can just run it as a standalone server:

./target/release/lr_webchat_rs

Dockerfile for the service

Add Dockerfile:

# Use a Rust Docker image as the base
FROM rust:1.77-alpine3.19 as builder

# Set the working directory inside the container
WORKDIR /app

# Install necessary packages
RUN apk update && \
    apk add --no-cache musl-dev pkgconfig openssl-dev

# Copy the Rust project files to the container
COPY Cargo.toml .
COPY src/ /app/src

# Define a build argument with a default value
ARG BINARY_NAME=lr_webchat_rs

# Build the Rust project
# See: https://github.com/rust-lang/rust/issues/115430
RUN RUSTFLAGS="-Ctarget-feature=-crt-static" cargo build --release --bin ${BINARY_NAME}

# Start a new stage from Alpine Linux
FROM alpine:3.19

# Install required packages
RUN apk update && \
    apk add --no-cache libgcc

# Define an environment variable from the build argument
ENV BINARY_NAME=lr_webchat_rs

# Set the working directory inside the container
WORKDIR /app

# Copy the built binary from the previous stage to the current stage
COPY --from=builder /app/target/release/${BINARY_NAME} .

# Command to run the binary when the container starts
CMD ./${BINARY_NAME}

With this Dockerfile, we‘re ready to run it with the front-end app in the Docker Compose.