OSDC Lesson 6: Dockers
Tags: osdc
Published: 2023-02-12 15:20:15

---
title: OSDC Lesson 6: Dockers
published: true
series: OSDC
description: 
tags: #osdc
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-02-12 12:58 +0000
---
# Exit code in tests
## R tests
Testthat is a library for tests in R

### Exit code
Every program that runs on the command line sends an exit code after finishing.

Show the exit code of the last run program on the command line
```
echo $?
```

Programs that finished successfully without errors return exit code 0.

In languages like R, that have no `assert` like python, when in tests, when I don't get the desired result, I will exit and send an exit code of anything but 0.
```
exit(1)
```

# Docker
* An encapsulation of a unified environment. 
* Define a very specific environment.
* One can control the environment.
* Install a development environment relatively easily.
* Separates between my computer to where I run code (eg when I download software from the web). With Docker I can limit the files that the Docker can see, as I map specific folder to docker.

## Run docker
```
docker run --rm -it ubuntu:22.04 bash
```
`--rm` : remove the docker when finishes
`--it` : interactive
`bash` : run bash inside the docker
`ubuntu` : is the image
`22.04` : Is a tag, normally a version of the image and contains the year and month
```
Unable to find image 'ubuntu:22.04' locally
22.04: Pulling from library/ubuntu
677076032cca: Pull complete
Digest: sha256:9a0bdde4188b896a372804be2384015e90e3f84906b750c1a53539b585fbbe7f
Status: Downloaded newer image for ubuntu:22.04
root@202e3c005b89:/#
```
Docker pulled the specific image from the image repository as it didn't find it locally on my computer.

Then I entered the docker into the `bash` command line.

```
root@202e3c005b89:/# apt-get update
```
Will bring me all the latest packages

```
root@202e3c005b89:/# apt-get install python3
root@202e3c005b89:/# python3
>>>
```
Now I can run python commands inside the docker...

Everything I will run will happen inside the docker container's file system.

Exit the image
```
root@202e3c005b89:/# exit
```

When I exit the docker everything will be removed.The file system of the docker container will be deleted (unless I use the -v flag, explained next).

There are many images in the [docker hub](https://hub.docker.com). I can select any image that suits my purpose.

e.g. a python docker
```
docker run --rm -it python:3.22
```

#### [PyDigger](https://pydigger.com)
A site that crawls the web and collects information about python packages

Look for an open source project to which you can contribute.

Clone the project by copying the project's ssh URL.

To see the source code inside the docker. I will ask the docker to map the project's folder to the docker's file system.
```
 docker run -it --rm -v /mnt/c/Users/shuly.avraham/
work/LIMS_results_validation/:/opt python:3.11 bash
```
The project's folder on my computer was mapped to the `opt/` folder within the docker.

Now I can access the project's folder from within the docker container.

```
root@c6e9d5452e5f:/# ls opt/
```
I can still edit the project's files using my preferred editor on the computer and it will take effect inside the docker container.

### Run tests inside the docker
```
pytest -svv tests/ 
```
where `tests/` is the folder in which I write my tests, which name start with `test_`.

### Dockerfile
Is a file where I write the configuration of my docker. I can start with a docker from docker hub and install more packages on it.

If I'm in a container, after installing several packages, if I leave the docker, the installations will be lost. I can then create an image from the container
```
docker freeze
```
Will create an image from within the container

The disadvantage is that I don't know what I installed.

A better way is to write a dockerfile with everything I want to install in my image. Let's call it `mydocker`
```
docker build -t mydocker
```

#### An alias to easily run docker from `mydocker` dockerfile
```
alias dr='docker run -it --rm --workdir /opt -v $(pwd):/opt mydocker bash'
```

## GitHub Actions for Continous Integration
After I added tests to a project and pushed them to git, I will configure the CI in GitHub to run the tests automatically in every push/pull_request (and other) attempt.

GitHub actions is a service of GitHub where I can run commands on GitHub servers.

I will have my own server/s in GitHub in which I can run commands, and the server/s will close after the commands finish.

In order to configure it I will create a special directory and `ci.yml` file inside my project's git root dir:
```
mkdir -p .github/workflows
```
Inside it I will create a file `ci.yml` and edit it to configure the servers in which I will run my tests, and decide which OS and which languages versions
```
vi .github/workflows/ci.yml
```

Now `git push` will run my tests on the servers and configurations I mentioned in  the `ci.yml` file. 

I can go to the GitHub website of the project and check whether the tests succeeded or failed.