├── .gitignore ├── base-images ├── nginx.Dockerfile └── nginx.conf ├── app.env.example ├── docker-compose.yml ├── README.md └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | app.env -------------------------------------------------------------------------------- /base-images/nginx.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM firhq/sslguala-ui-ce:1.0 as build-stage 2 | 3 | FROM nginx 4 | RUN apt-get update -qq && apt-get -y install apache2-utils 5 | ENV RAILS_ROOT /sslguala-ce 6 | WORKDIR $RAILS_ROOT 7 | RUN mkdir log 8 | RUN mkdir dist 9 | COPY --from=build-stage /sslguala-ui-ce/dist dist/ 10 | COPY nginx.conf /tmp/docker.nginx 11 | RUN envsubst '$RAILS_ROOT' < /tmp/docker.nginx > /etc/nginx/conf.d/default.conf 12 | EXPOSE 80 13 | CMD [ "nginx", "-g", "daemon off;" ] -------------------------------------------------------------------------------- /app.env.example: -------------------------------------------------------------------------------- 1 | # 域名地址 2 | WEB_DOMAIN='sslguala-ce.ce04.com' 3 | 4 | # 微信登录的appid以及key 5 | WECHAT_APP_ID='' 6 | WECHAT_APP_SECRET='' 7 | # 错误监控sentry的地址 8 | SENTRY_URL='' 9 | # 邮件发送的相关配置 10 | TUBECENTER_APP_TOKEN='' 11 | TUBECENTER_APP_URL='' 12 | # newrelic的key 13 | NEWRELIC_KEY='' 14 | 15 | REDIS_URL=redis://redis:6379/1 # redis的链接地址 16 | 17 | # postgres的数据库地址 18 | POSTGRES_DATABASE=sslguala_production 19 | POSTGRES_USERNAME=postgres 20 | POSTGRES_PASSWORD=postgres 21 | POSTGRES_HOST=db -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | app: 4 | ports: 5 | - 3010:3000 6 | image: firhq/sslguala-ce:1.0 7 | container_name: sslguala-ce 8 | command: bash -c "bundle exec rails s -b 0.0.0.0 -p 3000" 9 | environment: 10 | - ENV=production 11 | - RAILS_ENV=production 12 | env_file: 13 | - app.env 14 | depends_on: 15 | - redis 16 | - db 17 | volumes: 18 | - ./log:/sslguala-ce/log 19 | - ./public:/sslguala-ce/public # nginx 可以处理内容 20 | - ./public/assets:/sslguala-ce/public/assets # nginx 可以处理内容 21 | - ./public/packs:/sslguala-ce/public/packs # nginx 可以处理内容 22 | - ./tmp/pids:/sslguala-ce/tmp/pids 23 | db: 24 | image: postgres:10 25 | volumes: 26 | - "./datadir/postgresql:/var/lib/postgresql/data" 27 | environment: 28 | - POSTGRES_USER=postgres 29 | - POSTGRES_PASSWORD=postgres 30 | redis: 31 | image: redis:4 32 | volumes: 33 | - './datadir/redis:/data' 34 | nginx: 35 | image: firhq/sslguala-ce-nginx:1.0 36 | depends_on: 37 | - app 38 | ports: 39 | - 3011:80 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 使用docker运行 2 | 3 | 以ubuntu为例子[docker 入门](https://yeasy.gitbook.io/docker_practice/install/ubuntu) 4 | 5 | ## 1. 安装docker 6 | ``` 7 | $ curl -fsSL get.docker.com -o get-docker.sh 8 | $ sudo sh get-docker.sh --mirror Aliyun 9 | ``` 10 | 启动docker 11 | ``` 12 | $ sudo systemctl enable docker 13 | $ sudo systemctl start docker 14 | ``` 15 | 建立docker用户组 16 | ``` 17 | $ sudo groupadd docker 18 | $ sudo usermod -aG docker $USER 19 | ``` 20 | 21 | ## 2. 安装docker-compose 22 | 23 | ``` 24 | # 国内用户可以使用以下方式加快下载 25 | $ sudo curl -L https://download.fastgit.org/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose 26 | 27 | $ sudo chmod +x /usr/local/bin/docker-compose 28 | ``` 29 | 30 | ## 3. 修改环境变量 31 | 32 | ``` 33 | cp app.env.example app.env 34 | ``` 35 | 36 | 生成环境变量文件后, 可自行调整里面的内容 37 | 38 | ## 4. 运行项目 39 | 生成数据库以及数据结构 40 | 41 | ``` 42 | make install 43 | ``` 44 | 45 | 启动项目 46 | 47 | ``` 48 | docker-compose up 49 | ``` 50 | 后台运行 51 | 52 | ``` 53 | docker-compose up -d 54 | ``` 55 | 56 | ## 查看项目运行情况 57 | 默认暴露 3011 端口, 如ip为 223.123.45.2, 则可以访问 223.123.45.2:3011 。 注意3011端口需开放。 -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | RAKE = docker-compose run app bundle exec rake 2 | RUN = docker-compose run app 3 | RUN_DB = docker-compose run postgres 4 | 5 | include app.env 6 | export 7 | 8 | install: 9 | @touch app.env 10 | @$(RUN) bundle exec rails db:create 11 | @$(RUN) bundle exec rails db:migrate 12 | @$(RUN) bundle exec rails db:seed 13 | install_ssl: 14 | @echo "[DEPRECATED] \"make install_ssl\": command was been deprecated. Now we use Caddy Server for automatically manage SSL." 15 | update: 16 | @sh ./scripts/create-version 17 | @docker-compose pull 18 | @make secret 19 | @touch app.local.env 20 | @make restart 21 | @docker tag homeland/homeland:latest homeland/homeland:$$(date "+%Y%m%d%H%M%S") 22 | restart: 23 | @sh ./scripts/restart-app 24 | @docker-compose stop web 25 | @docker-compose up -d web 26 | @docker-compose stop app_backup 27 | start: 28 | @docker-compose up -d 29 | status: 30 | @docker-compose ps 31 | stop: 32 | @docker-compose stop caddy web app app_backup worker 33 | stop-all: 34 | @docker-compose down 35 | console: 36 | @$(RUN) bundle exec rails console 37 | clean: 38 | @echo "Clean Docker images..." 39 | @docker ps -aqf status=exited | xargs docker rm && docker images -qf dangling=true | xargs docker rmi 40 | backup: 41 | @echo "Backing up database..." 42 | @$(RUN_DB) pg_dump -d homeland -h postgresql -U postgres > postgres.sql -------------------------------------------------------------------------------- /base-images/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | #listen 443 ssl; 3 | #ssl_certificate /root/.acme.sh/sslguala.com/fullchain.cer; 4 | #ssl_certificate_key /root/.acme.sh/sslguala.com/sslguala.com.key; 5 | add_header Strict-Transport-Security "max-age=31536000"; 6 | 7 | server_name localhost; 8 | root /sslguala-ce/dist; 9 | #try_files $uri/index.html $uri @puma_sslguala_production; 10 | 11 | client_max_body_size 4G; 12 | keepalive_timeout 30; 13 | 14 | error_page 500 502 504 /500.html; 15 | error_page 503 @503; 16 | 17 | location ^~ /assets/ { 18 | gzip_static on; 19 | expires max; 20 | add_header Cache-Control public; 21 | } 22 | 23 | location = /50x.html { 24 | root html; 25 | } 26 | 27 | location = /404.html { 28 | root html; 29 | } 30 | 31 | location /users { 32 | rewrite (.*) /$1 break; 33 | proxy_pass http://app; 34 | proxy_redirect off; 35 | } 36 | 37 | location /madmin { 38 | rewrite (.*) /api/$1 break; 39 | proxy_pass http://app; 40 | proxy_redirect off; 41 | } 42 | 43 | 44 | location /api { 45 | rewrite /api/(.*) /api/$1 break; 46 | proxy_pass http://app; 47 | proxy_redirect off; 48 | } 49 | 50 | location / { 51 | # First attempt to serve request as file, then 52 | # as directory, then fall back to displaying a 404. 53 | try_files $uri $uri/ /index.html =404; 54 | } 55 | location @503 { 56 | error_page 405 = /system/maintenance.html; 57 | if (-f $document_root/system/maintenance.html) { 58 | rewrite ^(.*)$ /system/maintenance.html break; 59 | } 60 | rewrite ^(.*)$ /503.html break; 61 | } 62 | 63 | if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){ 64 | return 405; 65 | } 66 | 67 | if (-f $document_root/system/maintenance.html) { 68 | return 503; 69 | } 70 | } 71 | 72 | 73 | upstream app { 74 | server 'app:3000'; 75 | } 76 | server { 77 | listen 3000; 78 | server_name localhost; 79 | # ~2 seconds is often enough for most folks to parse HTML/CSS and 80 | # retrieve needed images/icons/frames, connections are cheap in 81 | # nginx so increasing this is generally safe... 82 | keepalive_timeout 5; 83 | # path for static files 84 | root /app/public; 85 | access_log /sslguala-ce/log/nginx.access.log; 86 | error_log /sslguala-ce/log/nginx.error.log info; 87 | # this rewrites all the requests to the maintenance.html 88 | # page if it exists in the doc root. This is for capistrano's 89 | # disable web task 90 | if (-f $document_root/maintenance.html) { 91 | rewrite ^(.*)$ /maintenance.html last; 92 | break; 93 | } 94 | location / { 95 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 96 | proxy_set_header Host $host; 97 | # If the file exists as a static file serve it directly without 98 | # running all the other rewrite tests on it 99 | if (-f $request_filename) { 100 | break; 101 | } 102 | # check for index.html for directory index 103 | # if it's there on the filesystem then rewrite 104 | # the url to add /index.html to the end of it 105 | # and then break to send it to the next config rules. 106 | if (-f $request_filename/index.html) { 107 | rewrite (.*) $1/index.html break; 108 | } 109 | # this is the meat of the rack page caching config 110 | # it adds .html to the end of the url and then checks 111 | # the filesystem for that file. If it exists, then we 112 | # rewrite the url to have explicit .html on the end 113 | # and then send it on its way to the next config rule. 114 | # if there is no file on the fs then it sets all the 115 | # necessary headers and proxies to our upstream pumas 116 | if (-f $request_filename.html) { 117 | rewrite (.*) $1.html break; 118 | } 119 | if (!-f $request_filename) { 120 | proxy_pass http://app; 121 | break; 122 | } 123 | } 124 | # Now this supposedly should work as it gets the filenames with querystrings that Rails provides. 125 | # BUT there's a chance it could break the ajax calls. 126 | location ~* \.(ico|css|gif|jpe?g|png|js)(\?[0-9]+)?$ { 127 | expires max; 128 | break; 129 | } 130 | # Error pages 131 | # error_page 500 502 503 504 /500.html; 132 | location = /500.html { 133 | root /sslguala-ce/public; 134 | } 135 | } --------------------------------------------------------------------------------