{"id":21,"date":"2018-03-11T21:56:33","date_gmt":"2018-03-12T01:56:33","guid":{"rendered":"http:\/\/bhoey.com\/blog\/?p=21"},"modified":"2020-06-25T15:46:06","modified_gmt":"2020-06-25T19:46:06","slug":"setting-up-a-postgresql-docker-sandbox","status":"publish","type":"post","link":"https:\/\/bhoey.com\/blog\/setting-up-a-postgresql-docker-sandbox\/","title":{"rendered":"Setting Up A PostgreSQL Docker Sandbox"},"content":{"rendered":"<h3>Motivation<\/h3>\n<p>Sandboxes are very handy for isolated testing and demonstration purposes. As it happens, I began to write a post that was going to use a PostgreSQL Docker container as a sandbox and I decided it was better to break it out into its own post that could be referred to in future posts rather than add complexity to a post where it wasn't the main focus.<\/p>\n<h3>Install Docker<\/h3>\n<p>For my docker host system I am using Debian 9 (Stretch). Installation was done following the official <a href=\"https:\/\/docs.docker.com\/install\/linux\/docker-ce\/debian\/\" target=\"_blank\" rel=\"noopener noreferrer\">Get Docker CE for Debian<\/a> instructions.<\/p>\n<p>I won't repeat the commands here as those instructions will be updated appropriately as packages, dependencies and Debian distributions change.<\/p>\n<p><strong>However<\/strong> I will mention I'm not a fan of piping raw URL output directly into sudo commands as some of the official instructions indicate. Anytime the instructions call for it I would suggest instead dumping the output to a file and sanity checking it before feeding it to a command with elevated privileges.<\/p>\n<p>One last installation note is that depending on your environment and requirements you may want to give specific users the ability to control docker. As a result of completing the instructions indicated above a new group 'docker' was added, adding users to this group is as easy as:<\/p>\n<pre class=\"brush: plain; notranslate\">usermod -aG docker yourUsername<\/pre>\n<p>Afterwhich you'll need to re-login for the group changes to take effect (a simple 'su - yourUsername' on the command line you plan to run docker commands on suffices for the short-term)<\/p>\n<h3>Firing Up The Sandbox<\/h3>\n<p>Downloading and starting the PostgreSQL sandbox is as easy as:<\/p>\n<pre class=\"brush: plain; notranslate\">docker run \\\n            --name pgsandbox1 \\\n            -d \\\n            -e \"POSTGRES_PASSWORD=password\" \\\n            -p 5432:5432 \\\n            postgres:10\n<\/pre>\n<p>This tells docker to:<\/p>\n<ul>\n<li>Run a (ephemeral) container named 'pgsandbox1' based of the <a href=\"https:\/\/hub.docker.com\/_\/postgres\/\">postgres:10 image tag<\/a><\/li>\n<li>In detached mode (-d)<\/li>\n<li>Setting the password for the PostgreSQL superuser to 'password' via a system environmental variable (-e)<\/li>\n<li>And publishes (-p) port 5432 of the container on the host<\/li>\n<\/ul>\n<h3>Kicking Tires<\/h3>\n<p>First, we verify the container is running:<\/p>\n<pre class=\"brush: plain; notranslate\">$ docker container list\n\nCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n3b445b6a2dc0 postgres:10 \"docker-entrypoint.s\u2026\" 3 minutes ago Up 3 minutes 5432\/tcp pgsandbox1\n<\/pre>\n<p>Next, we lauch the psql interactive shell<\/p>\n<p><b>Method 1: Exec psql inside the running docker<\/b><br \/>\nThis method does not require psql to be installed on the host system:<\/p>\n<pre class=\"brush: plain; notranslate\">$ docker exec \\\n          -it \\\n          pgsandbox1 \\\n          psql -U postgres\n\npsql (10.3 (Debian 10.3-1.pgdg90+1))\nType \"help\" for help.\n\npostgres=#\n<\/pre>\n<p><b>Method 2: Connect via local psql to the published container port<\/b><\/p>\n<pre class=\"brush: plain; notranslate\">$ psql \\\n     --host=127.0.0.1 \\\n     --port=5432 \\\n     --username=postgres\n\nPassword for user postgres: \n\npsql (10.3 (Debian 10.3-1.pgdg90+1))\nType \"help\" for help.\n\npostgres=# \n<\/pre>\n<p>And as a final check we create a table, add a row to it and run a query:<\/p>\n<pre class=\"brush: plain; notranslate\">postgres=# CREATE TABLE test (id SERIAL, name TEXT);\nCREATE TABLE\n\npostgres=# \\d\n             List of relations\n Schema |    Name     |   Type   |  Owner   \n--------+-------------+----------+----------\n public | test        | table    | postgres\n public | test_id_seq | sequence | postgres\n(2 rows)\n\n\npostgres=# \\d test\n                            Table \"public.test\"\n Column |  Type   | Collation | Nullable |             Default              \n--------+---------+-----------+----------+----------------------------------\n id     | integer |           | not null | nextval('test_id_seq'::regclass)\n name   | text    |           |          | \n\n\npostgres=# INSERT INTO test (name) VALUES ('Pat');\nINSERT 0 1\n\npostgres=# SELECT * FROM test;\n id | name \n----+------\n 1 | Pat\n(1 row)\n<\/pre>\n<p>Important reminder: The docker container running above is ephemeral; it does not retain or persist data between container restarts.<\/p>\n<h3>Final Notes<\/h3>\n<p>In the end of this we have a minimalist PostgreSQL instance ready for simple testing and examples. There is obviously a lot of room for enhancements and additional functionality. For those interested in modifications to the simple use-case above I would recommend reading through&nbsp;<a href=\"https:\/\/hub.docker.com\/_\/postgres\/\">the base postgres docker image page<\/a> which includes guidance on how best to do so.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sandboxes are very handy for isolated testing and demonstration purposes. As it happens, I began to write a post that was going to use a PostgreSQL Docker container as a sandbox and I decided it was better to break it out into its own post that could be referred to in future posts rather than add complexity to a post where it wasn't the main focus.&nbsp;<a href=\"https:\/\/bhoey.com\/blog\/setting-up-a-postgresql-docker-sandbox\/\">[Continue&nbsp;reading...] <span class=\"screen-reader-text\">Setting Up A PostgreSQL Docker Sandbox<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":837,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,12],"tags":[9,15,14,88,89],"_links":{"self":[{"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/posts\/21"}],"collection":[{"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/comments?post=21"}],"version-history":[{"count":20,"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/posts\/21\/revisions"}],"predecessor-version":[{"id":485,"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/posts\/21\/revisions\/485"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/media\/837"}],"wp:attachment":[{"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/media?parent=21"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/categories?post=21"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bhoey.com\/blog\/wp-json\/wp\/v2\/tags?post=21"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}