Compare commits

...

9 Commits

Author SHA1 Message Date
fcffbdb8f5 Media 2024-01-12 11:00:39 +01:00
e12386decf Update media 2024-01-12 10:55:51 +01:00
fef5fbc220 Media 2024-01-12 10:49:15 +01:00
4c20c41426 Add application user 2024-01-12 10:29:26 +01:00
10966f3c1f Update drawing 2024-01-11 21:27:58 +01:00
bec5fc997e Tweaks 2024-01-11 14:25:28 +01:00
516e17a8d8 Merge branch 'multistage-build' 2024-01-11 13:20:16 +01:00
176d22bbe4 Multistage build 2024-01-11 13:20:06 +01:00
d96368feb6 Add comments 2024-01-11 12:28:55 +01:00
20 changed files with 6106 additions and 1814 deletions

88
README.md Normal file
View File

@ -0,0 +1,88 @@
## Uvod
- Docker je platforma za development, delivery i izvršavanje aplikacija
- Docker omogućava da se aplikacija izolira u repetativnoj okolini i odvoji od infrastrukture
[Features of Docker](https://www.geeksforgeeks.org/features-of-docker/):
- Open-source platform
- An Easy, lightweight, and consistent way of delivery of applications
- Fast and efficient development life cycle
- Segregation of duties
- Service-oriented architecture
- Security
- Scalability
- Reduction in size
- Image management
- Networking
- Volume management
## Struktura
- Dockerfile
- image
- container registry
- lokalni
- dockerhub
- AWS ECR
- container
## Dockerfile
- base image
- odabir najmanjeg funkcionalnog
- debian prije ubuntua
- debian-slim prije debiana
- alpine
- from scratch
- env varijable
## Docker image
- single stage build
- multistage build
## Docker container
run, publish port 3000:
```
docker run --name api-server-3000 --publish 3000:3000 --env CONTAINER_NAME="Awesome API server on port 3000" -d api-server
```
run, publish port 3001:
```
docker run --name api-server-3001 --publish 3001:3000 --env CONTAINER_NAME="Awesome API server on port 3001" -d api-server
```
run, publish port 3002:
```
docker run --name api-server-3002 --publish 3002:3000 --env CONTAINER_NAME="Awesome API server on port 3002" -d api-server
```
# Media
## Docker vs VM
![Docker vs VM](media/docker-vs-vm.svg)
## Docker elements
![Docker elements](media/docker-elements.svg)
## Dockerfile layers
![Dockerfile layers](media/dockerfile-layers.svg)
## Port publishing
![Port publishing](media/port-publishing.svg)
## Horizontal scaling
![Horizontal scaling](media/horizontal-scaling.svg)
## Volumes
![Volumes](media/volumes.png)

View File

@ -1,18 +1,32 @@
FROM python:3.11-slim-bookworm
# uid to run application
ARG USER=1000
# gid to run application
ARG USER_GROUP=1000
# 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 app files to /app directory
COPY ./app .
# set permissions to log directory and install dependencies
RUN \
chown -R ${USER}:${USER_GROUP} /app/log && \
python -m venv /venv && \
pip install -r requirements.txt
# set user to run application
USER ${USER}:${USER_GROUP}
# start shell script when container starts
ENTRYPOINT ["/app/run.sh"]

View File

@ -1,13 +1,14 @@
IMAGE_NAME=api-server
CONTAINER_NAME=api-server
build: clean
@docker build \
--progress=plain \
--no-cache \
--tag $(IMAGE_NAME) \
.
run:
@docker run \
--name $(IMAGE_NAME) \
@ -16,6 +17,7 @@ run:
--detach \
$(CONTAINER_NAME)
run-mount-log:
@docker run \
--name $(IMAGE_NAME) \

File diff suppressed because it is too large Load Diff

21
media/docker-elements.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 181 KiB

21
media/docker-vs-vm.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 299 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 103 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 44 KiB

21
media/port-publishing.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 120 KiB

BIN
media/volumes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

86
media/volumes.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -0,0 +1,5 @@
**/.env/
**/__pycache__/
**/Makefile
**/Dockerfile
*.log

View File

@ -0,0 +1,40 @@
FROM python:3.11-slim-bookworm
# uid to run application
ARG USER=1000
# gid to run application
ARG USER_GROUP=1000
# 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 .
# set permissions to log directory and install dependencies && cleanup
RUN \
chown -R ${USER}:${USER_GROUP} /app/log && \
pip install -r requirements.txt && \
apt purge --auto-remove -y
# set user to run application
USER ${USER}:${USER_GROUP}
# start shell script when container starts
ENTRYPOINT ["/app/run.sh"]
# no additional parameters to run.sh script
CMD []

View File

@ -0,0 +1,56 @@
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
# uid to run application
ARG USER=1000
# gid to run application
ARG USER_GROUP=1000
# 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 .
# set permissions to log directory
RUN chown -R ${USER}:${USER_GROUP} /app/log
# set user to run application
USER ${USER}:${USER_GROUP}
# start shell script when container starts
ENTRYPOINT ["/app/run.sh"]
# no additional parameters to run.sh script
CMD []

33
multistage-build/Makefile Normal file
View File

@ -0,0 +1,33 @@
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" \
--volume /var/log/api-server:/app/log \
--detach \
$(CONTAINER_NAME)
clean:
- @docker stop $(CONTAINER_NAME)
- @docker rm $(CONTAINER_NAME)
- @docker rmi $(IMAGE_NAME)

View File

@ -0,0 +1,2 @@
run:
@./run.sh

View 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()

View File

@ -0,0 +1,3 @@
fastapi
uvicorn
psycopg2

9
multistage-build/app/run.sh Executable file
View 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