{"id":15725860,"url":"https://github.com/ndrean/sinatra-docker-nginx","last_synced_at":"2026-05-13T07:03:09.385Z","repository":{"id":56053299,"uuid":"313169784","full_name":"ndrean/sinatra-docker-nginx","owner":"ndrean","description":"A DNS load balanced dockerized  Sinatra/Puma  app on Docker with Postgres and Nginx.","archived":false,"fork":false,"pushed_at":"2020-11-28T16:49:01.000Z","size":768,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T01:28:44.604Z","etag":null,"topics":["dns-load-balancer","docker","load-balancing","nginx","postgres","puma","sequel","sinatra","static-file-server"],"latest_commit_sha":null,"homepage":"","language":"HTML","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/ndrean.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}},"created_at":"2020-11-16T02:22:33.000Z","updated_at":"2020-12-06T01:01:29.000Z","dependencies_parsed_at":"2022-08-15T12:20:11.797Z","dependency_job_id":null,"html_url":"https://github.com/ndrean/sinatra-docker-nginx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ndrean/sinatra-docker-nginx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fsinatra-docker-nginx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fsinatra-docker-nginx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fsinatra-docker-nginx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fsinatra-docker-nginx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ndrean","download_url":"https://codeload.github.com/ndrean/sinatra-docker-nginx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fsinatra-docker-nginx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32971672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T06:31:55.726Z","status":"ssl_error","status_checked_at":"2026-05-13T06:31:51.336Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["dns-load-balancer","docker","load-balancing","nginx","postgres","puma","sequel","sinatra","static-file-server"],"created_at":"2024-10-03T22:24:38.929Z","updated_at":"2026-05-13T07:03:09.370Z","avatar_url":"https://github.com/ndrean.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nginx config on Docker to serve multiple containerized apps\n\n```bash\n  proxy_cache_path /var/cache/nginx/mycache levels=1:2 keys_zone=mycache:1m inactive=10m;\n\n\n  # mapping between file type and expires length for browser caching;\n  map $sent_http_content_type $expires {\n      default                    off;\n      text/html                  epoch;\n      text/css                   max;\n      application/javascript     max;\n      ~image/                    max;\n  }\n\n  log_format my_log ' \"Request: $Request, Status: $status, Request_uri: $request_uri, Host: $host, Host: $upstream, Client_IP: $remote_addr, Proxy_IP: $proxy_add_x_forwarded_for, Proxy_Hostname: $proxy_host, Real_IP: $http_x_real_ip, Cache_Status: $upstream_cache_status  \"';\n  # check tail -f access.log\n\n  server {\n    server_name webapp.me*; # file /etc/hosts modified \u0026 \u003c- if SSL\n    listen 8080  default_server;\n\n    access_log /var/log/nginx/access.log my_log; #\u003c- to watch logs\n\n    set $upstream $PROXY_UPSTREAM;\n\n    proxy_set_header  Host            $upstream;  # $http_host needed for Rails ??\n    proxy_set_header Connection       \"\";\n    proxy_set_header  X-Real-IP       $remote_addr; # client IP adress\n    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;\n\n    # configure a resolver for Nginx with the address of your actual DNS resolver.\n    resolver 127.0.0.11:53  valid=1s; # \u003c- Docker network DNS resolver\n\n    expires   $expires;       # reading the mapping file/$expires\n\n    # Proxy-caching by Nginx\n    proxy_cache       mycache;\n    proxy_cache_valid 60m;\n    add_header        X-Proxy-Cache $upstream_cache_status;\n    proxy_cache_key   $scheme$request_method$host$request_uri;\n\n    location ~ \\.(jpeg|css|png|js|webp|ico)$ {\n      # since we run nginx in a separate container from the app, then we need to copy\n      # the static files into the nginx container. We do this with a bind, and tthe files\n      # are located in the folder below.\n      root /usr/share/nginx/html;\n\n      # return 200 http://webapp:8080$uri; # testing..\n\n      # gzip_static on;\n      access_log off;\n      add_header Cache-Control public;\n      add_header Last-Modified \"\";\n      add_header ETag \"\";\n\n      break;\n    }\n\n    # any other request not found by the regex and starting with '/' will be served by @app\n    location / {\n      # proxy_pass http://webapp;   \u003c- if 'upstream directive as can't pass env var'\n      proxy_pass http://$upstream; #$request_uri; # $request_uri; \u003c- revers proxying\n\n      gzip_static on;\n      proxy_pass_header Authorization;\n      proxy_http_version 1.1;\n      proxy_ssl_server_name on;\n\n      proxy_buffering       off;\n      proxy_read_timeout    5s;\n      proxy_redirect        off;\n      proxy_ssl_verify      off;\n      client_max_body_size  0;\n    }\n  }\n\n```\n\n# Postgres \u0026 ORM Sequel\n\ngem 'pg'\ngem 'sequel'\ngem 'gem 'sequel_pg', :require=\u003e'sequel'\n(no require)\n\n1. Create database\n   `\u003e: psql createdb test`\n\n2. Create USER/PWD\n   `\u003e: psql create ...`\n\n3. Create table\n   Run a SQL script\n\n4. Connect ot the database\n   Sequel.connect(\\$POSTGRES_URL)\n\n5. Create model\n\n```ruby\nclass Owner \u003c Sequel::Model\n  one_to_many :dogs\n\n  def validate\n    super\n    errors.add(:name, \"must be present\") if name.empty?\n  end\nend\n```\n\n6. Migration\n\n```ruby\nSequel.migration do\n  change do\n    create_table(:dogs) do\n      primary_key :id\n      String :ip, :null =\u003e false\n      ...\n    end\n  end\nend\n```\n\nand run: `sequel [path/to/migrate-file] postgres://[host]/[db-name]``\nFor example:\n\n```sh\n\u003e sequel -m /db/migrates/ postgres://localhost/test\n```\n\n7. Seeding\n   With the gem `sequel-seed`, we do:\n\n```ruby\nSequel.seed do\n    def run\n        ['123.123.123','/', 2020-11-01],\n        ['127.0.0.1','/',2020-11-02]\n        .each do |ip, path, requested_at|\n            Request.create(ip: ip, path: path, requested_at: requested_at )\n        end\n    end\nend\n```\n\nwe can do in the app:\n\n```ruby\nrequire 'sequel/extensions/seed'\nSequel.extension :seed\n\nSequel::Seeder.apply(DB,\"db/seeds\")\n```\n\n# Useful commands\n\n\u003e crop images and change format with Imagemagick\n\n`magick convert puma.jpeg -resize 180x180! puma.webp`\n\n\u003e Sinatra console (IRB)\n\n`bundle exec irb -I. -r app.rb`\n\n\u003e find file by name\n\n`ls / f -name puma.rb`\n=\u003e /usr/local/bin/puma\n\n\u003e find directory by name\n\n`ls / -type d -name bundle`\n\n\u003e find all directories in current directory\n\n`ls . -type d`\n\n\u003e create several subdir with '-p' in one go)\n\n`mkdir -p tmp/{pids,sockets}`\n\n\u003e count number of lines\n\n- List all Docker processes with:\n- `docker ps -q |wc -l` ('-q' is the get the process id, and '|wc' is 'Word Count)\n- List all TCP connections with `netstat -t`\n\n# Dotenv with Sinatra (or Rack based apps)\n\n\u003chttps://github.com/bkeepers/dotenv\u003e\n\nWe pass environment variables to **Sinatra** via the `.env` file and the `Dotenv` gem. It shuold be loaded as early as possible in the `Rakefile`. It loads by default `.env`:\n\n```ruby\n#Rakefile\nrequire 'dotenv'\nDotenv.load('.env')\n```\n\nThen we can get the variables with `ENV['PORT']` or better `ENV.fetch('PORT') { 9292 }` since this fraises an exception if not present. We also yield a default value.\n\n# Config Sinatra / Puma / Rack\n\nWe extend the class `Sinatra::Base` with a class `App \u003c Sinatra::Base` so we need to pass the class to `run App`.\n\nSince we use **bundler**, we need a `config.ru` for `rackup` since Rack launchs with `rackup config.ru`. The location of the \"DefaultRackup`is found with`File.expand_path(\".\",**dir**)` (try this in IRB).\n\nThen we can start the app in the Dockerfile with `bundle exec Puma -C puma.rb` where 'puma.rb' is Puma's config file.\n\n\u003chttps://medium.com/@theterminalguy/using-bundler-with-sinatra-e194c3422c6a\u003e\n\n# .dockerignore\n\nTo avoid to copy files into the container such as /tmp/pids/, you exclude them by putting into the dockerignore.\n\n# Docker-compose\n\n`docker-compose up --build`\n`docker-compose down`\nOpen a container for exploration during execution:\n`docker-compose exec webapp sh`\nScale up:\n`docker-compose up --scale webapp=2``\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndrean%2Fsinatra-docker-nginx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fndrean%2Fsinatra-docker-nginx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndrean%2Fsinatra-docker-nginx/lists"}