{"id":20345763,"url":"https://github.com/izzypt/inception","last_synced_at":"2026-06-04T02:31:04.475Z","repository":{"id":206856238,"uuid":"717848913","full_name":"izzypt/Inception","owner":"izzypt","description":"A System Administration related exercise using Docker,  setting up a small infrastructure composed of different services under specific rules.","archived":false,"fork":false,"pushed_at":"2024-08-14T12:20:17.000Z","size":225,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-14T21:45:28.548Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/izzypt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-12T19:37:39.000Z","updated_at":"2024-08-14T12:20:20.000Z","dependencies_parsed_at":"2025-01-14T21:34:23.009Z","dependency_job_id":"25752fa4-55de-42cc-8a7b-f34531c232ca","html_url":"https://github.com/izzypt/Inception","commit_stats":null,"previous_names":["izzypt/inception"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FInception","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FInception/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FInception/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/izzypt%2FInception/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/izzypt","download_url":"https://codeload.github.com/izzypt/Inception/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241876606,"owners_count":20035396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T22:09:41.626Z","updated_at":"2025-12-03T03:02:37.781Z","avatar_url":"https://github.com/izzypt.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Inception\nThis document is a System Administration related exercise.\n\n# List of Contents\n\n- [Introduction](#intro)\n- [Why is Docker important?](#docker)\n- [What is a container?](#docker)\n- [What is an image?](#image)\n- [Difference between Dockerfile and Docker Compose](#compose)\n- [Docker vs VM (Virtual Machine)](#dockervsvm)\n- [What are volumes](#volumes)\n- [What is the Docker Network](#network)\n- [Container Port vs Host Port](#ports)\n- [Docker commands](#commands)\n- [Web Servers](#web)\n- [NGINX](#nginx)\n\n# Another questions/problems I ran into later in development life\n\n- [Multi-Stage builds and --target](#multistage)\n- [Tagging and saving image](#tagandsave)\n\n\u003ca id=\"intro\"\u003e\u003c/a\u003e\n# Introduction \u003ch6\u003e(https://docs.docker.com/get-started/ and  https://www.educative.io/blog/docker-compose-tutorial)\u003c/h6\u003e\n\nThis project aims to broaden your knowledge of system administration by using Docker.\n\nYou will virtualize several Docker images, creating them in your new personal virtual\nmachine.\n\nThis project consists in having you set up a small infrastructure composed of different services under specific rules. \n\n![image](https://github.com/izzypt/Inception/assets/73948790/4c28b4ed-898d-4786-9e45-a091db86aa18)\n\n\nThe whole project has to be done in a virtual machine. \n- You have to use docker compose.\n- Each Docker image must have the same name as its corresponding service.\n- Each service has to run in a dedicated container.\n- For performance matters, the containers must be built either from the penultimate stable version of Alpine or Debian.\n- You also have to write your own Dockerfiles, one per service.\n- The Dockerfiles must be called in your docker-compose.yml by your Makefile.\n- It means you have to build yourself the Docker images of your project.\n- It is then forbidden to pull ready-made Docker images, as well as using services such as DockerHub (Alpine/Debian being excluded from this rule).\n\n- You then have to set up:\n\n  • A Docker container that contains NGINX with TLSv1.2 or TLSv1.3 only.\n  \n  • A Docker container that contains WordPress + php-fpm (it must be installed and configured) only without nginx.\n  \n  • A Docker container that contains MariaDB only without nginx.\n  \n  • A volume that contains your WordPress database.\n  \n  • A second volume that contains your WordPress website files.\n  \n  • A docker-network that establishes the connection between your containers.\n  \n - In your WordPress database, there must be two users, one of them being the administrator. The administrator’s username can’t contain admin/Admin or administrator/Administrator (e.g., admin, administrator, Administrator, admin-123, and so forth).\n\n - You have to configure your domain name so it points to your local IP address. This domain name must be login.42.fr.\n   \u003e For example, if your login is wil, wil.42.fr will redirect to the IP address pointing to wil’s website\n\n\u003ca id=\"docker\"\u003e\u003c/a\u003e\n# Why is Docker important?\nDocker can package up applications along with their necessary operating system dependencies for easier deployment across environments. \n\nIn the long run it has the potential to be the abstraction layer that easily manages containers running on top of any type of server, regardless of whether that server is on Amazon Web Services, Google Compute Engine, Linode, Rackspace or elsewhere.\n\nhttps://www.fullstackpython.com/docker.html\n\n\u003ca id=\"container\"\u003e\u003c/a\u003e\n# What is a container?\n\nA container is a sandboxed process running on a host machine that is isolated from all other processes running on that host machine. To summarize, a container:\n\n  - Is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI.\n  - Can be run on local machines, virtual machines, or deployed to the cloud.\n  - Is portable (and can be run on any OS).\n  - Is isolated from other containers and runs its own software, binaries, configurations, etc.\n\n\u003ca id=\"image\"\u003e\u003c/a\u003e\n# What is an image?\n\nA running container uses an isolated filesystem. \n\nThis isolated filesystem is provided by an image, and the image must contain everything needed to run an application - all dependencies, configurations, scripts, binaries, etc. \n\nThe image also contains other configurations for the container, such as environment variables, a default command to run, and other metadata.\n\n\u003ca id=\"compose\"\u003e\u003c/a\u003e\n# Difference between Dockerfile and Docker Compose\n\nThe key difference between the Dockerfile and docker-compose is that the Dockerfile describes how to build Docker images, while docker-compose is used to run Docker containers.\n\nThe contents of a Dockerfile describe how to create and build a Docker image, while docker-compose is a command that runs Docker containers based on settings described in a docker-compose.yaml file.\n\n\u003ca id=\"dockervsvm\"\u003e\u003c/a\u003e\n# Docker vs VM (Virtual Machine)\n\nDocker containers and virtual machines are both ways of deploying applications inside environments that are isolated from the underlying hardware: \n - The chief difference is the level of isolation.\n\nDocker containers share many of their resources with the host system, they require fewer things to be installed in order to run. \n\nContainers share the same kernel on the same host. As a result, processes running inside containers are visible from the host system (given enough privileges for listing all).\n\nCompared to a virtual machine, a container typically takes up less space and consumes less RAM and CPU time\n\nIn contrast, with a virtual machine, everything running inside the VM is independent of the host operating system, or hypervisor.\n\nWhat’s fundamentally different with a virtual machine is that at start time, it boots a new, dedicated kernel for this VM environment, and starts a (often rather large) set of operating system processes. This makes the size of the VM much larger than a typical container that only contains the application.\n\n\u003ca id=\"volumes\"\u003e\u003c/a\u003e\n#  What are volumes\n\nWhenever we run a container based on an image ( e.g. running a database in container) and have generated some data, if we remove that container the data will no longer be accessible to us. \n\nThe data gets removed with the container. And what if we want to preserve that data generated by running containers? Here’s where Docker Volumes comes in…\n\nDocker volumes are a filesystem used in docker to persist data of a container independent of its life cycle. It helps us to persist or store either a file or a directory so that we can share it across multiple container or to create new containers from it.\n\nFor this reason, you need some way to have a mechanism for storing data.\n\nThere are 2 ways to make data persistent in docker:\n  - volumes\n  - bind mounts\n\nIn a Docker Compose file, you can distinguish between a named volume and a bind mount based on how you define the volume in the volumes section. \n\nHere are the key differences:\n\n    Named Volume:\n\n        When using a named volume, you define the volume directly under the volumes section without specifying a host path. Docker Compose will automatically create and manage the named volume.\n\n        Example:\n\n        yaml\n\n    services:\n      myservice:\n        volumes:\n          - my-named-volume:/path/in/container\n    volumes:\n      my-named-volume:\n\nIn this example, my-named-volume is a named volume.\n\nBind Mount:\n\n    When using a bind mount, you define the volume under the volumes section with a host path specified before a colon (:), followed by the path in the container.\n\n    Example:\n\n    yaml\n\n        services:\n          myservice:\n            volumes:\n              - /host/path:/path/in/container\n\n    In this example, /host/path is a bind mount.\n\nHere's a more complete example demonstrating the use of both named volumes and bind mounts in a Docker Compose file:\n\n```\n\nversion: '3'\nservices:\n  myservice:\n    image: myimage\n    volumes:\n      - my-named-volume:/path/in/container\n      - /host/path:/another/path/in/container\n\nvolumes:\n  my-named-volume:\n```\n\nIn this example, my-named-volume is a named volume, and /host/path is a bind mount.\n\nRemember that named volumes are managed by Docker, and you can inspect them using docker volume ls and docker volume inspect \u003cvolume_name\u003e. Bind mounts, on the other hand, directly reference paths on the host machine.\n\n\n\u003ca id=\"network\"\u003e\u003c/a\u003e\n# What is the Docker Network\n\nDocker networks provide a communication bridge between different Docker containers, allowing them to talk to each other securely.\n\nExample:\n\nWhen I deploy two containers on the same docker network , in this case - mongo and mongo express- they can talk to each other only using the ***container name*** because they are in the same network. \n\nAnd the apps that run outside of Docker like this nodeJS, is gonna connect to them using localhost or the port number:\n\n\u003cimg width=\"1184\" alt=\"image\" src=\"https://github.com/user-attachments/assets/5aa8f941-8f2a-4907-92a2-d34575da50b8\"\u003e\n\n\nA Docker network enables isolated environments for containers, helping with better organization and management of containerized applications.\n\nHere's a simple explanation:\n\n  ### Isolation:\n  - Docker containers running on the same network can communicate with each other, but they are isolated from containers on other networks.\n\n  ### Default Bridge Network:\n  \n  - When you run a Docker container without specifying a network, it is connected to the default bridge network. \n  - Containers on the same bridge network can communicate with each other using IP addresses.\n\n  ### User-Defined Networks:\n  \n  - Docker allows you to create custom, user-defined networks. \n  - Containers connected to the same custom network can communicate with each other using container names as hostnames.\n\n  ### Scalability and Flexibility:\n  \n  - Docker networks make it easy to scale applications. \n  - For example, if you have a web application and a database, you can run them in separate containers on the same network.\n\n  ### Container Discovery:\n  \n  - Containers on the same network can discover and communicate with each other using service names or container names as if they were hostnames.\n\n  ### Security:\n  \n  - Docker networks provide a level of security by isolating communication between containers. Containers on different networks usually cannot communicate with each other directly.\n\n  ### Bridge, Overlay, and Host Networks:\n  \n  - Docker supports various types of networks, including bridge networks (default), overlay networks for multi-host communication, and host networks where containers share the host's network stack.\n\n  ### Network Drivers:\n  \n  - Docker supports different network drivers that determine how containers on a network communicate. \n  - The default is the bridge driver, but you can also use overlay, macvlan, and others based on your specific requirements.\n\nIn essence, Docker networks are a crucial part of managing and organizing containerized applications, providing a way for containers to communicate, share data, and work together in a controlled and secure manner. They contribute to the flexibility and scalability of containerized architectures.\n\nDocker has 7 types of network, this video explains more about each one:\n\n- https://www.youtube.com/watch?v=bKFMS5C4CG0\n\n\u003ca id=\"commands\"\u003e\u003c/a\u003e\n# Docker commands\n\nA list of commonly used docker comands:\n\n  - ```docker run```: Create and start a new container from an image.\n\n  - ```docker build```: Build a Docker image from a Dockerfile.\n\n  - ```docker pull```: Pull an image or a repository from a registry.\n\n  - ```docker push```: Push an image or a repository to a registry.\n\n  - ```docker ps```: List running containers.\n\n  - ```docker ps -a```: List all containers, including stopped ones.\n\n  - ```docker exec```: Run a command inside a running container.\n\n  - ```docker stop```: Stop one or more running containers.\n\n  - ```docker start```: Start one or more stopped containers.\n\n  - ```docker restart```: Restart one or more containers.\n\n  - ```docker rm```: Remove one or more containers.\n\n  - ```docker rmi```: Remove one or more images.\n\n  - ```docker images```: List available images on the local system.\n\n  - ```docker inspect```: Display detailed information about one or more containers, images, networks, or volumes.\n\n  - ```docker-compose up```: Create and start containers defined in the docker-compose.yml file.\n\n  - ```docker-compose down```: Stop and remove containers, networks, and volumes defined in the docker-compose.yml file.\n\n  - ```docker network ls```: List Docker networks.\n\n  - ```docker volume ls```: List Docker volumes.\n\n### ```docker run``` vs ```docker exec```\n\n  - docker run:\n    - This command is used to create a new container from a Docker image and then run a command inside that container.\n    - It's typically used to start new containers.\n    - When you use docker run, Docker creates a new container based on the specified image and then executes the command you provide within that container. If the container is already running, docker run will start another instance of the specified image.\n\n- docker exec:\n  - This command is used to run a command inside an existing, running container.\n  - It allows you to execute commands within a container that is already running.\n  - Unlike docker run, which creates a new container instance, docker exec works on an existing container that has already been created and started.\n\n- In summary, docker run is used to start new containers, while docker exec is used to execute commands within existing containers.\n\nTop 16 docker commands\n\n    docker ps -\u003e list running containers. \n    docker ps -a -\u003e list all container including stopped container\n    docker pull  -\u003e download a image from Docker Hub registry. Link to the docker image is always shown on the right at dockerhub.\n    docker build  -\u003e is used to build your own container based on a Dockerfile. Common use is docker build . to build a container based on the Dockerfile in the current directory (the dot). docker build -t “myimage:latest” . creates a container and stores the image under the given name\n    docker images or docker image ls -\u003e shows all local storage images\n    docker run  -\u003e Run a docker container based on an image, i. e. docker run myimage -it bash. If no local image can be found docker run automatically tries to download the image from Docker hub.\n    docker logs -\u003e display the logs of a container, you specified. To continue showing log updates just use docker logs -f mycontainer\n    docker volume ls -\u003e lists the volumes, which are commonly used for persisting data of Docker containers.\n    docker network ls –\u003e list all networks available for docker container\n    docker network connect adds the container to the given container network. That enables container communication by simple container name instead of IP.\n    docker rm  -\u003e removes one or more containers. docker rm mycontainer, but make sure the container is not running\n    docker rmi  -\u003e removes one or more images. docker rmi myimage, but make sure no running container is based on that image\n    docker stop  -\u003e stops one or more containers. docker stop mycontainer stops one container, while docker stop $(docker ps -a -q) stops all running containers. \n    docker start –\u003e starts a stopped container using the last state\n    docker update –restart=no -\u003e updates container policies, that is especially helpful when your container is stuck in a crash loop\n    docker cp -\u003e to copy files from a running container to the host or the way around. docker cp :/etc/file . to copy /etc/file to your current directory.\n\nSome combinations that help a lot:\n\n    kill all running containers with docker kill $(docker ps -q)\n    delete all stopped containers with docker rm $(docker ps -a -q)\n    delete all images with docker rmi $(docker images -q)\n    update and stop a container that is in a crash-loop with docker update –restart=no \u0026\u0026 docker stop\n    bash shell into container docker exec -i -t /bin/bash – if bash is not available use /bin/sh\n    bash shell with root if container is running in a different user context docker exec -i -t -u root /bin/bash\n\n**What about resource usage**\n\nGet docker container including size:\n\n``docker ps -s``\n\nGet docker container disk utilization:\n\n``docker system df``\n\nWhat about wasted resources?\n\nThe first command is used to remove local container images that are not used by any container and are not tagged. Its a pretty safe command to clean up your local filesystem\n\n``docker image prune``\n\nIf you want to clean up and delete all unused container images, just add -a\n\n``docker image prune -a``\n\nonly clean up container images that have been created over 24 hours ago run\n\n``docker image prune -a --filter \"=24h\"``\n\nsame can be done with container, that are not running anymore\n\n``docker container prune``\n\nHere comes a bonus command:\n\n``truncate -s 0 $(docker inspect --format='' \u003ccontainer_name_or_id\u003e)``\n\nThat’s it for now – please let us know if you like to add a command you feel is extremely important. We’re doing our best to add these in future blog posts are just append to the current posts. \n\nBtw. as we covered the Podman project some days ago, most of these commands work with podman instead of docker as well.\n\n\u003ca id=\"ports\"\u003e\u003c/a\u003e\n# Container Port vs Host Port\n\nIn Docker, the concepts of container port and host port are key to understanding how network traffic is routed to your containerized applications:\n\n- **Container Port**: This is the port number that your application inside the container listens to. It is defined within the Docker container.\n\n- **Host Port**: This is the port number on the host machine (the physical or virtual machine running Docker) that is mapped to the container port. This allows external systems or users to access the application running inside the container.\n\nWhen you run a Docker container, you can map a host port to a container port using the `-p` flag. \n\nFor example, `-p 8080:80` maps port `8080` on the host to port `80` in the container. \n\nThis means that if you access `http://localhost:8080` on the host machine, the request will be forwarded to the application running on port 80 inside the container.\n\n\u003cimg width=\"1546\" alt=\"image\" src=\"https://github.com/user-attachments/assets/2835b119-899c-404e-b622-4b2cb496be11\"\u003e\n\n\n\u003ca id=\"web\"\u003e\u003c/a\u003e\n# Web Servers\nWeb servers respond to Hypertext Transfer Protocol (HTTP) requests from clients and send back a response containing a status code and often content such as HTML, XML or JSON as well.\n\n# Why are web servers necessary?\nWeb servers are the ying to the web client's yang. The server and client speak the standardized language of the World Wide Web. This standard language is why an old Mozilla Netscape browser can still talk to a modern Apache or Nginx web server, even if it cannot properly render the page design like a modern web browser can.\n\nThe basic language of the Web with the request and response cycle from client to server then server back to client remains the same as it was when the Web was invented by Tim Berners-Lee at CERN in 1989. Modern browsers and web servers have simply extended the language of the Web to incorporate new standards.\n\n# Web server implementations\nThe conceptual web server idea can be implemented in various ways. The following web server implementations each have varying features, extensions and configurations.\n\nThe Apache HTTP Server has been the most commonly deployed web server on the Internet for 20+ years.\n\nNginx is the second most commonly used server for the top 100,000 websites and often serves as a reverse proxy for Python WSGI servers.\n\n\u003ca id=\"nginx\"\u003e\u003c/a\u003e\n# NGINX \n\nhttps://www.youtube.com/watch?v=iInUBOVeBCc\u0026t=22s\n\nnginx is one of the first services we need to set up. Let's talk about what it is and what we will use it for:\n(https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms)\n\nnginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev. \n\nFor a long time, it has been running on many heavily loaded Russian sites including Yandex, Mail.Ru, VK, and Rambler. \n\nAccording to Netcraft, nginx served or proxied 20.66% busiest sites in October 2023. Here are some of the success stories: Dropbox, Netflix, Wordpress.com, FastMail.FM.\n\n![image](https://github.com/user-attachments/assets/2a271e65-2f83-4d3d-b5e7-87ff01433636)\n\n![image](https://github.com/user-attachments/assets/4262c842-e855-49e9-b2db-1ac21fb7db1e)\n\n![image](https://github.com/user-attachments/assets/ffa850a2-261b-4e0e-b0d6-9ffea5ed5beb)\n\n![image](https://github.com/user-attachments/assets/e6c62875-59a6-4406-8769-9f0a0676265a)\n\n![image](https://github.com/user-attachments/assets/7dba0477-5f88-409d-aad4-562e7e2eabbe)\n\n\n\n\n### Basic HTTP server features\n- Serving static and index files, autoindexing; open file descriptor cache;\n- Accelerated reverse proxying with caching; load balancing and fault tolerance;\n- Accelerated support with caching of FastCGI, uwsgi, SCGI, and memcached servers; load balancing and fault tolerance;\n- Modular architecture. Filters include gzipping, byte ranges, chunked responses, XSLT, SSI, and image transformation filter. Multiple SSI inclusions within a single page can be processed in parallel if they are handled by proxied or - FastCGI/uwsgi/SCGI servers;\n- SSL and TLS SNI support;\n- Support for HTTP/2 with weighted and dependency-based prioritization;\n- Support for HTTP/3.\n\n### Configuration File’s Structure\n\nnginx consists of modules which are controlled by directives specified in the configuration file. \n\nDirectives are divided into simple directives and block directives. \n\nA simple directive consists of the name and parameters separated by spaces and ends with a semicolon (;). \n\nA block directive has the same structure as a simple directive, but instead of the semicolon it ends with a set of additional instructions surrounded by braces ({ and }). \n\nIf a block directive can have other directives inside braces, it is called a context (examples: events, http, server, and location).\n\nDirectives placed in the configuration file outside of any contexts are considered to be in the main context. The events and http directives reside in the main context, server in http, and location in server.\n\nThe rest of a line after the # sign is considered a comment.\n\nHow to create nginx config file -\u003e https://www.youtube.com/watch?v=NEf3CFjN0Dg\n\n### Serving Static Content\n\nAn important web server task is serving out files (such as images or static HTML pages). You will implement an example where, depending on the request, files will be served from different local directories: /data/www (which may contain HTML files) and /data/images (containing images). This will require editing of the configuration file and setting up of a server block inside the http block with two location blocks.\n\nFirst, create the /data/www directory and put an index.html file with any text content into it and create the /data/images directory and place some images in it.\n\nNext, open the configuration file. The default configuration file already includes several examples of the server block, mostly commented out. For now comment out all such blocks and start a new server block:\n  ```\n  http {\n      server {\n      }\n  }\n  ```\nGenerally, the configuration file may include several server blocks distinguished by ports on which they listen to and by server names. Once nginx decides which server processes a request, it tests the URI specified in the request’s header against the parameters of the location directives defined inside the server block.\n\nAdd the following location block to the server block:\n ```\nlocation / {\n    root /data/www;\n}\n ```\nThis location block specifies the “/” prefix compared with the URI from the request. For matching requests, the URI will be added to the path specified in the root directive, that is, to /data/www, to form the path to the requested file on the local file system. If there are several matching location blocks nginx selects the one with the longest prefix. The location block above provides the shortest prefix, of length one, and so only if all other location blocks fail to provide a match, this block will be used.\n\nNext, add the second location block:\n ```\nlocation /images/ {\n    root /data;\n}\n ```\nIt will be a match for requests starting with /images/ (location / also matches such requests, but has shorter prefix).\n\nThe resulting configuration of the server block should look like this:\n\n ```\nserver {\n    location / {\n        root /data/www;\n    }\n\n    location /images/ {\n        root /data;\n    }\n}\n ```\n\nThis is already a working configuration of a server that listens on the standard port 80 and is accessible on the local machine at http://localhost/. In response to requests with URIs starting with /images/, the server will send files from the /data/images directory. For example, in response to the http://localhost/images/example.png request nginx will send the /data/images/example.png file. If such file does not exist, nginx will send a response indicating the 404 error. Requests with URIs not starting with /images/ will be mapped onto the /data/www directory. For example, in response to the http://localhost/some/example.html request nginx will send the /data/www/some/example.html file.\n\nTo apply the new configuration, start nginx if it is not yet started or send the reload signal to the nginx’s master process, by executing:\n ```\nnginx -s reload\n ```\nIn case something does not work as expected, you may try to find out the reason in access.log and error.log files in the directory /usr/local/nginx/logs or /var/log/nginx.\n\n### Setting Up a Simple Proxy Server\nOne of the frequent uses of nginx is setting it up as a proxy server, which means a server that receives requests, passes them to the proxied servers, retrieves responses from them, and sends them to the clients.\n\nWe will configure a basic proxy server, which serves requests of images with files from the local directory and sends all other requests to a proxied server. In this example, both servers will be defined on a single nginx instance.\n\nFirst, define the proxied server by adding one more server block to the nginx’s configuration file with the following contents:\n```\nserver {\n    listen 8080;\n    root /data/up1;\n\n    location / {\n    }\n}\n```\nThis will be a simple server that listens on the port 8080 (previously, the listen directive has not been specified since the standard port 80 was used) and maps all requests to the /data/up1 directory on the local file system. Create this directory and put the index.html file into it. Note that the root directive is placed in the server context. Such root directive is used when the location block selected for serving a request does not include its own root directive.\n\nNext, use the server configuration from the previous section and modify it to make it a proxy server configuration. In the first location block, put the proxy_pass directive with the protocol, name and port of the proxied server specified in the parameter (in our case, it is http://localhost:8080):\n\n```\nserver {\n    location / {\n        proxy_pass http://localhost:8080;\n    }\n\n    location /images/ {\n        root /data;\n    }\n}\n```\nWe will modify the second location block, which currently maps requests with the /images/ prefix to the files under the /data/images directory, to make it match the requests of images with typical file extensions. The modified location block looks like this:\n```\nlocation ~ \\.(gif|jpg|png)$ {\n    root /data/images;\n}\n```\nThe parameter is a regular expression matching all URIs ending with .gif, .jpg, or .png. A regular expression should be preceded with ~. The corresponding requests will be mapped to the /data/images directory.\n\nWhen nginx selects a location block to serve a request it first checks location directives that specify prefixes, remembering location with the longest prefix, and then checks regular expressions. If there is a match with a regular expression, nginx picks this location or, otherwise, it picks the one remembered earlier.\n\nThe resulting configuration of a proxy server will look like this:\n```\nserver {\n    location / {\n        proxy_pass http://localhost:8080/;\n    }\n\n    location ~ \\.(gif|jpg|png)$ {\n        root /data/images;\n    }\n}\n```\nThis server will filter requests ending with .gif, .jpg, or .png and map them to the /data/images directory (by adding URI to the root directive’s parameter) and pass all other requests to the proxied server configured above.\n\nTo apply new configuration, send the reload signal to nginx as described in the previous sections.\n\nThere are many more directives that may be used to further configure a proxy connection.\n\n\n\u003ca id=\"multistage\"\u003e\u003c/a\u003e\n# Multi-Stage builds and --target\n\nThe `--target` flag in Docker is used in the context of multi-stage builds within a Dockerfile. When you have a Dockerfile with multiple build stages, the `--target` option allows you to specify which stage you want to build up to.\n\n### Multi-Stage Builds\n\nIn a multi-stage build, you can define multiple `FROM` instructions within a single Dockerfile. Each `FROM` instruction starts a new build stage, and you can use different base images or configurations for each stage. Typically, you might use one stage to build your application and another to package the final, optimized image.\n\n### The `--target` Flag\n\nThe `--target` flag allows you to stop the build process at a specific stage and output the image created up to that point. This can be useful when you only want to build an intermediate stage for debugging or if you have different targets for development, testing, and production.\n\n### Example\n\nHere’s a simplified example Dockerfile with multi-stage builds:\n\n```dockerfile\n# Stage 1: Build\nFROM golang:1.18 AS builder\nWORKDIR /app\nCOPY . .\nRUN go build -o myapp .\n\n# Stage 2: Production Image\nFROM alpine:latest AS prod_image\nWORKDIR /app\nCOPY --from=builder /app/myapp .\nCMD [\"./myapp\"]\n\n# Stage 3: Debug Image\nFROM alpine:latest AS debug_image\nWORKDIR /app\nCOPY --from=builder /app/myapp .\nRUN apk add --no-cache bash\nCMD [\"bash\"]\n```\n\nIn this example, there are three stages:\n1. **builder**: Compiles the Go application.\n2. **prod_image**: Copies the compiled binary from the builder stage to a lightweight Alpine image, creating a minimal production image.\n3. **debug_image**: Similar to the production image, but includes a shell for debugging.\n\n### Using the `--target` Flag\n\nIf you want to build the production image only, you would use the `--target` flag:\n\n```bash\ndocker build --target prod_image -t myapp:prod .\n```\n\n- **`--target prod_image`**: Instructs Docker to build only up to the `prod_image` stage.\n- **`-t myapp:prod`**: Tags the resulting image as `myapp:prod`.\n\nSimilarly, you could build the debug image like this:\n\n```bash\ndocker build --target debug_image -t myapp:debug .\n```\n\nThis flexibility allows you to have different build targets for various purposes (e.g., production, testing, debugging) within a single Dockerfile.\n\n\u003ca id=\"tagandsave\"\u003e\u003c/a\u003e\n\n# Tagging and saving image\n\n### Tagging the Image:\n\nIf you want this image to appear under a specific tag, you can tag it manually:\n\n`\ndocker tag \u003cimage_id\u003e nexus.eigen.live/generative_service:\u003cdesired_tag\u003e\n`\n\nReplace \u003cdesired_tag\u003e with the tag name you prefer. After doing this, running docker images will show the image with the tag you've assigned.\n\n### Saving the Image:\n\nTo save your Docker image to a `.tar` file, you can use the `docker save` command. This command exports the image into a tarball, which you can then transfer or store as needed.\n\nHere’s how you can do it:\n\n1. **Use `docker save` to Export the Image**\n\n   Run the following command, replacing `\u003cimage_id\u003e` with the ID of the image you want to save and `\u003cfile_name\u003e.tar` with your desired filename:\n\n   ```bash\n   docker save -o \u003cfile_name\u003e.tar \u003cimage_id\u003e\n   ```\n\n   In your case, the command would be:\n\n   ```bash\n   docker save -o generative_service_image.tar c400271e778d\n   ```\n\n   This command will create a file named `generative_service_image.tar` in your current directory containing the image.\n\n2. **Verify the Tarball**\n\n   After saving the image, you can list the files in your directory to ensure that the tarball has been created:\n\n   ```bash\n   ls -l generative_service_image.tar\n   ```\n\n   You can also inspect the tarball to verify its contents:\n\n   ```bash\n   tar -tf generative_service_image.tar\n   ```\n\n### Additional Tips\n\n- **Compress the Tarball**: If you want to save space, you can compress the tarball using `gzip`:\n\n  ```bash\n  gzip generative_service_image.tar\n  ```\n\n  This will create a `generative_service_image.tar.gz` file.\n\n- **Load the Image from Tarball**: To load the saved image back into Docker on another system or after cleaning up, use:\n\n  ```bash\n  docker load -i \u003cfile_name\u003e.tar\n  ```\n\n  For example:\n\n  ```bash\n  docker load -i generative_service_image.tar\n  ```\n\nThis process allows you to export and import Docker images as needed, facilitating image transfer and backup.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzypt%2Finception","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fizzypt%2Finception","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fizzypt%2Finception/lists"}