diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..8985d30b3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM ubuntu:22.04 +RUN apt-get update && \ + apt-get install -y \ + python3 -y \ + python3-pip -y && \ + groupadd -g 1234 notroot && \ + useradd -m -u 1234 -g notroot notroot +USER notroot +WORKDIR /app +COPY requirements.txt . +RUN pip install -r requirements.txt +COPY app . +EXPOSE 5000 +CMD ["python3", "app.py"] \ No newline at end of file diff --git a/M1-3-Ansible/README.md b/M1-3-Ansible/README.md new file mode 100644 index 000000000..e44faf9c3 --- /dev/null +++ b/M1-3-Ansible/README.md @@ -0,0 +1,36 @@ +# M1-3-1 Configuration Management + +## Ansible Task + +Create an Ansible playbook that build, push and then run the Docker image for the Python +application. Let your playbook has the following variables: + +* `image_name` - contains the name of your image without the tag, i.e. `vutoff/python-app` +* `image_tag` - contains the tag you tagged your image with, i.e. `v0.2` +* `listen_port` - contains the listening port you're binding your app to. + +Make sure that you set environment variable `PORT` when you define your container +in the Ansible playbook that takes its value from `listen_port` variable. + +Use Ansible modules. Do not shell out. + +### Requirements + +* Make sure you have Python installed. Any version above 3.8 would suffice. +* The `requirements.txt` file in this directory contains the required Ansible version. Run + +```sh +pip install -r requirements.txt +``` + +* Make sure that Docker is running on your local machine. + +### Mind the following + +* If you're running Docker Desktop or Rancher Desktop, mind the location of the `docker.sock` file. The location of the socket file is + * Docker Desktop - `${HOME}/.docker/run/docker.sock` + * Rancher DEsktop - ${HOME}/.rd/run/docker.sock + +* If you're using one of the above, when you write your Ansible playbook you +must specify the path to the docker socket with the parameter `docker_host`, +i.e. `docker_host: "unix://{{ ansible_env.HOME }}/.rd/docker.sock"`. diff --git a/M1-3-Ansible/docker-playbook.yml b/M1-3-Ansible/docker-playbook.yml new file mode 100644 index 000000000..0819458d9 --- /dev/null +++ b/M1-3-Ansible/docker-playbook.yml @@ -0,0 +1,76 @@ +- name: Build, push and run Docker container + hosts: localhost + vars: + image_name: "ghristov/practice1" + image_tag: "e934bdd" + listen_port: 8080 + full_image_name: "{{ image_name }}:{{ image_tag }}" + dockerfile_path: "../" + + tasks: + - name: Is Docker Python SDK installed + pip: + name: docker + state: present + become: true + + - name: Is Dockerfile exists in parent dir + stat: + path: "{{ dockerfile_path }}/Dockerfile" + register: dockerfile_check + + - name: Fail if Dockerfile is missing + fail: + msg: "Dockerfile not found" + when: not dockerfile_check.stat.exists + + - name: Build Docker image + community.docker.docker_image: + name: "{{ image_name }}" + tag: "{{ image_tag }}" + source: build + build: + path: "{{ dockerfile_path }}" + pull: yes + force_source: yes + state: present + register: build_result + + - name: Log into Docker registry + community.docker.docker_login: + username: "{{ docker_username }}" + password: "{{ docker_password }}" + when: docker_username is defined and docker_password is defined + register: login_result + + - name: Push Docker image to registry + community.docker.docker_image: + name: "{{ full_image_name }}" + push: yes + source: local + when: + - docker_username is defined + - docker_password is defined + - build_result is succeeded + register: push_result + + - name: If existing container then remove + community.docker.docker_container: + name: ansible-test + state: absent + force_kill: yes + ignore_errors: yes + + - name: Run Docker container + community.docker.docker_container: + name: ansible-test + image: "{{ full_image_name }}" + state: started + recreate: yes + pull: false + ports: + - "{{ listen_port }}:{{ listen_port }}" + env: + PORT: "{{ listen_port | string }}" + restart_policy: unless-stopped + when: build_result is succeeded \ No newline at end of file diff --git a/M1-3-Ansible/requirements.txt b/M1-3-Ansible/requirements.txt new file mode 100644 index 000000000..a1a99e359 --- /dev/null +++ b/M1-3-Ansible/requirements.txt @@ -0,0 +1,12 @@ +ansible==10.3.0 +ansible-compat==24.9.1 +ansible-core==2.17.5 +ansible-lint==24.9.2 +blinker==1.6.3 ; python_version >= "3.10" and python_version < "4.0" +click==8.1.7 ; python_version >= "3.10" and python_version < "4.0" +colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows" +flask==3.0.0 ; python_version >= "3.10" and python_version < "4.0" +itsdangerous==2.1.2 ; python_version >= "3.10" and python_version < "4.0" +jinja2==3.1.2 ; python_version >= "3.10" and python_version < "4.0" +markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "4.0" +werkzeug==3.0.0 ; python_version >= "3.10" and python_version < "4.0" \ No newline at end of file diff --git a/app/app.py b/app/app.py index 67e0180c0..1c2c83d55 100644 --- a/app/app.py +++ b/app/app.py @@ -11,4 +11,4 @@ def hello_world(): if __name__ == "__main__": - app.run(port=os.environ.get("PORT", 3000), host="0.0.0.0") + app.run(port=os.environ.get("PORT", 5000), host="0.0.0.0") diff --git a/requirements.txt b/requirements.txt index b5ba78cca..5ea80b143 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,2 @@ -blinker==1.6.3 ; python_version >= "3.10" and python_version < "4.0" -click==8.1.7 ; python_version >= "3.10" and python_version < "4.0" -colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows" -flask==3.0.0 ; python_version >= "3.10" and python_version < "4.0" -itsdangerous==2.1.2 ; python_version >= "3.10" and python_version < "4.0" -jinja2==3.1.2 ; python_version >= "3.10" and python_version < "4.0" -markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "4.0" -werkzeug==3.0.0 ; python_version >= "3.10" and python_version < "4.0" +flask==3.0.0