”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 在 Docker 容器上设置 Redmine

在 Docker 容器上设置 Redmine

发布于2024-11-09
浏览:240

Setup Redmine on Docker Container

Redmine 是一个灵活的开源项目管理和问题跟踪 Web 应用程序。它广泛用于管理项目、跟踪错误以及处理任务和截止日期。 Redmine 使用 Ruby on Rails 开发,具有高度可定制性,支持广泛的团队协作和项目组织功能。

Redmine 因其灵活性、定制性和开源特性而成为商业项目管理工具的流行替代品。

在本文中,我们将在 docker 容器上设置 redmine 以及数据库服务器、mysql 和 nginx 作为反向代理。

安装 Docker

我们使用托管在AWS EC2上的ubuntu服务器和docker官方的安装指南。

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

我们使用最新版本的 docker 以及 docker compose。

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

好了,docker安装完毕,接下来我们需要配置我们的用户(ubuntu)可以直接访问docker,无需sudo。

sudo groupadd docker
sudo usermod -aG docker $USER

然后注销并再次登录我们的服务器。 Docker 已准备就绪!
我们可以使用下面的命令在服务器重新启动时启动 docker 容器。

sudo systemctl enable docker.service
sudo systemctl enable containerd.service

docker 容器目前就足够了。

创建 docker compose 文件

我们将创建一个 docker compose 文件。

nano docker-compose.yaml

并粘贴此 yaml 代码。

version: '3.1'

services:
  nginx:
    # we use the latest of nginx as base
    image: nginx:latest
    restart: always
    # we expose port 80 and 443 to the public as our reverse proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      # we link volume from host for nginx configuration
      - './nginx.conf:/etc/nginx/conf.d/nginx.conf'
      # we link volume from host for nginx certs
      - './certs:/etc/nginx/certs'
      # we link also timezone from the host
      - '/etc/localtime:/etc/localtime:ro'
      - '/etc/timezone:/etc/timezone:ro'
    depends_on:
      # we will wait until server redmine is ready
      - redmine
  redmine:
    # we use redmine from dockerhub as base
    image: redmine
    restart: always
    volumes:
      # we link redmine data to our local storage, so it will persistent when
      # the service redmine restarted
      - 'redmine_data:/usr/src/redmine/files'
      # we link redmine plugin also from the host
      - '/home/bkn/redmine_plugins:/usr/src/redmine/plugins'
      # we link also timezone from the host
      - '/etc/localtime:/etc/localtime:ro'
      - '/etc/timezone:/etc/timezone:ro'
    # we don't expose port on this service because nginx service will do
    # default port redmine expose internally is 3000
    #ports:
      #- 3000:3000
      #- 444:3000
    environment:
      # we create some env for redmine
      REDMINE_DB_MYSQL: db
      REDMINE_DB_PORT: 3306
      REDMINE_DB_DATABASE: redmine_db
      REDMINE_DB_USERNAME: redmine
      REDMINE_DB_PASSWORD: my_p@ssword
      REDMINE_SECRET_KEY_BASE: G75eddsecretkey
    # we will wait until db service is ready
    depends_on:
      - db
  db:
    # we use mysql server for redmine database
    image: mysql:8.0
    restart: always
    volumes:
      # we also link the database storage with volume we created below
      - 'mysql_data:/var/lib/mysql'
    environment:
      # we create some env for mysql
      MYSQL_USER: redmine
      MYSQL_PASSWORD: my_p@ssword
      MYSQL_RANDOM_ROOT_PASSWORD: 1
      MYSQL_ROOT_PASSWORD: JRFFHT534rth4u3!@#
      MYSQL_DATABASE: redmine_db

volumes:
  # we create two volume used by redmine and our database
  mysql_data:
    driver: local
  redmine_data:
    driver: local

接下来,我们创建 nginx 配置文件,与 docker-compose 文件相同的文件夹

