| | 1 | Part 1: |
| | 2 | Installing Docker on Ubuntu Server |
| | 3 | 1. Update Your System: Ensure your system package database is up-to-date. |
| | 4 | $ sudo apt update |
| | 5 | $ sudo apt upgrade |
| | 6 | 2. Install Docker: Install Docker using the convenience script provided by Docker. |
| | 7 | $ curl -fsSL https://get.docker.com -o get-docker.sh |
| | 8 | $ sudo sh get-docker.sh |
| | 9 | 3. Add User to Docker Group (Optional): If you want to run Docker commands without sudo, add your user to the docker group. |
| | 10 | $ sudo usermod -aG docker ${USER} |
| | 11 | Log out and log back in for the group changes to take effect. |
| | 12 | 4. Start and Enable Docker: Ensure Docker starts on boot. |
| | 13 | $ sudo systemctl enable docker |
| | 14 | $ sudo systemctl start docker |
| | 15 | 5. Verify Docker Installation: Check the Docker version to ensure it's installed correctly. |
| | 16 | $ docker --version |
| | 17 | 6. Deploying a Sample Web Application using Docker |
| | 18 | 6.1 Pull a Sample Web Application Image: For this guide, we'll use a simple HTTP server image from Docker Hub. |
| | 19 | $ docker pull httpd |
| | 20 | 6.2 Run the Web Application: Start a container using the httpd image. This will run the web server on port 8080. |
| | 21 | $ docker run -d -p 8080:80 --name sample-webapp httpd |
| | 22 | 6.3 Access the Web Application: If you're accessing the server locally, open a web browser and navigate to: (Since you are connected via SSH lets install a text-based web browser lynx.) |
| | 23 | $ sudo apt-get install lynx |
| | 24 | $ lynx http://localhost:8080 |
| | 25 | 6.4 Stop and Remove the Web Application (Optional): |
| | 26 | When you're done testing the web application, you can stop and remove the container. |
| | 27 | $ docker stop sample-webapp |
| | 28 | $ docker rm sample-webapp |
| | 29 | |
| | 30 | Extra Ref: |
| | 31 | https://linuxhint.com/best_linux_text_based_browsers/ |
| | 32 | https://romanzolotarev.com/ssh.html |
| | 33 | |
| | 34 | Basic Docker Commands and Their Usage |
| | 35 | • docker --version |
| | 36 | Usage: Displays the Docker version installed. |
| | 37 | Example: docker --version |
| | 38 | • docker info |
| | 39 | Usage: Provides detailed information about the Docker installation. |
| | 40 | Example: docker info |
| | 41 | • docker pull <image_name> |
| | 42 | Usage: Downloads a Docker image from Docker Hub. |
| | 43 | Example: docker pull nginx |
| | 44 | • docker build -t <image_name>:<tag> <path> |
| | 45 | Usage: Builds a Docker image from a Dockerfile located at <path>. |
| | 46 | Example: docker build -t myapp:latest . |
| | 47 | • docker images |
| | 48 | Usage: Lists all available Docker images on the system. |
| | 49 | Example: docker images |
| | 50 | • docker run <options> <image_name> |
| | 51 | Usage: Creates and starts a container from a Docker image. |
| | 52 | Example: docker run -d -p 80:80 nginx |
| | 53 | • docker ps |
| | 54 | Usage: Lists running containers. |
| | 55 | Example: docker ps |
| | 56 | • docker ps -a |
| | 57 | Usage: Lists all containers, including stopped ones. |
| | 58 | Example: docker ps -a |
| | 59 | • docker stop <container_id/container_name> |
| | 60 | Usage: Stops a running container. |
| | 61 | Example: docker stop my_container |
| | 62 | • docker rm <container_id/container_name> |
| | 63 | Usage: Removes a stopped container. |
| | 64 | Example: docker rm my_container |
| | 65 | • docker rmi <image_name> |
| | 66 | Usage: Removes a Docker image. |
| | 67 | Example: docker rmi nginx |
| | 68 | • docker logs <container_id/container_name> |
| | 69 | Usage: Displays logs from a running or stopped container. |
| | 70 | Example: docker logs my_container |
| | 71 | |
| | 72 | Troubleshooting Common Docker Container Issues |
| | 73 | • Container Fails to Start |
| | 74 | Check Logs: Use docker logs <container_name> to check for any error messages. |
| | 75 | Inspect Configuration: Ensure that the Docker run command has the correct parameters, such as port mappings and volume mounts. |
| | 76 | • Networking Issues |
| | 77 | Check IP Address: Use docker inspect <container_name> | grep IPAddress to find the container's IP address. |
| | 78 | Check Port Bindings: Ensure that the ports inside the container are correctly mapped to the host using the -p option. |
| | 79 | You may use docker port <container_name> to further check the port mapping. |
| | 80 | • File or Directory Not Found in Container |
| | 81 | Check Volumes: Ensure that directories or files from the host are correctly mounted into the container using the -v option. |
| | 82 | You may use docker volume ls to list all volumes mapped and docker volume inspect <volume_name> to inspect a selected volume. |
| | 83 | Inspect Image: Use docker image inspect <image_name> to see the image's layers and ensure the required files are present. |
| | 84 | • Container Performance Issues |
| | 85 | Check Resources: Containers might face performance issues if they're not allocated enough resources. Use docker stats to check the resource usage of running containers. |
| | 86 | Limit Resources: When running a container, you can use flags like --cpus and --memory to limit its resources. |
| | 87 | You can use docker top <container_name> to see some stats. |
| | 88 | • Image-Related Issues |
| | 89 | Pull Latest Image: Ensure you have the latest version of the image using docker pull <image_name>. |
| | 90 | Check Dockerfile: If you're building your own image, ensure that the Dockerfile has the correct instructions. |
| | 91 | • Permission Issues |
| | 92 | User Mappings: If a containerized application can't access certain files, it might be a user permission issue. Ensure that the user inside the container has the necessary permissions. |
| | 93 | Use --user Flag: When running a container, you can specify which user the container should run as using the --user flag. |
| | 94 | |
| | 95 | |
| | 96 | Part 2: |
| | 97 | What is a Dockerfile? |
| | 98 | A Dockerfile is a script containing a set of instructions used by Docker to automate the process of building a new container image. It defines the environment inside the container, installs necessary software, sets up commands, and more. |
| | 99 | Basic Structure of a Dockerfile |
| | 100 | A Dockerfile consists of a series of instructions and arguments. Each instruction is an operation used to build the image, like installing a software package or copying files. The instruction is written in uppercase, followed by its arguments. |
| | 101 | Key Dockerfile Instructions |
| | 102 | FROM: Specifies the base image to start from. It's usually an OS or another application. |
| | 103 | Example: FROM ubuntu:20.04 |
| | 104 | LABEL: Adds metadata to the image, like maintainer information. |
| | 105 | Example: LABEL maintainer="name@example.com" |
| | 106 | RUN: Executes commands in a new layer on top of the current image and commits the result. |
| | 107 | Example: RUN apt-get update && apt-get install -y nginx |
| | 108 | CMD: Provides defaults for the executing container. There can only be one CMD instruction in a Dockerfile. |
| | 109 | Example: CMD ["nginx", "-g", "daemon off;"] |
| | 110 | ENTRYPOINT: Configures the container to run as an executable. It's often used in combination with CMD. |
| | 111 | Example: ENTRYPOINT ["nginx"] |
| | 112 | COPY: Copies files or directories from the host machine to the container. |
| | 113 | Example: COPY ./webapp /var/www/webapp |
| | 114 | ADD: Similar to COPY, but can also handle URLs and tarball extraction. |
| | 115 | Example: ADD https://example.com/app.tar.gz /app/ |
| | 116 | WORKDIR: Sets the working directory for any subsequent RUN, CMD, ENTRYPOINT, COPY, and ADD instructions. |
| | 117 | Example: WORKDIR /app |
| | 118 | EXPOSE: Informs Docker that the container listens on the specified network port at runtime. |
| | 119 | Example: EXPOSE 80 |
| | 120 | ENV: Sets environment variables. |
| | 121 | Example: ENV MY_VARIABLE=value |
| | 122 | VOLUME: Creates a mount point for external storage or other containers. |
| | 123 | Example: VOLUME /data |
| | 124 | |
| | 125 | Let's create a Dockerfile for a basic web server using Nginx: |
| | 126 | First, create a folder called my-webserver and go inside it cd my-webserver |
| | 127 | Then create another folder inside that called website and a file called index.html within the folder website with any content of your choice. |
| | 128 | |
| | 129 | Create a file dockerfile with the following content within the my-webserver folder. |
| | 130 | |
| | 131 | # Use the official Nginx image as a base |
| | 132 | FROM nginx:latest |
| | 133 | |
| | 134 | # Set the maintainer label |
| | 135 | LABEL maintainer="name@example.com" |
| | 136 | |
| | 137 | # Copy static website files to the Nginx web directory |
| | 138 | COPY ./website /usr/share/nginx/html |
| | 139 | |
| | 140 | # Expose port 80 for the web server |
| | 141 | EXPOSE 80 |
| | 142 | |
| | 143 | # Default command to run Nginx in the foreground |
| | 144 | CMD ["nginx", "-g", "daemon off;"] |
| | 145 | |
| | 146 | |
| | 147 | Building an Image from a Dockerfile |
| | 148 | To build a Docker image from your Dockerfile, navigate to the directory containing the Dockerfile and run: |
| | 149 | docker build -t my-webserver:latest . |
| | 150 | This command tells Docker to build an image using the Dockerfile in the current directory (.) and tag it as my-webserver:latest. |
| | 151 | |
| | 152 | Best Practices |
| | 153 | • Minimize Layers: Try to reduce the number of layers in your image to make it lightweight. For instance, chain commands using && in a single RUN instruction. |
| | 154 | • Use .dockerignore: Just like .gitignore, you can use .dockerignore to exclude files that aren't needed in the container. |
| | 155 | • Avoid Installing Unnecessary Packages: Only install the packages that are necessary to run your application. |
| | 156 | • Clean Up: Remove temporary files and caches to reduce image size. |
| | 157 | |
| | 158 | Part 3: |
| | 159 | What is Docker Compose? |
| | 160 | Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you can define a multi-container application in a single file, then spin up your application with a single command (docker-compose up). |
| | 161 | Key Concepts |
| | 162 | Services: Each container started by Docker Compose is a service. Services are defined in the docker-compose.yml file. |
| | 163 | Networks: By default, Docker Compose sets up a single network for your application. Each container for a service joins the default network and is discoverable via a hostname identical to the container name. |
| | 164 | Volumes: Volumes can be used to share files between the host and container or between containers. |
| | 165 | |
| | 166 | Basic docker-compose Commands |
| | 167 | • docker-compose up: Starts up the services defined in the docker-compose.yml file. |
| | 168 | • docker-compose down: Stops and removes all the containers defined in the docker-compose.yml file. |
| | 169 | • docker-compose ps: Lists the services and their current state (running/stopped). |
| | 170 | • docker-compose logs: Shows the logs from the services. |
| | 171 | |
| | 172 | Deploying WordPress with Docker Compose |
| | 173 | Let's deploy a WordPress application using two containers: one for WordPress and another for the MySQL database. |
| | 174 | Create a docker-compose.yml file: |
| | 175 | version: '3' |
| | 176 | |
| | 177 | services: |
| | 178 | # Database Service |
| | 179 | db: |
| | 180 | image: mysql:5.7 |
| | 181 | volumes: |
| | 182 | - db_data:/var/lib/mysql |
| | 183 | environment: |
| | 184 | MYSQL_ROOT_PASSWORD: somewordpress |
| | 185 | MYSQL_DATABASE: wordpress |
| | 186 | MYSQL_USER: wordpress |
| | 187 | MYSQL_PASSWORD: wordpress |
| | 188 | |
| | 189 | # WordPress Service |
| | 190 | wordpress: |
| | 191 | depends_on: |
| | 192 | - db |
| | 193 | image: wordpress:latest |
| | 194 | ports: |
| | 195 | - "8080:80" |
| | 196 | environment: |
| | 197 | WORDPRESS_DB_HOST: db:3306 |
| | 198 | WORDPRESS_DB_USER: wordpress |
| | 199 | WORDPRESS_DB_PASSWORD: wordpress |
| | 200 | WORDPRESS_DB_NAME: wordpress |
| | 201 | volumes: |
| | 202 | - wordpress_data:/var/www/html |
| | 203 | |
| | 204 | volumes: |
| | 205 | db_data: {} |
| | 206 | wordpress_data: {} |
| | 207 | |
| | 208 | Start the WordPress and Database Containers: Navigate to the directory containing the docker-compose.yml file and run: |
| | 209 | |
| | 210 | |
| | 211 | docker-compose up -d |
| | 212 | This command will start the services in detached mode. Once the services are up, you can access the WordPress site by navigating to http://<Floating_IP>:8080 from your browser. |
| | 213 | |
| | 214 | Stopping the Services: To stop the services, navigate to the same directory and run: |
| | 215 | |
| | 216 | docker-compose down |
| | 217 | |
| | 218 | Best Practices |
| | 219 | • Explicit Service Names: Give your services explicit names to make it clear what each service does. |
| | 220 | • Environment Variables: Use environment variables for sensitive information and configurations. |
| | 221 | • Service Dependencies: Use the depends_on option to ensure services start in the correct order. |
| | 222 | |
| | 223 | |
| | 224 | Part 4: |
| | 225 | Deploy any web app as per your wish and showcase its usage of it. You need to use more than one docker container eg: you can use three containers, one to run a web app and the others to run a database and other data storage respectively. You may use the docker hub to get any existing containers. What we evaluate is your ability to deploy the containers and bringing up a working web app. |