Sometimes we want to manage source code or configuration files for small projects or laboratories with a Git server, but we don't want to use any of the hosted services available on the Internet, either due to privacy reasons, or to work on a disconnected environment.
Gogs is a self-hosted Git server written in Go that provides many of the same features you find in cloud-based Git services such as GitLab or GitHub. For more information about this project check the official GitHub repository. Gogs allows you to deploy a local Git server for a single machine or a small network. It lets you clone and push code using HTTP and SSH protocols, and provides a nice web UI with common features such as Pull Requests and Issues.
In this tutorial, you use Podman to run a local Gogs server using containers. By deploying Gogs in a container, you don't need to worry about downloading and compiling the code. It also allows you to manage the entire configuration with a single directory that is shared with the container. Finally, it permits easy upgrades by running the latest versions of the container image.
Let's start by installing Podman.
In Red Hat Enterprise Linux (RHEL) 8, deploy Podman by installing the
container-tools module. List the available versions with the following command:
$ sudo dnf module list container-tools Name Stream Profiles Summary container-tools rhel8 [d] common [d] Common tools and dependencies for container runtimes container-tools 1.0 common [d] Common tools and dependencies for container runtimes container-tools 2.0 common [d] Common tools and dependencies for container runtimes Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
Install the default stream for this module:
$ sudo dnf module install -y container-tools
Wait until the installation finishes and test Podman by running:
$ podman run --rm busybox echo hello world Trying to pull docker.io/library/busybox... Getting image source signatures Copying blob 91f30d776fb2 done Copying config c7c37e472d done Writing manifest to image destination Storing signatures hello world
In Red Hat Enterprise Linux (RHEL) 8, Podman is already configured to run "rootless" containers.
For more information about installing and configuring Podman in RHEL8, consult the product documentation.
For general information about Podman and installation instructions for other Linux distributions, consult the project page.
Now that Podman is installed, let's start the Gogs container.
Start the Gogs container
By default, data in the container is ephemeral and is deleted when the container is removed. That is fine for temporary data or if we can quickly re-create the environment. Since we're deploying a Git server that we may want to use for a long time, we need to ensure data persists across containers and system restarts. Otherwise, we would have to re-deploy the Gogs server every time.
The Gogs container supports custom data in the
/data directory. To ensure data persists, we map that directory in the container to a local directory using the
-v option with the
podman run command. First, create the local directory. For this example, we use
$HOME/var/gogs, but you can use any directory for which you have write permissions. Here is the command:
$ mkdir -p $HOME/var/gogs $ ls -ld $HOME/var/gogs drwxrwxr-x. 2 ricardo ricardo 6 Aug 1 18:26 /home/ricardo/var/gogs
The Gogs container uses two TCP ports for external communications: Port 22 for SSH communication and port 3000 for HTTP. Because you're running this container in "rootless" mode, you cannot use port 22. It would conflict with the machine's SSH service. In this case, we'll map this port to port 10022. Users can access Gogs via SSH through this port. We'll also expose the HTTP port as 10080, so it's close to the SSH port. This makes it easier to find grouped entries in case you decide to run several instances of Gogs in the same machine.
Now that you defined the volume and the required ports, use these values to start the Gogs container, like this:
$ podman run -d --name gogs01 -p 10022:22 -p 10080:3000 -v /home/ricardo/var/gogs:/data:Z gogs/gogs e884b6dfc3197204308c7ddbb37369ae81c2ef845c801d16b87940b14fb0231d
This command returns the container ID for the running container. Your ID will be different from this example.
Note that we used the option
:Z when mounting the local volume. This is necessary on RHEL8 to allow Podman to create the volume with the correct SELinux permissions. You can omit this option when running this example in a system that does not use SELinux.
Verify that the container is running with
podman ps -l to list the most recently started container:
$ podman ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e884b6dfc319 docker.io/gogs/gogs:latest /bin/s6-svscan /a... 2 minutes ago Up 2 minutes ago 0.0.0.0:10022->22/tcp, 0.0.0.0:10080->3000/tcp gogs01
You can also list the persistent directory content using
ls -lZ to ensure the sub-directories were created with the correct SELinux label `container_file_t`:
$ ls -lZ $HOME/var/gogs total 0 drwxr-xr-x. 3 100999 100999 system_u:object_r:container_file_t:s0:c355,c706 18 Aug 1 18:36 git drwxr-xr-x. 5 100999 100999 system_u:object_r:container_file_t:s0:c355,c706 41 Aug 1 18:36 gogs drwx------. 2 100999 100999 system_u:object_r:container_file_t:s0:c355,c706 226 Aug 1 18:36 ssh
Now that the Gogs container is up and running let's configure it for remote access.
[ Getting started with containers? Check out this free course. Deploying containerized applications: A technical overview. ]
If you want to use this container locally, you can access it directly using the hostname
localhost. For this example, we'll assume that we want to access it remotely so we can push code from other machines in the same network.
First, add the exposed ports to the firewall to allow remote access. In RHEL8, use
firewall-cmd for that:
$ sudo firewall-cmd --add-port=10080/tcp --add-port=10022/tcp success $ sudo firewall-cmd --add-port=10080/tcp --add-port=10022/tcp --permanent success
Now list the enabled ports to ensure they are configured correctly:
$ sudo firewall-cmd --list-ports 10080/tcp 10022/tcp
Then, use a browser to access the Gogs server. Use the appropriate hostname or IP address for your machine. For this example, the hostname of this machine is
rh8vm02 so we can access it by browsing to
The first time you access it, Gogs presents the configuration page where you define its main settings. First, select the database to store Gogs data. Gogs supports several databases, including Postgres, MySQL, and SQLite3. Since we're running a personal server, let's use SQLite3, a local database stored in a single file in the data directory. By using SQLite3, you don't need to manage another database instance. Leave the database file path as is:
Next, set the domain value to the hostname of the machine running the Gogs container. In this case,
rh8vm02. Set the SSH port to the exposed port value: 10022.
Finally, set the application URL to match your server's hostname and the exposed HTTP port. In this example,
When you're done with the settings, click on "Install Gogs" to complete the setup:
Next, create the admin user for Gogs. The first account that you register automatically becomes the admin user. Click on the button "Register" on the top right corner and fill in the details. You can choose any name. For this example, we're using
gogs-admin. Fill in the user email address, password, and complete the captcha. Then click on "Create New Account" to create the user:
Gogs created the admin user. Next, log in with your new user and password to access the Gogs dashboard and configure an SSH key.
Log into Gogs and configure an SSH key
You can use SSH keys with Gogs to clone and push code to your Git repositories. This allows automatic authentication without prompting for a password all the time. If you don't have an SSH key, create one in Linux using the command
$ ssh-keygen -t rsa Generating public/private RSA key pair. Enter file in which to save the key (/home/ricardo/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/ricardo/.ssh/id_rsa. Your public key has been saved in /home/ricardo/.ssh/id_rsa.pub. The key fingerprint is: SHA256:n8gKxhDCPPLfuFb9z5J9CmQedI6Wrw32vc6WtOh60uc firstname.lastname@example.org The key's randomart image is: +---[RSA 3072]----+ | | |o | |o+. . . | |.o.. . = | | o .S B . | | + o...B + . | | *.. o.B+.o o | | ..o . .=B=o* | | .. . oBBBE. | +----[SHA256]-----+
Then, copy the public key and add it to Gogs. By default the
ssh-keygen command generates the public key in
$ cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDWj/xcXVmRKkLAUZPk9ReFQ8kvT76mtrFeGKiZ+anHU2C9UEDdbcPNNJdSWQyq7J6NObmc+LV7ozCdjA6oPaSPQ8pVX1BLpxdiOT1cSeV21BPvmtM/Kzut9P39GDx9Nvi3POyDRmwAXceE+MlUvPLtLzqLq7Y0UTWTOmBeRJU3QVFw5fNOeCkl3KgCMseVew8q6UY/mSaMtxKsJCMYA5NJb00tBKtY7iQ+mKr2Yk99nsMQjqySqPvzMHepDP9s6qayNv51qSW8TxT/dkGZMOipMDmvZk3kv0mMW9iAst66kmCGBwnxj3EkMv5nz4JuOsaDQcCN49eHnCz1eL8TKtncApuIoUI3qs9h6X/r2i765b+tvGYXXfOChbrQ6vmL+aPzVk3sQIen7BoUkjrG5TKbIBC9tvdc7lDCuLMYDBfHirN8yjDDn6R4d/hd5ZdqGXiaN8XERWItc47OsmK94RDVMNX3rLEE7OkvBVBQ1cyOHub9Y6RUdl3p4kAIbXsiSB8= email@example.com
Note: Never share the private key with anyone. By default the private key is in
Now, log in to the Gogs UI by clicking on "Sign In" in the Gogs home page using your browser. Use the admin user and password you created earlier.
You see the user's dashboard. For now, it is empty, since we have not created any repositories yet.
To add the SSH key, expand the user profile drop-down on the top right corner, and click on "Your Settings."
Next, click on "SSH Keys" on the "Settings" menu to the left and the "Add Key" button on the right corner. Give the key a name, such as "Admin Public Key," and paste the public key you copied earlier into the "Content" field. When done, click on the "Add Key" button at the bottom of the screen to create the key:
You will see a message confirming the key was added: New SSH key Admin Public Key has been added successfully!
Now that you added your SSH key to Gogs let's create a repository and push some code into it.
Creating a new repository and pushing code
In this final step, create a new repository in Gogs to manage source code. Click on the + icon drop-down and "New Repository" to add a new repository:
Fill in the details about the new repository. For example, set the name to
test-repo01, and add a description Test Repository. Initialize the repository with an MIT License and a Default ReadMe file. Then click on "Create Repository" button to create the repository:
Next, clone this repository on your machine to add code to it:
$ git clone ssh://git@rh8vm02:10022/gogs-admin/test-repo01.git Cloning into 'test-repo01'... The authenticity of host '[rh8vm02]:10022 ([192.168.122.169]:10022)' can't be established. ECDSA key fingerprint is SHA256:sKixNIbH5mtFmsd8EeMTTtrTwE57+grnm+LhUUBieHM. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[rh8vm02]:10022,[192.168.122.169]:10022' (ECDSA) to the list of known hosts. remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (3/3), done. remote: Total 4 (delta 0), reused 0 (delta 0) Receiving objects: 100% (4/4), done.
Change into the created directory
test-repo01 and update the
$ vi README.md # test-repo01 Test Repository This is just a test repository!
Save and close the file. Now commit the changes using Git:
$ git add README.md $ git commit -m "Updated README.md" [master ddf4545] Updated README.md 1 file changed, 4 insertions(+), 1 deletion(-)
Finally, push the code back to Gogs using
git push. Because you configured your SSH key, there's no need to authenticate explicitly.
$ git push Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 333 bytes | 333.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To ssh://rh8vm02:10022/gogs-admin/test-repo01.git 5fd0fde..ddf4545 master -> master
You can see the changes you made to the
README.md file using Gogs web UI:
You have your own containerized Git server using Gogs. You can use it to save and manage your own code, or to share code across different machines in your network or with a small team. This personal Git server is also useful to support a small lab. You can use it to manage your Ansible projects and synchronize them with Ansible Tower without using a cloud-based solution. Finally, you can also use it to manage and build your applications with OpenShift.
[ Are you a current RHCSA looking to learn more about working with containers? RHCSAs are eligible for 50% off online containers, Kubernetes, and Red Hat OpenShift training through the end of 2020. ]