I am using just a single node for my project. But I still want to use docker swarm mode, to learn and for possible scaling later.
I want to write a github action workflow file that will create such a swarm, run pytest on the container, and if tests pass, push code to production server.
On my development local machine, following commands work:
docker swarm init
docker stack deploy -c docker-compose.yml ex
docker exec $(docker ps -q -f name=ex_backend) pytest
Corresponding github action workflow do not work though:
- run: docker swarm init
- run: docker stack deploy -c docker-compose.yml ex
- run: docker exec $(docker ps -q -f name=ex_backend) pytest
I get the error "docker exec" requires at least 2 arguments.
Upon inspection I notice that docker ps -q -f name=ex_backend
does not return anything, hence the last command fails.
- run: docker service ps ex_backend
shows:
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ppfwcobs1x33 ex_backend.1 xxx/ex_backend:0.0.1 fv-az36-929 Running Preparing less than a second ago
- run: docker service ls
shows following:
ID NAME MODE REPLICAS IMAGE PORTS
hzp5gigrmjm4 ex_backend replicated 0/1 xxx/ex_backend:0.0.1 *:8888->8888/tcp
iuaparyt8qws ex_postgres replicated 0/1 postgres:12 *:5432->5432/tcp
In my local machine replicas column value is '1/1'. Here '0/1'.
So, does that mean container is not started? I am new to docker swarm and github actions and stuck here at this point. How can I run pytest in the ex_backend service?
EDIT: here is the full workflow file(.github/workflows/build.yml):
name: Build and Deploy
on:
push:
branches:
- "main"
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Get the code from github
uses: actions/checkout@v2
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- run: docker swarm init
- run: docker stack deploy -c docker-compose.yml exs --with-registry-auth
- run: docker exec $(docker ps -q -f name=exs_backend) pytest -x
And docker-compose.yml:
version: "3.7"
services:
backend:
image: xxx/exi_backend:latest
ports:
- 8888:8888
tty: true
volumes:
- ./backend:/app/:cached
- ./.docker/.ipython:/root/.ipython:cached
environment:
PYTHONPATH: .
DATABASE_URL: "postgresql://postgres:postgres123@postgres:5432/postgres"
depends_on:
- "postgres"
command: bash -c "uvicorn app.main:app --host 0.0.0.0 --port 8888 --reload"
postgres:
image: postgres:12
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres123
ports:
- "5432:5432"
volumes:
- db-data:/var/lib/postgresql/data:cached
volumes:
db-data: