{"id":13826380,"url":"https://github.com/vasuadari/docker","last_synced_at":"2025-10-01T01:31:23.097Z","repository":{"id":55475727,"uuid":"52200440","full_name":"vasuadari/docker","owner":"vasuadari","description":"A simple guide to get you started on docker. (Might be outdated but it should still give you a basic overview.)","archived":false,"fork":false,"pushed_at":"2020-12-28T14:27:11.000Z","size":11,"stargazers_count":21,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-14T11:46:15.991Z","etag":null,"topics":["container-docker","data-volume","docker","docker-application","docker-container","docker-tutorial","dockerfile","nginx-container","rails-application"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vasuadari.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-21T10:01:00.000Z","updated_at":"2023-03-04T09:00:58.000Z","dependencies_parsed_at":"2022-08-15T01:10:45.074Z","dependency_job_id":null,"html_url":"https://github.com/vasuadari/docker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vasuadari%2Fdocker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vasuadari%2Fdocker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vasuadari%2Fdocker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vasuadari%2Fdocker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vasuadari","download_url":"https://codeload.github.com/vasuadari/docker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234808947,"owners_count":18890088,"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":["container-docker","data-volume","docker","docker-application","docker-container","docker-tutorial","dockerfile","nginx-container","rails-application"],"created_at":"2024-08-04T09:01:36.609Z","updated_at":"2025-10-01T01:31:22.794Z","avatar_url":"https://github.com/vasuadari.png","language":"Dockerfile","readme":"# Getting started with docker\n\n## Contents\n\n1. [Introduction](#user-content-introduction)\n2. [Installation](#user-content-installation)\n3. [Basics of docker](#user-content-basics-of-docker)\n    - [docker-machine](#user-content-docker-machine)\n    - [docker](#user-content-docker)\n    - [Image](#user-content-image)\n    - [Container](#user-content-container)\n    - [Dockerfile](#user-content-dockerfile)\n    - [Docker hub](#user-content-docker-hub)\n4. [Dockerize Applications](#user-content-dockerize-applications)\n    - [Rails on docker](#user-content-rails-on-docker)\n    - [Rails application](#user-content-rails-application)\n        - [Docker compose](#user-content-docker-compose)\n        - [Creating Dockerfile](#user-content-creating-dockerfile)\n        - [Creating docker-compose file](#user-content-creating-docker-compose-file)\n        - [Start your application on docker](#user-content-running-your-application-on-docker)\n    - [Setup nginx to host your rails application](#user-content-setup-nginx-to-host-your-rails-application)\n\n## Introduction\n\nUsing docker you can wrap your application with all its dependencies into a [container](#user-content-container) by having your host machine clean.\n\n## Installation\n\nFollow below links to setup docker on your machine.\n\n[Ubuntu](https://docs.docker.com/engine/installation/linux/ubuntulinux/)\n\n[Mac OS X](https://docs.docker.com/engine/installation/mac/)\n\n## Basics of docker\n\nBefore getting started with docker, you need to understand below terminologies.\n\n### docker-machine\n\nDocker follows client-server architecture. `docker-machine` is a command to create Virtual machine with a minimal linux os running on it. All the images that you build will be hosted on this server.\n\n### docker\n\n`docker` is a command to interact with your `docker-machine`. Think of it as a client which talks to a server(`docker-machine`) to get the work done.\n\n### Image\n\nIt is a pre-built image like the ones you download for OSes which can be ran on the container.\n\n### Container\n\nLight weight virtual machine which runs your image.\n\n### Dockerfile\n\nIt is a manifest file which is used for building your own images. This manifest file contains set of instructions which guides docker to run list of commands to setup your application. Docker rebuilds the image only if it finds any new instruction after the first build.\n\nBelow is the sample Dockerfile\n\n```\n# Filename: Dockerfile\n# Pull image from the docker hub\nFROM ruby\n\nRUN which ruby\n\n```\n\nOn mac, you may need to start `docker Quickstart Terminal` before trying out docker commands.\n\nNow, run `docker build -t myruby .` within the same directory. Your output will look like the below.\nUse `-t` option to name your image.\n\n```\nSending build context to Docker daemon 197.7 MB\nStep 1 : FROM ruby\n ---\u003e c6ebc3270d1c\nStep 2 : RUN which ruby\n ---\u003e Running in 425293ec8f98\n/usr/local/bin/ruby\n ---\u003e bc3c6f463349\nRemoving intermediate container 425293ec8f98\nSuccessfully built bc3c6f463349\n```\n\nIf you try to rerun the same command, you will find that docker says that it is `Using cache`.\n\n```\nSending build context to Docker daemon 197.7 MB\nStep 1 : FROM ruby\n ---\u003e c6ebc3270d1c\nStep 2 : RUN which ruby\n ---\u003e Using cache\n ---\u003e bc3c6f463349\nSuccessfully built bc3c6f463349\n```\n\nRun `docker images` to find your images.\n\nTo start a new container, run `docker run -t myruby` which will start the irb console.\nTo enter into the container with new TTY, run `docker run -it myruby /bin/bash`.\n\n### Docker hub\n\nIt is a public repository which hosts all the docker images.\n\n## Dockerize Applications\n\nStep by step guide to move things to docker.\n\n### Rails on docker\n\n**Requirements**:\n\n- ruby\n- build-essential\n- nokogiri dependencies\n- nodejs\n\n**Dockerfile**:\n\n```\n# Pull image from the docker hub\nFROM ruby\n\nRUN apt-get update -qq \u0026\u0026 apt-get install -y build-essential\n\n# Nokogiri dependencies\nRUN apt-get install -y libxml2-dev libxslt1-dev\n\n# JS runtime dependencies\nRUN apt-get install -y nodejs\n\nRUN gem install rails\n```\n\nRun `docker build -t rails .` to create a new rails image.\n\n### Rails application\n\nLets take a sample rails application which uses MySQL database with redis and a sidekiq for running background jobs.\n\n#### Docker compose\n\n  It's a tool provided by docker(_You may need to install this separately from [here](https://docs.docker.com/compose/install/)_) which takes a YAML file with all the components, links and the ports to be exposed. And it will take care of linking, exposing ports, mounting volumes etc. This command will look for docker-compose.yml file or you can also pass the custom YAML file to it.\n\n  Sample docker-compose.yml may look like this:\n\n  ```\n  redis:\n    image: redis\n    ports:\n      - '6379'\n  ```\n\n  Run `docker-compose build` inside the directory which contains docker-compose file to build all the images and then do `docker-compose up` to start the services. When you run build, it will fetch latest redis image from the docker hub since we are using `image` option. When do `docker-compose up`, redis container will be started in its default port which we are exposing it to our host machine by setting it in the `ports` options.\n\n### Creating Dockerfile\n\nLets create a Dockerfile with ruby and install bundler.\n\n```\n# Pulls latest ruby version from the docker hub\nFROM ruby\n\nRUN apt-get update -qq \u0026\u0026 apt-get install -y build-essential\n\n# Nokogiri dependencies\nRUN apt-get install -y libxml2-dev libxslt1-dev\n\n# JS runtime dependencies\nRUN apt-get install -y nodejs\n\nRUN apt-get install -y mysql-client\n\nRUN gem install bundler\n\nENV BUNDLE_PATH /bundle\n```\n\n### Creating docker-compose file\n\nCreate a docker-compose file within the same directory where you have created Dockerfile. Typically you will have these files inside the root of your rails application.\n\n**MySQL**:\n\nFor MySQL server you would need a persistent storage meaning you wouldn't want to have data inside the same container. For these reasons, docker provides\nyou with data volume containers or you could use data volume. Lets create a data volume container for MySQL. Data volume container is a container which will save your data but use a light weight and existing image for running these containers.\n\nNow, lets create a docker-compose file with mysql data volume.\n\nFilename: docker-compose.yml\n```\nmysql_data_volume:\n  image: redis\n  volumes:\n    - /var/lib/mysql\n  command: echo 'Data container for mysql'\n```\n\nWe have named the image as `mysql_data_volume`. Here we are using `redis` as a light weight image and `/var/lib/mysql` is a path that is created in this container. Whenever we start the services, docker runs a startup command. For data containers, you don't want your containers to be running all the time.\nSo, we just run a command which will create a container and exit. But, it will not be removed.\n\nLets add MySQL server to it.\n\n```\nmysql_data_volume:\n  image: redis\n  volumes:\n    - /var/lib/mysql\n  command: echo 'Data container for mysql'\n\nmysql:\n  image: mysql:5.5\n  volumes_from:\n    - mysql_data_volume\n  environment:\n    - MYSQL_ROOT_PASSWORD=$DOCKER_MYSQL_ROOT_PASSWORD\n```\n\nHere, we are setting mysql version as `5.5` which will be downloaded from the docker hub. `mysql` will be the image name. Set the env. variable `DOCKER_MYSQL_ROOT_PASSWORD` in your host machine. When you start the services, docker will pick up the env. variables.\n\n**Redis**:\n\n```\nredis:\n  image: redis\n```\n\nI'm not creating data container for redis. But, you can try creating a data container for redis like we have done for mysql.\n\n**Sidekiq**:\n\n```\nsidekiq:\n  build: .\n  working_dir: /opt/myapp/current\n  environment:\n    - BUNDLE_GEMFILE=/opt/myapp/current/Gemfile\n  command: bundle exec sidekiq --environment staging -C /opt/myapp/shared/config/sidekiq.yml\n  volumes:\n    - '$PWD:/opt/myapp/current'\n  links:\n    - mysql\n    - redis\n```\n\n`sidekiq` will be our image name. Setting `build` to . will tell docker-compose to look for Dockerfile within this directory. You need to set working directory for running rails commands. Use `environment` to set environment variables for the sidekiq container. Running sidekiq as startup command. You can mount host volume on the docker container using `volumes` option. Syntax goes like this `[HOST_FILE_PATH]:[DOCKER_CONTAINER_FILE_PATH]`. Since, sidekiq needs mysql and redis to run, we are linking both our images to it using `links` option.\n\n**Application**\n\n```\nmyapp:\n  build: .\n  working_dir: /opt/myapp/current\n  environment:\n    - BUNDLE_GEMFILE=/opt/myapp/current/Gemfile\n  command: bundle exec thin start\n  ports:\n    - '3000:3000'\n  volumes:\n    - '$PWD:/opt/myapp/current'\n  links:\n    - mysql\n    - redis\n```\n\nWe are using same Dockerfile for both sidekiq and the application. In `ports` options, we are exposing default port of the thin server on the host machine.\n\n### Running your application on docker\n\nFirst, run `docker-compose build .` to build all the images. Once it completes, we need to run `bundle install`. You do not want to run it all the time. Lets cache the gems by creating a data volume container for bundler.\n\n```\nbundle_data:\n  image: redis\n  volumes:\n    - /bundle\n  command: echo 'Data container for bundler'\n```\n\nNow, you need to use mount these volume inside `sidekiq` and `myapp` images.\n\nYour final docker-compose will look the following,\n\n```\nbundle_data:\n  image: redis\n  volumes:\n    - /bundle\n  command: echo 'Data container for bundler'\n\nmysql_data_volume:\n  image: redis\n  volumes:\n    - /var/lib/mysql\n  command: echo 'Data container for mysql'\n\nmysql:\n  image: mysql:5.5\n  volumes_from:\n    - mysql_data_volume\n  environment:\n    - MYSQL_ROOT_PASSWORD=$DOCKER_MYSQL_ROOT_PASSWORD\n\nredis:\n  image: redis\n\nsidekiq:\n  build: .\n  working_dir: /opt/myapp/current\n  environment:\n    - BUNDLE_GEMFILE=/opt/myapp/current/Gemfile\n  command: bundle exec sidekiq --environment staging -C /opt/myapp/shared/config/sidekiq.yml\n  volumes:\n    - '$PWD:/opt/myapp/current'\n  volumes_from:\n    - bundle_data\n  links:\n    - mysql\n    - redis\n\nmyapp:\n  build: .\n  working_dir: /opt/myapp/current\n  environment:\n    - BUNDLE_GEMFILE=/opt/myapp/current/Gemfile\n  command: bundle exec thin start\n  ports:\n    - '3000:3000'\n  volumes:\n    - '$PWD:/opt/myapp/current'\n  volumes_from:\n    - bundle_data\n  links:\n    - mysql\n    - redis\n```\n\nTo run `bundle install` using docker-compose, do `docker-compose run myapp bundle install`.\n\nFinally, run `docker-compose up` to start all the services.\n\n### Setup nginx to host your rails application\n\nUsing nginx, we are going to expose port 80 to outside world which serves your rails application. We're going to link rails app with nginx container. So far we have seen how to link containers within a directory. Lets see how to link external containers within the current directory which contains docker-compose.yml for nginx.\n\nLets create a nginx conf file.\n\n**nginx.conf**\n\n```\nuser www-data;\nworker_processes 4;\n\nevents {\n  worker_connections 768;\n}\n\nhttp {\n  sendfile on;\n  tcp_nopush on;\n  tcp_nodelay on;\n  keepalive_timeout 65;\n  types_hash_max_size 2048;\n\n  default_type application/octet-stream;\n\n  access_log /var/log/nginx/access.log;\n  error_log /var/log/nginx/error.log;\n\n  gzip on;\n  gzip_disable 'msie6';\n\n  include /etc/nginx/conf.d/*.conf;\n  include /etc/nginx/sites-enabled/myapp;\n}\n```\n\n**sites-enabled/myapp**\n\n```\nserver {\n  listen 80;\n  server_name localhost;\n\n  root /opt/myapp/current/public;\n\n  location / {\n    proxy_pass http://rails_app_myapp_1:3000;\n  }\n}\n```\n\n**docker-compose.yml**\n\n```\nweb_server:\n  image: nginx\n  volumes:\n    - './config:/etc/nginx'\n    - '/opt/myapp:/opt/myapp'\n    - '/var/log/nginx:/var/log/nginx'\n  ports:\n    - '80:80'\n  external_links:\n    - rails_app_myapp_1\n```\n\nMounting volumes for nginx configuration, your application directory and nginx log path. Also exposing port 80 on your host machine. `rails_app` is directory name of your rails app which contains docker files and `myapp_1` is nothing but your image name of your app. When you start any container docker will name the container with the image name and suffixes it with `_[0-9.*]` and thats why we are using `rails_app_myapp_1`. To verify it, just run `docker ps` command if you rails app container is running. You will find this container name.\n\nNow just run `docker-compose up` to start the nginx container.\n","funding_links":[],"categories":["Dockerfile"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvasuadari%2Fdocker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvasuadari%2Fdocker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvasuadari%2Fdocker/lists"}