Multistage build
This commit is contained in:
5
multistage-build/.dockerignore
Normal file
5
multistage-build/.dockerignore
Normal file
@ -0,0 +1,5 @@
|
||||
**/.env/
|
||||
**/__pycache__/
|
||||
**/Makefile
|
||||
**/Dockerfile
|
||||
*.log
|
||||
31
multistage-build/Dockerfile
Normal file
31
multistage-build/Dockerfile
Normal file
@ -0,0 +1,31 @@
|
||||
FROM python:3.11-slim-bookworm
|
||||
|
||||
# set virtual env path
|
||||
ENV \
|
||||
PATH=/venv/bin:$PATH
|
||||
|
||||
# does nothing, for documentation only
|
||||
EXPOSE 3000
|
||||
|
||||
# create and set main app directory
|
||||
WORKDIR /app
|
||||
|
||||
# install sys libs and create virtual env
|
||||
RUN \
|
||||
apt update && \
|
||||
apt install -y gcc libpq-dev python3-dev && \
|
||||
python -m venv /venv
|
||||
|
||||
# copy app files to /app directory
|
||||
COPY ./app .
|
||||
|
||||
# install dependencies && cleanup
|
||||
RUN \
|
||||
pip install -r requirements.txt && \
|
||||
apt purge --auto-remove -y
|
||||
|
||||
# start shell script when container starts
|
||||
ENTRYPOINT ["/app/run.sh"]
|
||||
|
||||
# no additional parameters to run.sh script
|
||||
CMD []
|
||||
51
multistage-build/Dockerfile.multistage
Normal file
51
multistage-build/Dockerfile.multistage
Normal file
@ -0,0 +1,51 @@
|
||||
FROM python:3.11-slim-bookworm AS install-dependencies
|
||||
|
||||
# create and set main app directory
|
||||
WORKDIR /app
|
||||
|
||||
# set virtual env path
|
||||
ENV \
|
||||
PATH=/venv/bin:$PATH
|
||||
|
||||
# install sys libs and create virtual env
|
||||
RUN \
|
||||
apt update && \
|
||||
apt install -y gcc libpq-dev python3-dev && \
|
||||
python -m venv /venv
|
||||
|
||||
# copy app files to /app directory
|
||||
COPY ./app/requirements.txt .
|
||||
|
||||
# install dependencies && cleanup
|
||||
RUN \
|
||||
pip install -r requirements.txt
|
||||
|
||||
|
||||
FROM python:3.11-slim-bookworm
|
||||
|
||||
# set virtual env path
|
||||
ENV \
|
||||
PATH=/venv/bin:$PATH
|
||||
|
||||
# does nothing, for documentation only
|
||||
EXPOSE 3000
|
||||
|
||||
# create and set main app directory
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=install-dependencies /venv /venv
|
||||
|
||||
# copy app files to /app directory
|
||||
COPY ./app .
|
||||
|
||||
RUN ls -alF /
|
||||
RUN ls -alF /venv
|
||||
RUN ls -alF /venv/bin
|
||||
RUN ls -alF /app
|
||||
|
||||
|
||||
# start shell script when container starts
|
||||
ENTRYPOINT ["/app/run.sh"]
|
||||
|
||||
# no additional parameters to run.sh script
|
||||
CMD []
|
||||
28
multistage-build/Makefile
Normal file
28
multistage-build/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
IMAGE_NAME=api-server-ms
|
||||
CONTAINER_NAME=api-server-ms
|
||||
|
||||
build: clean
|
||||
@docker build \
|
||||
--progress=plain \
|
||||
--tag $(IMAGE_NAME) \
|
||||
.
|
||||
|
||||
build-multistage: clean
|
||||
@docker build \
|
||||
--progress=plain \
|
||||
--tag $(IMAGE_NAME) \
|
||||
--file Dockerfile.multistage \
|
||||
.
|
||||
|
||||
run:
|
||||
@docker run \
|
||||
--name $(IMAGE_NAME) \
|
||||
--publish 3000:3000 \
|
||||
--env CONTAINER_NAME="Awesome API server" \
|
||||
--detach \
|
||||
$(CONTAINER_NAME)
|
||||
|
||||
clean:
|
||||
- @docker stop $(CONTAINER_NAME)
|
||||
- @docker rm $(CONTAINER_NAME)
|
||||
- @docker rmi $(IMAGE_NAME)
|
||||
2
multistage-build/app/Makefile
Normal file
2
multistage-build/app/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
run:
|
||||
@./run.sh
|
||||
29
multistage-build/app/main.py
Normal file
29
multistage-build/app/main.py
Normal file
@ -0,0 +1,29 @@
|
||||
from fastapi import FastAPI
|
||||
import logging
|
||||
import os
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
LOG_FILE = "./log/api-server.log"
|
||||
CONTAINER_NAME = os.environ.get("CONTAINER_NAME", "Unknown")
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
logging.info(f"Container {CONTAINER_NAME} received request")
|
||||
return {
|
||||
"message": f"Hello World from {CONTAINER_NAME}",
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
logging.basicConfig(
|
||||
filename=LOG_FILE,
|
||||
format="%(asctime)s %(levelname)s %(message)s",
|
||||
level=logging.INFO,
|
||||
)
|
||||
logging.info(f"Starting server {CONTAINER_NAME}")
|
||||
|
||||
|
||||
main()
|
||||
3
multistage-build/app/requirements.txt
Normal file
3
multistage-build/app/requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
fastapi
|
||||
uvicorn
|
||||
psycopg2
|
||||
9
multistage-build/app/run.sh
Executable file
9
multistage-build/app/run.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/sh
|
||||
|
||||
# start command with exec to replace execution shell and properly receive signals from docker
|
||||
# without exec, container can't be gracefully terminated with ctrl+c or docker stop
|
||||
exec uvicorn \
|
||||
main:app \
|
||||
--host 0.0.0.0 \
|
||||
--port 3000 \
|
||||
--lifespan off
|
||||
Reference in New Issue
Block a user