[#17] Wrote dockerfiles; moved everything to Docker
parent
7243be302c
commit
93ec27bb02
37
Dockerfile
37
Dockerfile
|
@ -1,37 +0,0 @@
|
|||
# syntax = docker/dockerfile:1.2
|
||||
|
||||
# We use a multi-stage build to end up with a very small final image
|
||||
FROM alpine:latest AS builder
|
||||
|
||||
ENV PATH "$PATH:/root/.cargo/bin"
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install build dependencies, rustup & rust's nightly build & toolchain
|
||||
RUN apk update && apk add --no-cache openssl-dev build-base curl && \
|
||||
{ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly; }
|
||||
|
||||
# Copy source code over to builder
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src/ ./src/
|
||||
|
||||
# Run the tests, don't want no broken docker image
|
||||
# And then finally, build the project
|
||||
# Thank the lords that this article exists
|
||||
# https://users.rust-lang.org/t/sigsegv-with-program-linked-against-openssl-in-an-alpine-container/52172
|
||||
# TODO add what these flags do & why they work
|
||||
# NOTE: cargo install auto-appends bin to the path
|
||||
RUN --mount=type=cache,target=/usr/src/app/target RUSTFLAGS="-C target-feature=-crt-static" cargo test && \
|
||||
RUSTFLAGS="-C target-feature=-crt-static" cargo install --path . --bin fej --root /usr/local
|
||||
|
||||
|
||||
# Now, we create the actual image
|
||||
FROM alpine:latest
|
||||
|
||||
# Install some dynamic libraries needed for everything to work
|
||||
RUN apk update && apk add --no-cache openssl libgcc
|
||||
|
||||
# Copy binary over to final image
|
||||
COPY --from=builder /usr/local/bin/fej /usr/local/bin/fej
|
||||
|
||||
CMD ["/usr/local/bin/fej"]
|
25
Makefile
25
Makefile
|
@ -1,35 +1,36 @@
|
|||
IMAGE := chewingbever/fej
|
||||
|
||||
|
||||
all: debug
|
||||
.PHONY: all
|
||||
|
||||
# Builds
|
||||
debug:
|
||||
@ cargo build
|
||||
@ ./build -m dev
|
||||
.PHONY: debug
|
||||
|
||||
release:
|
||||
@ cargo build --release
|
||||
@ ./build -m rel
|
||||
.PHONY: release
|
||||
|
||||
image: Dockerfile
|
||||
@ ./build '$(IMAGE)'
|
||||
.PHONY: image
|
||||
|
||||
push:
|
||||
@ ./build '$(IMAGE)' push
|
||||
@ ./build -m prod -a push
|
||||
.PHONY: push
|
||||
|
||||
# Run
|
||||
run:
|
||||
@ RUST_BACKTRACE=1 cargo run --bin fej
|
||||
@ ./build -m dev -a run
|
||||
.PHONY: run
|
||||
|
||||
stop:
|
||||
@ docker stop -t 2 fej
|
||||
.PHONY: stop
|
||||
|
||||
logs:
|
||||
@ docker logs -f fej
|
||||
.PHONY: logs
|
||||
|
||||
|
||||
# Testing
|
||||
test:
|
||||
@ cargo test --no-fail-fast
|
||||
@ ./build -m dev -a run -l -- test --no-fail-fast
|
||||
.PHONY: test
|
||||
|
||||
format:
|
||||
|
|
66
build
66
build
|
@ -1,10 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Simple guard to check input args
|
||||
[[ $# -eq 1 ]] || [[ $# -eq 2 ]] || {
|
||||
>&2 echo "Usage: ./build IMAGE [ACTION]"
|
||||
exit 1
|
||||
}
|
||||
image="chewingbever/fej"
|
||||
# Should be either dev or rel
|
||||
mode="dev"
|
||||
action=""
|
||||
attach="--detach"
|
||||
|
||||
while getopts ":i:m:a:l" c; do
|
||||
case $c in
|
||||
i ) image="$OPTARG" ;;
|
||||
m ) mode="$OPTARG" ;;
|
||||
a ) action="$OPTARG" ;;
|
||||
l ) attach="" ;;
|
||||
? ) exit 1 ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
# Extract current version from Cargo.toml & get current branch
|
||||
patch_version="$(grep -Po '(?<=version = ").*(?=")' Cargo.toml | head -n1)"
|
||||
|
@ -25,31 +36,58 @@ else
|
|||
|
||||
fi
|
||||
|
||||
# Run the actual build command
|
||||
DOCKER_BUILDKIT=1 docker build -t "$1:$tags" .
|
||||
# First, we build the builder
|
||||
DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile.builder -t "$image-builder:latest" .
|
||||
|
||||
if [[ "$2" = push ]]; then
|
||||
# Run the actual build command
|
||||
if [ "$mode" = "rel" ]; then
|
||||
DOCKER_BUILDKIT=1 docker build -t "$image:$tags" -f docker/Dockerfile.rel .
|
||||
|
||||
elif [[ "$mode" = "dev" ]]; then
|
||||
DOCKER_BUILDKIT=1 docker build -t "$image-dev:$tags" -f docker/Dockerfile.dev .
|
||||
|
||||
else
|
||||
>&2 echo "Invalid mode."
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
if [[ "$action" = push ]]; then
|
||||
[[ "$branch" =~ ^develop|master$ ]] || {
|
||||
>&2 echo "You can only push from develop or master."
|
||||
exit 2
|
||||
}
|
||||
|
||||
[[ "$mode" = "rel" ]] || {
|
||||
>&2 echo "You can only push release builds."
|
||||
exit 3
|
||||
}
|
||||
|
||||
for tag in "${tags[@]}"; do
|
||||
# Create the tag
|
||||
docker tag "$1:$tags" "$1:$tag"
|
||||
docker tag "$image:$tags" "$image:$tag"
|
||||
|
||||
# Push the tag
|
||||
docker push "$1:$tag"
|
||||
docker push "$image:$tag"
|
||||
|
||||
# Remove the tag again, if it's not the main tag
|
||||
[[ "$tag" != "$tags" ]] && docker rmi "$1:$tag"
|
||||
[[ "$tag" != "$tags" ]] && docker rmi "$image:$tag"
|
||||
done
|
||||
|
||||
elif [[ "$2" = run ]]; then
|
||||
docker run \
|
||||
elif [[ "$action" = run ]]; then
|
||||
if [[ "$mode" = "dev" ]]; then
|
||||
# Create caching volumes if needed (they need to be named)
|
||||
docker volume create fej_build-cache
|
||||
docker volume create fej_registry-cache
|
||||
|
||||
flags="-v fej_build-cache:/usr/src/app/target -v fej_registry-cache:/root/.cargo/registry"
|
||||
fi
|
||||
|
||||
docker run $attach $flags \
|
||||
--rm \
|
||||
--interactive \
|
||||
--tty \
|
||||
--publish 8000:8000 \
|
||||
"$1:$tags"
|
||||
--name fej \
|
||||
"$image$([[ "$mode" != "rel" ]] && echo "-dev"):$tags" "$@"
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# We use a multi-stage build to end up with a very small final image
|
||||
FROM alpine:latest AS builder
|
||||
|
||||
ARG MODE
|
||||
ARG RUN_TESTS
|
||||
|
||||
ENV PATH "$PATH:/root/.cargo/bin"
|
||||
# Needed for proper compiling of openssl-dev
|
||||
ENV RUSTFLAGS="-C target-feature=-crt-static"
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install build dependencies, rustup & rust's nightly build & toolchain
|
||||
RUN apk update && apk add --no-cache openssl-dev build-base curl && \
|
||||
{ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly; }
|
||||
|
||||
# Copy source code over to builder
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY src/ ./src/
|
|
@ -0,0 +1,6 @@
|
|||
FROM chewingbever/fej-builder:latest
|
||||
|
||||
ENV RUST_BACKTRACE=1
|
||||
|
||||
ENTRYPOINT ["cargo"]
|
||||
CMD ["run"]
|
|
@ -0,0 +1,22 @@
|
|||
FROM chewingbever/fej-builder:latest AS builder
|
||||
|
||||
# And then finally, build the project
|
||||
# Thank the lords that this article exists
|
||||
# https://users.rust-lang.org/t/sigsegv-with-program-linked-against-openssl-in-an-alpine-container/52172
|
||||
# TODO add what these flags do & why they work
|
||||
# NOTE: cargo install auto-appends bin to the path
|
||||
RUN --mount=type=cache,target=/usr/src/app/target \
|
||||
--mount=type=cache,target=/root/.cargo/registry \
|
||||
cargo install --path . --bin fej --root /usr/local
|
||||
|
||||
|
||||
# Now, we create the actual image
|
||||
FROM alpine:latest
|
||||
|
||||
# Install some dynamic libraries needed for everything to work
|
||||
RUN apk update && apk add --no-cache openssl libgcc
|
||||
|
||||
# Copy binary over to final image
|
||||
COPY --from=builder /usr/local/bin/fej /usr/local/bin/fej
|
||||
|
||||
CMD ["/usr/local/bin/fej"]
|
Loading…
Reference in New Issue