OS / Reproducible Builds
List all daemons running on the OS.
ps -e --no-headers -o pid,tty,comm | grep '^ *[0-9]* *\?' | wc -l
ps -e
: Lists all processes.-o for what variables need to be in the output
pid,tty,comm
: Displays the process ID (PID), terminal (TTY), and command name (comm).grep '^ *[0-9]* *\?'
: Filters processes whereTTY
is?
, which indicates background (daemon) processes.wc -l
: Counts the number of lines, giving the total number of daemons.
Output of above command: 4
Inside a docker container, running as root, the command line looks like root@b9146ea99bae:/#
Getting some system info:
root@b9146ea99bae:/# cat /proc/1/cgroup
0::/
List what containers are running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
List all containers from history
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2aab35c84c71 ubuntu “bash” 2 minutes ago Exited (0) 2 minutes ago brave_cartwright
b9146ea99bae ubuntu “bash” 20 minutes ago Exited (0) 2 minutes ago festive_cori
Running an executable file inside a docker container.
- Run a docker container and in the same command, as an argument, name an executable file that’s on PATH to be run inside the container by the docker daemon.
- The docker daemon streams the output of the executable to the docker client.
Install nginx inside the docker container with an ubuntu OS and verify that it installed.
nginx -version
nginx version: nginx/1.24.0 (Ubuntu)
Installing nginx also created a directory structure within the /var dir of the default linux organization. Same directory structure as created by default by the apache webserver. There is an index html file. Likely the nginx web server delivers this file to the localhost and to the web after the webserver is configured to listen to a particular domain name / ip address.
/var/www/html# ls
index.nginx-debian.html
Installing with package manager apt
VIM and PYTHON3 had to be installed in the docker container although they are natively installed in Linux distros now.
apt install vim
apt install python3
Tested creating and executing a .py file containing ‘2+2’ via the newly installed vim and python3.
dockerfile example that pulls an OS image, installs software, and starts a database server and a webserver
FROM ubuntu:latest # pulls the latest ubuntu image, specify version for consistency across builds over time
ENV DEBIAN_FRONTEND=noninteractive #prevents interactive questions during installation
# normally want to run psql and psql-client in separate containers, or run psql server from host machine. keep data in a more persistent location. and keep the container hosting a microservice easy to upgrade and replicate on different machines.
RUN apt-get update && \
apt-get install -y nginx python3 vim postgresql postgresql-client && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
EXPOSE 80 5432 # These are the default Nginx and PostgreSQL ports. Can modify if ports are used by some other service or otherwise.
RUN service postgresql start # Daemons / servers within the container can be configured to start listening as soon as the container is built. This starts running the psql server.
CMD service postgresql start && nginx -g “daemon off;” # Start both PostgreSQL and Nginx in the foreground
Results on building
It took 17 seconds to build the first container with a dockerfile. Building a second container with the same dockerfile was siginificantly faster. Here’s the result.
[+] Building 0.1s (6/6) FINISHED docker:default
=> [internal] load build definition from dockerfile 0.0s
=> => transferring dockerfile: 508B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/2] FROM docker.io/library/ubuntu:latest 0.0s
=> CACHED [2/2] RUN apt-get update && apt-get install -y nginx python3 vim && apt-get clean && rm -rf /var/lib/apt/lists 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:68f08d8e7ebcbc83b6bd77c32522b317870dd3923317cd6fd36393dfa6410b15 0.0s
=> => naming to docker.io/library/container_planet1 0.0s
Configuring a web server, in this case, nginx, for reverse proxy
— — — — — — — -Example config file: — — — — —
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Another example of a dockerfile that pulls an OS image, creates a new group, adds a user to the group (this user has less previliges than the root user and generally accessing the application via this user’s profile will decrease chance of crashing or other vulnerabilities because the types of actions will be limited, such as this user will not be able to change memory allocated to the container), creates a directory within the filesystem where the application contents will be, installs packages inside the container (as part of building the container, i.e. build container, install packages within its namespace(?)), change ownership of the application files to an assigned user, expose ports. All of this is executed and then the container can be launched. After the launch, the dockerfile can define subsequent commands to be executed, the same commands that one would execute via shell. Here is the resulting file:
FROM ubuntu:latest
RUN groupadd -r kids && useradd -r -g kids Brin
WORKDIR /app
COPY . /app
RUN chown -R myuser:myuser /app
RUN apt-get update && apt-get install -y nginx python3
USER Brin
EXPOSE 8080
CMD [“python3”, “-m”, “http.server”, “8080”]
The repetition of words in a config and declarative file, such as this helps to see links. Brin is created as a user and then the user is switched to Brin. Port 8080 is exposed and then a command creates a python server that listens on port 8080.
If repetition were to be reduced, it would be in the first instance.
If user Brin does not exist, create user Brin. Explicitly creating user Brin is not required. Both of these actions are part of building the container(?) and so this modification is likely possible.
No explicit command ‘Expose 8080’. If there is an application within the container listening on a certain port, then that port should be exposed. The ‘CMD’ indicates a command that is run after the container is built, whereas exposing the ports is part of the config when the container is launched. If this repetition were to be reduced, it requires considering 2 different stages.