I have a Flask API inside a Docker container, the purpose of this project is to scrapp my schools' system, and get all the class schedules in order to generate all the possible combinations of schedules for a student. Everything runs just fine. However, I have an endpoint that serves for the purpose of scrapping my schools' webpage (I have to do it manually and it's VITAL in order to run the other functions that consume that information).
I created a bash script that sends a GET request to that endpoint that I mentioned previously:
#!/bin/bash
URL="http://localhost:5555/FetchGroupDataUPSite"
max_retries=3
retries=0
delay=5
echo "Sending GET request to scrapper endpoint..."
while [ $retries -lt $max_retries ]
do
response=$(curl -s -o /dev/null -w "%{http_code}" -X GET $URL)
if [ $response -eq 200 ]
then
echo "Scrapper script completed."
break
else
echo "Request failed with status code $response. Retrying in $delay seconds..."
retries=$((retries+1))
sleep $delay
fi
done
if [ $retries -eq $max_retries ]
then
echo "Maximum number of retries reached. Scrapper script failed."
fi
Is it possible to run that bash script every time I build the docker container after all the services started?
I'm also open to hear suggestions to different approaches to solve this problem (My approach could be completely wrong)
Here is my docker-compose and Dockerfile files in case it's necessary:
docker-compose.yml:
version: '3.8'
networks:
app-tier:
driver: bridge
services:
db:
image: mysql:5.7
container_name: UP_DB
restart: always
environment:
MYSQL_ROOT_PASSWORD: ***
MYSQL_PASSWORD: ***
MYSQL_DATABASE: ***
MYSQL_USER: ***
command: --default-authentication-plugin=mysql_native_password --bind-address=0.0.0.0 --explicit_defaults_for_timestamp
volumes:
- ./sql:/docker-entrypoint-initdb.d
ports:
- 3306:3306
networks:
- app-tier
adminer:
image: adminer
container_name: UP_Adminer
restart: always
ports:
- 8080:8080
networks:
- app-tier
api:
container_name: UP_API
stdin_open: true
tty: true
restart: always
build: .
ports:
- 5555:5555
volumes:
- ./App:/SmartUP/App
networks:
- app-tier
Dockerfile
FROM python:3.10.7-buster
WORKDIR /SmartUP
COPY . .
ENV FLASK_ENV development
ENV DEBUG true
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get install -y wget
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
RUN apt-get -y update
RUN apt-get install -y google-chrome-stable
RUN apt-get install -yqq unzip
RUN wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
# Unzip the Chrome Driver into /usr/local/bin directory
RUN unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/
# Set display port as an environment variable
ENV DISPLAY=:99
RUN pip install --upgrade pip && pip3 install -r requirements.txt
CMD ["python", "App/run.py"]
# Makes the file executable
EXPOSE 5555
Thank you in advance for taking the time to answer my question 😁.
Just run the script as required. You don't need to do anything Docker-specific for it. If you're running it on the same host as the containers, then when it curl http://localhost:5555/...
, it will reach the container via its published ports:
.
If you want this to be triggered every time you restart the container stack, then you could package this into a script
#!/bin/sh
docker-compose up --build -d
./trigger-scraper
The script already contains a retry loop. Even if you run the script before the container stack is fully functional, you'll go into that retry loop and it might work the second or third time as things start up. (You may need to wait longer than 15 seconds for the database container to be fully usable.)