nano nginx/nginx.conf
server {
        listen 80;
        server_name proman.withenri.tech;
        location / {
            proxy_pass http://henri_redmine_1:3000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
server {
        listen 443 ssl;
        server_name proman.withenri.tech;
        ssl_certificate /etc/nginx/certs/withenri.tech_chained.crt;
        ssl_certificate_key /etc/nginx/certs/withenri.tech.key;
        location / {
            proxy_pass http://henri_redmine_1:3000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }

并创建名为 certs 的文件夹,然后将我们的证书放在那里。

创建容器

让我们使用命令运行我们的 docker compose 文件

docker-compose up -d

当我们运行这个 docker compose 文件时,将自动创建一个网络并链接这些网络中的三个服务(nginx、redmine、db)。

我们可以使用命令检查我们的容器:

docker ps -a

然后在我们的浏览器上使用端口 80 和端口 443 以及 https 连接测试 redmine 应用程序。使用用户“admin”和密码“admin”登录我们的 redmine 应用程序。

这篇文章和我们直接安装在vps上基本是一样的,参考这篇文章。

希望这篇文章对您有帮助!

版本声明 本文转载于:https://dev.to/henri_sekeladi/setup-redmine-on-docker-container-ohk?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何使用node-mysql在单个查询中执行多个SQL语句?
    如何使用node-mysql在单个查询中执行多个SQL语句?
    Multi-Statement Query Support in Node-MySQLIn Node.js, the question arises when executing multiple SQL statements in a single query using the node-mys...
    编程 发布于2025-04-29
  • MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    在两个条件下插入或更新或更新 solution:的答案在于mysql的插入中...在重复键更新语法上。如果不存在匹配行或更新现有行,则此功能强大的功能可以通过插入新行来进行有效的数据操作。如果违反了唯一的密钥约束。实现所需的行为,该表必须具有唯一的键定义(在这种情况下为'名称'...
    编程 发布于2025-04-29
  • 您如何在Laravel Blade模板中定义变量?
    您如何在Laravel Blade模板中定义变量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配变量对于存储以后使用的数据至关重要。在使用“ {{}}”分配变量的同时,它可能并不总是最优雅的解决方案。幸运的是,Blade通过@php Directive提供了更优雅的方法: $ old_section =“...
    编程 发布于2025-04-29
  • Entity Framework 5更新记录的最佳方法
    Entity Framework 5更新记录的最佳方法
    Entity Framework 5记录更新的最佳实践 在Entity Framework 5中更新记录,开发者常常面临多种方法的选择,每种方法都有其优缺点。本文将探讨三种常用方法及其局限性,并最终给出最佳方案。 方法一:加载原始记录并逐个更新属性 此方法需要先加载原始记录,然后手动更新每个修改后...
    编程 发布于2025-04-29
  • C#静态变量如何工作及为何不能在方法内声明
    C#静态变量如何工作及为何不能在方法内声明
    C#中的静态变量 许多开发人员难以理解C#中静态变量的功能。本文旨在阐明它们的用途和用法,同时解释为什么不能在方法内部声明静态变量。 什么是静态变量? 静态变量是类级别的变量,在该类的所有实例之间共享。其值在从该类创建的所有对象之间共享。 何时使用静态变量? 在需要跨类的多个实例维护值的情况下,通...
    编程 发布于2025-04-29
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    编程 发布于2025-04-29
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-04-29
  • IACA助力优化Intel CPU代码性能分析
    IACA助力优化Intel CPU代码性能分析
    被称为英特尔体系结构代码分析仪,IACA是用于评估针对Intel CPU的代码调度的高级工具。它以三种模式运行: 吞吐量模式: iaca iaca衡量最大的吞吐量,假设它是嵌套循环的主体。 IACA traces the sequence of instructions as they progr...
    编程 发布于2025-04-29
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
    编程 发布于2025-04-29
  • 如何使用PHP将斑点(图像)正确插入MySQL?
    如何使用PHP将斑点(图像)正确插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call ...
    编程 发布于2025-04-29
  • Java GUI计算器中如何使用getSource()获取数字按钮值?
    Java GUI计算器中如何使用getSource()获取数字按钮值?
    如何使用getSource() 要检索每个按钮的值,请按照以下步骤操作: 当前的code bud y you budsors。 ETC。)。为数字按钮(例如NumactionListener)创建一个单独的操作侦听器。 为号码按钮注册操作侦听器。将NumactionListener添加到所有数字按...
    编程 发布于2025-04-29
  • Java字符串非空且非null的有效检查方法
    Java字符串非空且非null的有效检查方法
    检查字符串是否不是null而不是空的 if(str!= null && str.isementy())二手: if(str!= null && str.length()== 0) option 3:trim()。isement(Isement() trim whitespace whitesp...
    编程 发布于2025-04-29
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月份)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将...
    编程 发布于2025-04-29
  • Go语言垃圾回收如何处理切片内存?
    Go语言垃圾回收如何处理切片内存?
    Garbage Collection in Go Slices: A Detailed AnalysisIn Go, a slice is a dynamic array that references an underlying array.使用切片时,了解垃圾收集行为至关重要,以避免潜在的内存泄...
    编程 发布于2025-04-29
  • 使用JavaScript将SVG转换为JPEG、PNG等格式的技巧
    使用JavaScript将SVG转换为JPEG、PNG等格式的技巧
    将SVG转换为JPEG,PNG和浏览器中的其他格式 从SVG图形中创建高质量的图像可能是一个挑战,尤其是您需要以各种格式导出它们。 JavaScript为此任务提供了一种多功能解决方案,使您无需外部工具或插件即可将SVG图像无缝地转换为位映射。 使用canvg库进行渲染:Capture Image...
    编程 发布于2025-04-29

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3