Compare commits
	
		
			3 Commits 
		
	
	
		
			7243be302c
			...
			c51401f7d8
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						c51401f7d8 | |
| 
							
							
								
									
								
								 | 
						34b32a3252 | |
| 
							
							
								
									
								
								 | 
						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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										76
									
								
								build
								
								
								
								
							
							
						
						
									
										76
									
								
								build
								
								
								
								
							| 
						 | 
				
			
			@ -1,18 +1,27 @@
 | 
			
		|||
#!/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)"
 | 
			
		||||
major_version="$(echo "$patch_version" | 
 | 
			
		||||
    sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1/')"
 | 
			
		||||
minor_version="$(echo "$patch_version" |
 | 
			
		||||
    sed -E 's/([0-9]+).([0-9]+).([0-9]+)/\1.\2/')"
 | 
			
		||||
branch="$(git branch --show-current)"
 | 
			
		||||
patch_version=`grep -Po '(?<=version = ").*(?=")' Cargo.toml | head -n1`
 | 
			
		||||
major_version=`echo "$patch_version" | sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1/'`
 | 
			
		||||
minor_version=`echo "$patch_version" | sed -E 's/([0-9]+).([0-9]+).([0-9]+)/\1.\2/'`
 | 
			
		||||
branch=`git rev-parse --abbrev-ref HEAD`
 | 
			
		||||
 | 
			
		||||
if [[ "$branch" = "master" ]]; then
 | 
			
		||||
    tags=("$patch_version" "$minor_version" "$major_version" "latest")
 | 
			
		||||
| 
						 | 
				
			
			@ -25,31 +34,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